Java 我怎样才能按照我想要的方式对这个 ArrayList 进行排序?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/890254/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 20:43:47  来源:igfitidea点击:

How can I sort this ArrayList the way that I want?

javasortingarraylist

提问by Pahari Chora

Here is a simple sorting program of an ArrayList:

下面是一个简单的 ArrayList 排序程序:

ArrayList<String> list = new ArrayList<String>();

list.add("1_Update");
list.add("11_Add");
list.add("12_Delete");
list.add("2_Create");

Collections.sort(list);
for (String str : list) {
  System.out.println(str.toString());
}

I was expecting the output of this program as:

我期待这个程序的输出为:

1_Update
2_Create
11_Add
12_Delete

But when I run this program I am getting output as:

但是当我运行这个程序时,我得到的输出为:

11_Add
12_Delete
1_Update
2_Create

Why is this and how do I get the ArrayList to sort as shown in the expected output?

为什么会这样,我如何让 ArrayList 按照预期的输出进行排序?

采纳答案by nsayer

You could write a custom comparator:

您可以编写自定义比较器:

Collections.sort(list, new Comparator<String>() {
    public int compare(String a, String b) {
        return Integer.signum(fixString(a) - fixString(b));
    }
    private int fixString(String in) {
        return Integer.parseInt(in.substring(0, in.indexOf('_')));
    }
});

回答by Halvard

It is sorted as text (alphabetically), not as numbers. To get around this you could implement a custom comparator as suggested in the answer by nsayer.

它按文本(按字母顺序)排序,而不是按数字排序。为了解决这个问题,您可以按照 nsayer 的答案中的建议实现自定义比较器。

回答by Vincent Ramdhanie

The Collections.sort() method's docs says:

Collections.sort() 方法的文档说:

Sorts the specified list into ascending order, according to the natural ordering of its elements.

根据其元素的自然顺序,将指定列表按升序排序。

Which means for Strings that you are going to get the list in alphabetic order. The String 11_assign_privileges.sql comes before the string 1_create_table.sql and 12_07_insert_static_data.sql comes before 1_create_table.sql etc. So the program is working as expected.

这意味着对于字符串,您将按字母顺序获取列表。字符串 11_assign_privileges.sql 出现在字符串 1_create_table.sql 之前,12_07_insert_static_data.sql 出现在 1_create_table.sql 之前等等。所以程序按预期工作。

回答by Matej

Because strings are sorted in a alphabetic ordering and the underscore character is after characters for numbers. You have to provide a comparator implementing "Natural Order" to achieve desired result.

因为字符串按字母顺序排序,下划线字符在数字字符之后。您必须提供一个实现“自然秩序”的比较器才能达到预期的结果。

回答by Jim Blake

When you sort this type of data as a string, it is comparing the characters themselves, including the digits. All of the string that begin with "1", for example, will end up together. So the order ends up similar to this...

当您将这种类型的数据作为字符串进行排序时,它是在比较字符本身,包括数字。例如,所有以“1”开头的字符串都将一起结束。所以订单最终类似于这个......

1 10 100 2 20 200

1 10 100 2 20 200

At no point does the sort "realize" that you are assigning meaning to subsets of the string, such as the variable length numbers at the front of the string. When sorting numbers as strings, padding to the left with zeros as much as required to cover the largest number can help, but it does not really solve the problem when you don't control the data, as in your example. In that case, the sort would be...

排序永远不会“意识到”您正在为字符串的子集分配含义,例如字符串前面的可变长度数字。将数字作为字符串进行排序时,向左填充零以覆盖最大数字会有所帮助,但是当您不控制数据时,它并不能真正解决问题,如您的示例所示。在那种情况下,排序将是......

001 002 010 020 100 200

001 002 010 020 100 200

回答by Zifre

The string compare algorithm compare each characterat a time. 1sorts before 2. It doesn't matter that it is followed by a 1or a 2.

字符串比较算法一次比较每个字符1排序之前2。后面跟 a1或 a都没有关系2

So 100would sort before 2. If you don't want this behavior, you need a compare algorithm that handles this case.

所以100会排序之前2。如果您不想要这种行为,则需要一个处理这种情况的比较算法。

回答by jiggy

As others have stated, the elements will be sorted alphabetically by default. The solution is define a concrete java.util.Comparator class and pass it as a second argument to the sort method. Your comparator will need to parse out the leading integers from the strings and compare them.

正如其他人所说,默认情况下元素将按字母顺序排序。解决方案是定义一个具体的 java.util.Comparator 类并将其作为第二个参数传递给 sort 方法。您的比较器需要从字符串中解析出前导整数并进行比较。

回答by QSmienk

It is doing a lexicographic comparison. It compares the first character in each string sorting them. It then compares the second string of those with the same first charater. When it compares the '_' character to a number, it is greater in value than any single number character just like 8 > 7 and a > 9. Remember it is doing a character comparison and not a numeric comparison.

它正在做一个字典比较。它比较对它们进行排序的每个字符串中的第一个字符。然后将这些字符串的第二个字符串与相同的第一个字符进行比较。当它将“_”字符与数字进行比较时,它的值比任何单个数字字符都大,就像 8 > 7 和 a > 9 一样。记住它是在进行字符比较而不是数字比较。

There are ways to implement your own custom sorting routing which may be better than renaming your script names.

有一些方法可以实现您自己的自定义排序路由,这可能比重命名脚本名称更好。

If renaming your script names is an option, this may allow other script tools to be used. One format may be

如果重命名您的脚本名称是一个选项,这可能允许使用其他脚本工具。一种格式可能是

01_create_table.sql
02_create_index.sql
11_assign_privileges.sql

By keeping your first two digits to two characters, the lexicographic comparison will work.

通过将前两位数字保持为两个字符,字典比较将起作用。

回答by Kris

To have Collection.sort() sort arbitrarily you can use

要使 Collection.sort() 任意排序,您可以使用

Collections.sort(List list, Comparator c)  

Then simply implement a Comparator that splits the string and sorts first based on the number and then on the rest or however you want it to sort.

然后简单地实现一个比较器,它拆分字符串并首先根据数字进行排序,然后根据其余部分或您希望它排序的方式进行排序。

回答by Carl Manaster

Everyone has already pointed out that the explanation is that your strings are sorting as strings, and a number have already directed your attention to Natural Order string comparison. I'll just add that it's a great exercise to write that comparator yourself, and a great opportunity to practice test-driven development. I've used it to demonstrate TDD at Code Camp; slides & code are here.

大家已经指出,解释是你的字符串是按字符串排序的,有一个数字已经把你的注意力引向了自然顺序字符串比较。我只想补充一点,自己编写比较器是一个很好的练习,也是练习测试驱动开发的好机会。我已经用它在 Code Camp 中演示了 TDD;幻灯片和代码在这里

回答by johnstok

As stated above, you are looking for a Comparator implementation that implements a natural sort. Jeff Atwood wrote an excellent post on natural sortingsome time ago - it's well worth a read.

如上所述,您正在寻找实现自然排序的 Comparator 实现。Jeff Atwood前段时间写了一篇关于自然排序的优秀文章- 非常值得一读。

If you're looking for a Java implementation I have found this one to be useful: http://www.davekoelle.com/alphanum.html

如果您正在寻找 Java 实现,我发现这个很有用:http: //www.davekoelle.com/alphanum.html