我怎样才能按照我想要的方式排列这个ArrayList?

这是一个ArrayList的简单sorting程序:

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

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

 1_Update 2_Create 11_Add 12_Delete 

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

 11_Add 12_Delete 1_Update 2_Create 

为什么是这样的,我怎么得到ArrayListsorting如预期的输出中所示?

你可以写一个自定义比较器:

 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('_'))); } }); 

将这种types的数据作为stringsorting时,它将比较字符本身,包括数字。 例如,以“1”开始的所有string将一起结束。 所以订单类似于这个…

1 10 100 2 20 200

在这种情况下,“意识到”你没有意识到你正在为string的子集分配含义,比如string前面的可变长度数字。 当将数字sorting为string时,尽可能多地填充到最左边的数字可以帮助填充左边的数字,但是当您不控制数据时,它并不能真正解决问题,就像在您的示例中那样。 在这种情况下,sorting是…

001 002 010 020 100 200

它按文本(按字母顺序)sorting,而不是数字。 为了解决这个问题,你可以按照nsayer的build议,实现一个自定义比较器。

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

有很多方法可以实现自己的自定义sorting路由,这可能比重命名脚本名称更好。

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

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

通过保持您的前两位数字为两个字符,字典对比将工作。

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

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

这意味着string,你将按字母顺序得到列表。 11_assign_privileges.sqlstring出现在string1_create_table.sql之前,而12_07_insert_static_data.sql出现在1_create_table.sql之前。所以程序正常工作。

因为string按字母顺序sorting,下划线字符在数字字符之后。 您必须提供一个实现“自然顺序”的比较器来达到预期的效果。

string比较algorithm一次比较每个字符1之前2 。 它跟随12是没有关系的。

所以100会在2之前sorting。 如果你不想要这种行为,你需要一个处理这种情况的比较algorithm。

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

要让Collection.sort()任意sorting,您可以使用

 Collections.sort(List list, Comparator c) 

然后简单地实现一个比较器来分割string,然后根据数字对数据进行sorting,然后对剩下的数据进行sorting,或者将其sorting。

每个人都已经指出,解释是你的string被sorting为string,并且一个数字已经把你的注意力引向了自然顺序string比较。 我只是补充说,自己编写这个比较器是一个很好的练习,也是一个实践testing驱动开发的好机会。 我已经用它在Code Camp展示了TDD; 幻灯片和代码在这里 。

如上所述,您正在寻找实现自然sorting的比较器实现。 杰夫·阿特伍德(Jeff Atwood)前段时间写了一篇关于自然sorting的优秀文章 – 这非常值得一读。

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

您可以添加IComparable接口,然后按特定属性进行sorting。 如果你有一个商店的物品集合,例如,也许你想按价格或按类别sorting等。如果你想按名称sorting这里是一个例子:

注意ArrayList是如何按项目的name属性sorting的。 如果您不添加IComparable然后当您使用sorting方法它会引发错误。

在这里输入图像说明

 static void Main(string[] args) { ArrayList items = new ArrayList(); items.Add(new Item("book", 12.32)); items.Add(new Item("cd", 16.32)); items.Add(new Item("bed", 124.2)); items.Add(new Item("TV", 12.32)); items.Sort(); foreach (Item temp in items) Console.WriteLine("Name:{0} Price:{1}", temp.name, temp.price); Console.Read(); } class Item: IComparable { public string name; public double price; public Item(string _name, double _price) { this.name = _name; this.price = _price; } public int CompareTo(object obj) { //note that I use the name property I may use a different one int temp = this.name.CompareTo(((Item)obj).name); return temp; } }