java - 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
,或者你用来实现它的 lambda,必须返回一个负值 if a < b
,而不仅仅是一个正值 if a > b
。如果a
等于(或比较等于),它也必须返回零b
。这与其他一些编程语言的期望不同,我认为这让你感到困惑。
永远不要关注积极的输出,只关注消极的输出,这将是一个完全有效的实现sort
。看起来它没有按照您预期的顺序进行比较。
您可以将这个比较器正确地实现为(a, b) -> Integer.compare(a.length(), b.length())
,或者更简单地实现为Comparator.comparingInt(String::length)
。
推荐阅读
- angular - 表单组上的角度自定义交叉字段验证无法按预期的日期字段工作
- sql - 表的“三角关系”中的 SQL 查询
- java - 如何解决“找不到符号”的问题?
- c# - C# System.Text.Json JSON 值无法转换为类结构
- mysql - 我在 docker 上设置了 mysql 和 apache 超集并通过桥接网络连接,SQLAlchemy URI 是什么?
- firebase - 退出后无法登录 - Firebase Google Signin with Flutter
- django - DJANGO - 模型中的默认过滤器
- reactjs - Material UI:访问子节点
- 零件
- javascript - 在项目中包含 X 射线刮刀时出现 Npm 错误
- reactjs - React Typesscript 消费组件回调