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)); 像预期的那样工作。

回答

阅读的文档Comparatorcompare,或者你使用来实现它的拉姆达,必须返回一个负值,如果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.

以上是Java:将Collection.sort和lambda表达式与三元运算符结合使用会导致意外结果的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>