我的List<String>
包含以下值:
[1h,0h,2h,10h,4h,9h,3h,7h,8h,6h,5h]
当我使用Collections.sort()
对其进行排序时,订单变为:
[0h,10h,1h,2h,3h,4h,5h,6h,7h,8h,9h]
相反,它应该是:
[0h,1h,2h,3h,4h,5h,6h,7h,8h,9h,10h]
我怎样才能做到这一点?
答案 0 :(得分:1)
您在问题中引用的输出是正常的。如果您查看Collection.sort
的API说明,您会看到:
根据元素的自然顺序,将指定列表按升序排序。列表中的所有元素都必须实现Comparable接口。此外,列表中的所有元素必须是可相互比较的(即,e1.compareTo(e2)不得对列表中的任何元素e1和e2抛出ClassCastException。)
按照自然顺序,它们表示由compareTo
- 方法指定的排序(接口Comparable
只有方法compareTo
),它告诉this
- 对象是与排序中作为参数传递的对象相比,更大(返回严格正整数),或者等于(返回0),更少(返回严格的负整数)。要知道对象a
是否应该在对象b
之前获取,它只需调用a.compareTo(b)
。
sort
方法会在排序后的数组中a
之后设置b
。sort
方法会在排序数组中的a
之前设置b
。sort
方法不会更改它们的顺序。我会参考the API of the compareTo
method in the String
class,详细解释了如何排序字符串以及方法返回的内容。
它的作用是在每个字符串上迭代每个字符的字符,并比较相同位置的字符,直到找到差异。如果在那个差异,this
- 字符串的字符具有更高的Unicode value,它将返回严格的正整数(this
纵梁更大)否则它将返回严格的负数整数(this
- 字符串低于参数)。如果没有找到差异,它将返回0(this
- 字符串,并且参数具有相同的“订单值”)。
现在你的情况(以及许多第一次订购字符串的人)的问题是整数不能与Unicode排序一起排序,因为它按字符每个字符。如果必须对String s1 = "19"
和String s2 = "1119"
进行排序,则会调用s1.compareTo(s2)
。第一个区别是第二个字符s1
有9
而s2
在该位置有1
。由于 1
位于Unicode表格中9
之前(1
的值为十六进制值31且9
具有十六进制值39),{{ 1}}将返回一个严格的正整数(请参阅API的链接以查看哪个值)。因此即使s1.compareTo(s2)
,它也会在排序数组中s2
之前放置s1
!
所以现在你知道为什么会这样排序,让我们看看我们有什么解决方案:
Map
使用Integer.parseInt
方法将数组元素转换为其开始部分的十进制值,对这些十进制值进行排序,并将生成的排序数组映射回原始元素。我不会真的推荐这个解决方案,因为额外的集合和由于映射而产生的额外代码。Comparator
-object,在那里指定您希望如何排序字符串(例如使用Integer.parseInt
方法)并将其作为参数传递给Collections.sort
方法。通过将其作为参数传递,您可以告诉sort方法使用您的1119 > 19
- 对象而不是经典的Comparator
方法。 This link显示了如何使用compareTo
对数组进行排序。它与使用它来对arraylist进行排序完全相同。希望它有所帮助!
祝你好运