对数字字符串的 ArrayList 进行排序

Posted

技术标签:

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

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

【问题讨论】:

您可以实现自己的比较器,但不确定是否更快。 为什么要在数组列表中插入数字作为字符串 @GeorgeThomas 长话短说:维护别人的代码。 @GeorgeThomas 我同意,如果是我,我会让他们都双打 检查此答案 [此处][1]。它适用于每种类型的变量。 [1]:***.com/a/12771571/4096270 【参考方案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 接口,该接口使您能够在输入数据时对数据进行排序。最好实现自己的比较器,我相信这将没有什么好处。

【讨论】:

以上是关于对数字字符串的 ArrayList 进行排序的主要内容,如果未能解决你的问题,请参考以下文章

在数字前使用字母对 Java ArrayList 进行排序

按长度对字符串的 ArrayList 进行排序

Java对ArrayList进行排序

排序包含字符串和整数的数组列表

按对象属性对对象的 ArrayList 进行排序

Groovy:如何按字符串长度顺序对 String:s 的 ArrayList 进行排序?