【问题标题】:Sorting list of Strings having integer values- Java [duplicate]具有整数值的字符串的排序列表-Java [重复]
【发布时间】:2013-06-26 09:40:47
【问题描述】:

我有这个字符串列表

Car1

Car2

Car3

......


Carn

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

【问题讨论】:

标签: java jakarta-ee sorting collections comparator


【解决方案1】:

你需要一个自定义的比较器,比如

    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);
        }
    });

【讨论】:

  • +1,但为了提高性能,我会编译正则表达式并使用正匹配来提取数字。比较器通常对性能至关重要。
【解决方案2】:

您需要将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;
    }
});

【讨论】:

  • 使用减号比较整数时要小心——它可能会溢出。
  • @Howard 如果担心溢出,那么即使将值解析为整数也可能是个问题。
【解决方案3】:

使用这个:

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 ());

【讨论】:

  • 使用减号比较整数时要小心——它可能会溢出。
【解决方案4】:

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

【讨论】:

  • +1 用于解释字符串的字典顺序
  • 感谢您的回复我已经这样做了,但我想确定这是唯一的方法还是我只是在重新发明轮子:)
【解决方案5】:

您需要为 Collections.sort() 方法指定自定义的 Comparator&lt;String&gt;,该方法定义了您想要的字符串排序。

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

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);

【讨论】:

    【解决方案6】:

    您将需要创建一个自定义比较器,以按照您的要求进行排序。然后你可以调用

    Collections.sort(myList, myComparator)
    

    Collections.sort(List, Comparator)

    您可以在此处阅读比较器:Implementing Java Comparator

    【讨论】:

      【解决方案7】:

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

      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;
          }
      }
      

      【讨论】:

      • 请原谅我的无知,-1 和 1 是什么意思……它们表示什么?
      • 这仅适用于字符串中索引 3 处的数字。我确信“Car1”、“Car2”等只是一个例子。请参阅我的答案以获得完整的解决方案。
      • 返回值“-1”表示列表中“o2”应高于“o1”。 “1”的返回值将“o1”置于“o2”之上。返回值 0 表示 o1 和 o2 相等。您基本上是在指示对列表进行排序的方式。
      【解决方案8】:

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

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

      【讨论】:

        【解决方案9】:

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

            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());
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-04-21
          • 2017-02-18
          • 2017-11-17
          • 1970-01-01
          • 1970-01-01
          • 2014-07-31
          • 2018-09-21
          • 2014-10-04
          相关资源
          最近更新 更多