Java:将Collection.sort和lambda表达式与三元运算符结合使用会导致意外结果
我有以下课程:
import java.util.*;
class ClassA {
public static void main(String...args) {
var list = new ArrayList<String>();
list.add("test");
list.add("abc");
Collections.sort(list, (a, b) -> a.length() >= b.length() ? 1 : 0); // [test, abc]
//Collections.sort(list, (a, b) -> a.compareTo(b)); // [abc, test]
System.out.println(list);
}
}
我以为Collection.sort()会排序加音。我认为a.length()是 4 并且b.length()是 3,这将评估为(4 >= 3)真。所以a.length() >= b.length() ? 1 : 0会返回 1 并意味着它"test"大于"abc"。所以它应该像[abc, test].
但是我只有在[abc, test]将代码更改为时才得到结果a.length() >= b.length() ? 1 : -1,这似乎表明a.length() >= b.length()评估为false。这是为什么?
为什么第一个 lambda 表达式导致[test, abc],而修改后的版本导致[abc, test]?
Collections.sort(list, (a, b) -> a.compareTo(b)); 像预期的那样工作。
回答
阅读的文档Comparator:compare,或者你使用来实现它的拉姆达,必须返回一个负值,如果a < b,不只是一个正值当a > b。如果a等于(或比较等于),它也必须返回零b。这与其他一些编程语言的期望不同,我认为这让您感到困惑。
这将是一个完全有效的实现sort来从未注意正输出,仅负输出。看起来它没有按照您预期的顺序进行比较。
你可以正确地实现这个比较器(a, b) -> Integer.compare(a.length(), b.length()),或者更简单地实现Comparator.comparingInt(String::length)。
- Also IIRC needs to return 0 if equal, so returning 1 for same length is also not a good idea.
THE END
二维码