我正在尝试对List<String>
个项目进行排序。这是未分类的List
,以及它当前的排序方式:
Unsorted: [Pineapple, pineapple, apple, apricot, Banana, mango, Mango, melon, peach]
Sorted: [apple, apricot, Banana, mango, Mango, melon, peach, Pineapple, pineapple]
为什么Mango
未放置在mango
之前,为什么Pineapple
放在pineapple
之前?
这是我的代码:
import java.util.*;
import java.lang.*;
import java.io.*;
class Test {
public static void main (String[] args) throws java.lang.Exception {
List<String> fruits = new ArrayList<String>(7);
fruits.add("Pineapple");
fruits.add("pineapple");
fruits.add("apple");
fruits.add("apricot");
fruits.add("Banana");
fruits.add("mango");
fruits.add("Mango");
fruits.add("melon");
fruits.add("peach");
System.out.println("Unsorted: " + fruits);
Collections.sort(fruits, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o1.compareToIgnoreCase(o2);
}
});
System.out.println("Sorted: " + fruits);
}
}
答案 0 :(得分:4)
您使用compareToIgnoreCase()
作为比较方法,因此它比较了菠萝&#39;和菠萝&#39;因为Collections.sort保证相同的元素不会被重新排序,所以将它们按照排序时的顺序排列为0(相同的字符串)。
换句话说,&#39; Pineapple&#39;来自菠萝&#39;之前,由于ignoreCase,菠萝&#39;菠萝&#39;菠萝&#39;菠萝&#39;菠萝&#39;将留在菠萝面前。
由于未排序的列表中有菠萝&#39;在&菠萝&#39;之前,比较将它们以相同的顺序放入排序列表中。这些相同的规则适用于芒果&#39;和&#39;芒果&#39;。您正在寻找的比较方法只是compareTo()
,它会考虑大写和小写字母。
答案 1 :(得分:2)
为什么“芒果”没有放在“芒果”之前,为什么'菠萝'之前是'菠萝'?
根据你的比较器,“芒果”和“芒果”比较相等。由于Collections.sort()
为stable,因此比较相等的项目按照原始集合中找到它们的顺序返回(不稳定排序会以任意顺序返回它们)
如果你希望“芒果”总是在“芒果”之前返回,你的比较器需要反映出来。这意味着“芒果”需要比较少于“芒果”(但大于“苹果”,“杏”,“香蕉”等)。
实现这一目标的一种方法是使用以下比较器:
Collections.sort(fruits, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
int ret = o1.compareToIgnoreCase(o2);
if (ret == 0) {
ret = o1.compareTo(o2);
}
return ret;
}
});
这将返回:
Sorted: [apple, apricot, Banana, Mango, mango, melon, peach, Pineapple, pineapple]
答案 2 :(得分:2)
因为您正在使用compareToIgnoreCase
,正如名称所示,在比较两个String时忽略大小写。因此,芒果和芒果是相同的,并且以与它们相同的顺序排除(排序是稳定,例如:equals元素按照它们在排序之前的顺序保留。)。< / p>
另一方面,您的比较器与String.CASE_INSENSITIVE_ORDER相同。 compareToIgnoreCase
简化称为比较器。
答案 3 :(得分:0)
According to the javadocs Collections.sort
保证稳定 - 比较为相等的项目的相对排序不会因排序而发生变化。如果要强制执行将大写字母置于其小写等价物之前的排序,则需要使用实现该排序的不同比较器,最简单的实现方法可能是使用java.text.RuleBasedCollator
。 / p>
答案 4 :(得分:-1)
你正在做的一切。
“芒果”确实应该出现在“菠萝”之前和“苹果”之后。
但“菠萝”和“菠萝”是“相同的”。等于。 “0”。因为你说“ignoreCase”。