对包含Java中的数字的字符串进行排序

我对字符串的默认比较器(在SortedSet中)有问题。 问题是默认比较器没有排序包含数字的良好字符串,即:在集合中我有:

room1, room2, room100 

自然排序应该如上所述,但在集合中我有:

 room1, room100, room2 

我知道它为什么但我不知道如何改变它。

尝试使用此比较器,删除所有非数字字符,然后将剩余字符作为数字进行比较:

 Collections.sort(strings, new Comparator() { public int compare(String o1, String o2) { return extractInt(o1) - extractInt(o2); } int extractInt(String s) { String num = s.replaceAll("\\D", ""); // return 0 if no digits found return num.isEmpty() ? 0 : Integer.parseInt(num); } }); 

这是一个测试:

 public static void main(String[] args) throws IOException { List strings = Arrays.asList("room1", "foo", "room2", "room100", "room10"); Collections.sort(strings, new Comparator() { public int compare(String o1, String o2) { return extractInt(o1) - extractInt(o2); } int extractInt(String s) { String num = s.replaceAll("\\D", ""); // return 0 if no digits found return num.isEmpty() ? 0 : Integer.parseInt(num); } }); System.out.println(strings); } 

输出:

 [foo, room1, room2, room10, room100] 

尝试这个。 我假设你的字符串开头总是有“空间”。

  List list = Arrays.asList("room1", "room100", "room2"); Collections.sort(list, new Comparator() { @Override public int compare(String o1, String o2) { return new Integer(o1.replaceAll("room", "")) .compareTo(new Integer(o2.replaceAll("room", ""))); } }); 

用@bohemian回答。 刚刚改进了一下。 这对我很有用..

  Collections.sort(asdf, new Comparator() { public int compare(String o1, String o2) { String o1StringPart = o1.replaceAll("\\d", ""); String o2StringPart = o2.replaceAll("\\d", ""); if(o1StringPart.equalsIgnoreCase(o2StringPart)) { return extractInt(o1) - extractInt(o2); } return o1.compareTo(o2); } int extractInt(String s) { String num = s.replaceAll("\\D", ""); // return 0 if no digits found return num.isEmpty() ? 0 : Integer.parseInt(num); } }); 

这是我的Comparator实现这样的一种:(字符串可以从任何字符开始)

 public class StringNumberComparator implements Comparator{ @Override public int compare(String o1, String o2) { int i1 = this.getRearInt(o1); int i2 = getLeadingInt(o2); String s1 = getTrailingString(o1); String s2 = getTrailingString(o2); if(i1==i2) return s1.compareTo(s2); if(i1>i2) return 1; else if(i1 

您可以实现比较器并将其传递给set构造函数。 请参见http://docs.oracle.com/javase/1.4.2/docs/api/java/util/Comparator.html 。

如果您的所有字符串都是房间[编号]的forms,您可以剥离“房间”解析数字并进行比较。
或者 – 您可以在设置中存储整数并使用“room”前缀打印它们。

一个懒惰的替代方案是使String比较器工作而不做任何额外的事情(定义你自己的比较器)。 你可以通过用零填充你的字符串中的数字,如下所示: room0001, room0002, room0100然后默认的字符串比较器将起作用。 但是,您需要知道最大数值,以便相应地调整填充。