【问题标题】:Sort an ArrayList of Strings that are numbers对数字字符串的 ArrayList 进行排序
【发布时间】:2014-12-07 23:32:24
【问题描述】:

对包含数字的ArrayList<String>(以降序/升序方式)进行排序的最快方法是什么,例如:{ "12", "3.5", "188", "33.03" }Collections 有内置方法吗?目前我正在将ArrayList 的内容复制到ArrayList<Double>,然后使用Collections.Sort() 方法,然后将其放回初始数组。有更快的方法吗?

【问题讨论】:

  • 您可以实现自己的比较器,但不确定是否更快。
  • 为什么要在数组列表中插入数字作为字符串
  • @GeorgeThomas 长话短说:维护别人的代码。
  • @GeorgeThomas 我同意,如果是我,我会让他们都双打
  • 检查此答案 [此处][1]。它适用于每种类型的变量。 [1]:stackoverflow.com/a/12771571/4096270

标签: java arrays sorting arraylist


【解决方案1】:

您可以在List<String> 上使用Collections.sort(),字符串是Comparable,但这种比较不会给您正确的结果。

您也可以定义自己的Comparator,并将其传递给Collections.sort()

【讨论】:

    【解决方案2】:

    试试下面的代码:

    String test[] = {"12", "3.5", "188", "33.03"};
    double numbers[] = new double[test.length];
    for (int i = 0; i < test.length; i++) {
         numbers[i] = Double.parseDouble(test[i]);
    }
    Arrays.sort(numbers);
    for (double i : numbers) {
         System.out.println(i);
    }
    

    输出:

    3.5
    12.0
    33.03
    188.0
    

    【讨论】:

    • 确实,为什么?我现在正在尝试
    • 作者就是这么干的,不过我没有投反对票
    • 和我做的差不多,是的,但可能有更快的方法。
    • 您可以使用比较器,但我认为这是更快的方法。是的,为什么要投反对票?
    • 我个人不会在这里使用Floats,因为可能会损失准确性(当然取决于输入值),但原则上这应该没问题。
    【解决方案3】:

    我认为您当前的方法可能很好,我会避免使用自定义 Comparator,因为您最终会多次将相同的字符串转换为数值(每次排序算法想要比较 2 个值)而不是就像你现在做的一样。

    【讨论】:

    • 当原始元素为“0.1”时,OPs 方法是否会导致列表中出现“0.0999999999123”?
    • 关于多次转换的观点很好;一种解决方案可能是将转换后的值保存到地图中,然后进行检查。哪种解决方案更快但是是一个完全不同的问题......
    【解决方案4】:

    您需要实现自己的比较器,并在您的列表中使用它。 您必须使用 BigDecimal,因为您可能会遇到精度损失问题。如果您的数字精度要求较低,您可以使用双精度。

    class MyComparator implements Comparator<String, String> {
    
        public int compare(String o1, String o2){
            return new BigDecimal(o1).compareTo(new BigDecimal(o2));
        }
    
    }
    ...
    Collections.sort(list, new MyComparator());
    

    【讨论】:

    • 最佳 Java 1.7 解决方案!除非您知道这些值的精度有限,否则您可以使用 Double.parseDouble() 而不是 BigDecimal
    【解决方案5】:

    如果您使用的是 Java 8,则可以使用 Comparator.comparing(Double::parseDouble) 使用 parseDouble 快速创建比较器。这应该(见下文)为每个条目只调用一次函数,而不是每对调用一次。

    List<String> list = Arrays.asList( "12", "3.5", "188", "33.03" );
    list.sort(Comparator.comparing(Double::parseDouble));
    System.out.println(list);
    

    输出:

    [3.5, 12, 33.03, 188]
    

    更新:好吧,我认为这会为每个元素只调用一次比较器函数,就像在 Python 中使用 key-函数一样,但经过快速使用每次调用时增加计数器的函数进行测试,该函数的调用频率与使用旧式“对”比较器一样频繁。不过,还是有点短……

    【讨论】:

    • 谢谢。尽管编写的代码更少,但我使用的是 Java 7,据我了解,List 在版本 7 中没有 sort() 方法,对吧?有什么解决方法吗?
    • 您必须找到解决方案,就像在旧 Java 版本中一样。要么你创建一个比较器,就像上面的例子,要么你必须让你的所有集合对象都实现 Comparable,然后使用 Collections.sort() :) 所以不,List 没有排序方法:) 为什么?因为它是一个iterface,有时list不必被索引。
    • @Ben 在 Java 8 中,List has a sort method.
    【解决方案6】:

    您可以尝试 sortedset 接口,该接口使您能够在输入数据时对数据进行排序。最好实现自己的比较器,我相信这将没有什么好处。

    【讨论】:

      猜你喜欢
      • 2011-07-28
      • 1970-01-01
      • 2017-06-07
      • 2014-05-05
      • 2011-11-26
      • 2015-07-14
      • 2012-11-14
      • 2017-02-23
      • 1970-01-01
      相关资源
      最近更新 更多