4

我有这个字符串列表

Car1

Car2

Car3

......


Carn

我想根据其中的数字对该列表进行排序。
例如,如果我有Car3, Car1, Car12, Car45,我希望它被排序为Car1, Car3, Car12, Car45.
我用过Collections.sort(),但它返回类似Car1, car12, car3, Car45.
我应该怎么做才能把它按正确的顺序排列?

4

9 回答 9

6

您需要一个自定义比较器,例如

    Collections.sort(list, new Comparator<String>() {
        public int compare(String s1, String s2) {
            int i1 = Integer.parseInt(s1.replaceAll("\\D", ""));
            int i2 = Integer.parseInt(s2.replaceAll("\\D", ""));
            return Integer.compare(i1, i2);
        }
    });
于 2013-06-26T09:46:32.203 回答
4

用这个:

class ComparatorOfNumericString implements Comparator<String>{

    public int compare(String string1, String string2) {
        // TODO Auto-generated method stub
        String a = string1.substring(3);
        String b = string2.split(3);
        return Integer.parseInt(a)-Integer.parseInt(b);
    }
}

现在,当排序通过此比较器时,如下所示:

Collections.sort(stringList,new ComparatorOfNumericString ());
于 2013-06-26T09:45:19.740 回答
3

排序是按字典顺序排列的,你得到这个顺序是因为 1 在字母表中小于 3,并且比较器忽略接下来的内容。您需要做的是编写自己的比较器,这将削减“汽车”,只留下字符串中的数字,然后您需要将该数字的字符串表示解析为一个整数并比较整数(作为解决方案)

于 2013-06-26T09:48:35.740 回答
3

您需要为定义字符串排序Comparator<String>的方法指定一个自定义项。Collections.sort()

这适用于字符串中任何位置的数字,也可以处理没有数字的字符串(回退到自然排序的普通字符串比较):

final Pattern intsOnly = Pattern.compile("\\d+");

Comparator<String> comparator = new Comparator<String>() {
    @Override
    public int compare(final String string1, final String string2) {
        String int1 = null;
        String int2 = null;
        Matcher matcher1 = intsOnly.matcher(string1);
        if (matcher1.find()) {
            int1 = matcher1.group();
            Matcher matcher2 = intsOnly.matcher(string2);
            if (matcher2.find()) {
                int2 = matcher2.group();
            }
        }
        if (int1 == null || int2 == null) { return string1.compareTo(string2); }
        return Integer.valueOf(int1).compareTo(Integer.valueOf(int2));
    }
};
Collections.sort(strings, comparator);

当然,这意味着 Truck1 将在 Car2 之前出现,但根据您的问题,这就是您想要的。

更新:上述解决方案不能确保 Car6 会在 Truck6 之前出现。如果您还想在数字相等的情况下回退到自然字符串排序,请使用以下命令:

final Pattern intsOnly = Pattern.compile("\\d+");

Comparator<String> comparator = new Comparator<String>() {
    @Override
    public int compare(final String string1, final String string2) {
        String int1 = null;
        String int2 = null;
        Matcher matcher1 = intsOnly.matcher(string1);
        if (matcher1.find()) {
            int1 = matcher1.group();
            Matcher matcher2 = intsOnly.matcher(string2);
            if (matcher2.find()) {
                int2 = matcher2.group();
            }
        }
        int result = 0;
        if (int1 != null && int2 != null) {
            result = Integer.valueOf(int1).compareTo(Integer.valueOf(int2));
        }
        if (result == 0) {
            return string1.compareTo(string2);
        }
        else {
            return result;
        }
    }
};
Collections.sort(strings, comparator);
于 2013-06-26T10:10:51.553 回答
1

您需要使用sort带有比较器的重载。以下代码适用于您的特定字符串 (CarXXX):

Collections.sort(carList, new Comparator<String>() {
    public int compare(String s1, String s2) {
        int t1 = Integer.parseInt(s1.substring(3));
        int t2 = Integer.parseInt(s2.substring(3));
        return t1 - t2;
    }
});
于 2013-06-26T09:47:47.140 回答
1

您将需要创建一个自定义 Comparator 来按您想要的方式进行排序。然后你可以打电话

Collections.sort(myList, myComparator)

请参阅Collections.sort(List, Comparator)

您可以在此处阅读比较器:实现 Java 比较器

于 2013-06-26T09:43:18.153 回答
1

Collections.sort() 是正确的,所以只需要编写比较器:

public class testComp implements Comparator<String> {

@Override
public int compare(String o1, String o2) {
    int number1 = Integer.parseInt(o1.substring(3, o1.length()));
    int number2 = Integer.parseInt(o2.substring(3, o2.length()));
    if (number1 > number2) {
        return -1;
    } else {
        return 1;
    }
}
于 2013-06-26T09:49:19.773 回答
0

Car1 是对象,因此您必须为此创建一个自定义比较器。并指定它的排序性质。

Collection.Sort()is根据其元素的自然顺序,将指定列表按升序排序。只是示例:字符串会像 az 一样,数字是 0-9。但是对象没有任何自然顺序。

于 2013-06-26T09:50:44.580 回答
0

这对你有用。但你不能有重复

    String text = "Car3, Car1, Car12, Car45";
    String[] str = text.split(", ");
    Map<Integer,String> myMap=new HashMap<>();
    int[] numOnly=new int[str.length];
    for (int i = 0; i < str.length; i++) {
          numOnly[i] = Integer.parseInt(str[i].replaceAll("\\D", ""));
          myMap.put(numOnly[i],str[i]);
    }       
    System.out.println(myMap.values());
于 2013-06-26T11:01:09.007 回答