Aly*_*ona 4 java sorting lambda comparator java-8
我想按日期排序从数据库中获取的对象列表.问题是日期(table1,table2)的位置取决于ObjectType.如果是1,则应从第一个表中选择日期,如果它是2,则从第二个表中选择.我开始是这样的:
objectList.stream().sorted((h1,h2)->
if(h1.getObjectType().getId()==1){
h1.getObject().getTable1().getTime()}//here is the problem
);
Run Code Online (Sandbox Code Playgroud)
但后来我感到困惑,因为在if条款之后我不能只是添加.compareTo.有没有办法使用带有if子句的lambda表达式来制作Java 8比较器?
这里有一些事情一下子发生.
首先,如果要if-else在lambda中使用语句,则需要使用语句lambda(带括号的类型)而不是表达式lambda(其中省略了大括号).使用语句lambda,您必须return显式使用语句,而在表达式lambda中,返回值隐式只是评估表达式的结果.
您有一些条件逻辑用于选择要比较的值.我假设这个逻辑需要独立地应用于被比较的两个对象中的每一个,因此这意味着直接的进行方式将要求您写出两次逻辑.
最后,您需要为实际比较编写一些逻辑.
对于这个例子,我将假设被排序的对象是类型的,Obj并且它们被排序的值是ObjDate我将进一步假设彼此相当的类型.(也就是说ObjDate implements Comparable<ObjDate>.)我还假设对象id是1或2,所以我不会处理值为其他的情况.
这是一个使用语句lambda的完全写出的比较器:
objectList.stream().sorted((h1, h2) -> {
ObjDate h1date;
ObjDate h2date;
if (h1.getObjectType().getId() == 1) {
h1date = h1.getObject().getTable1().getTime();
} else {
h1date = h1.getObject().getTable2().getTime();
}
if (h2.getObjectType().getId() == 1) {
h2date = h2.getObject().getTable1().getTime();
} else {
h2date = h2.getObject().getTable2().getTime();
}
return h1date.compareTo(h2date);
});
Run Code Online (Sandbox Code Playgroud)
啊! 编写比较器很有趣,不是吗?:-)
基本上,我们的想法是应用get-from-table1-or-table2逻辑来为第一个对象提取正确的值,然后对第二个对象进行相同的处理.最后,返回比较它们的结果.
这样可行,但这里有一些明显的重复代码.公共代码可以称为密钥提取器,因为给定要比较的对象,它提取用作比较基础的密钥.这是一个关键的提取器方法,它为单个对象执行此操作:
ObjDate getSortingDate(Obj obj) {
if (obj.getObjectType().getId() == 1) {
return obj.getObject().getTable1().getTime();
} else {
return obj.getObject().getTable2().getTime();
}
}
Run Code Online (Sandbox Code Playgroud)
现在我们有了这个,我们可以大大简化比较器:
objectList.stream().sorted((h1, h2) -> {
ObjDate h1date = getSortingDate(h1);
ObjDate h2date = getSortingDate(h2);
return h1date.compareTo(h2date);
});
Run Code Online (Sandbox Code Playgroud)
如果我们折叠局部变量,我们可以将它转换为表达式lambda:
objectList.stream().sorted(
(h1, h2) -> getSortingDate(h1).compareTo(getSortingDate(h2)));
Run Code Online (Sandbox Code Playgroud)
最后,从两个对象中提取密钥并比较它们的想法在比较器中是如此常见,以至于有一个辅助方法可以为您完成此任务:Comparator.comparing(keyExtractor).给定两个对象,它在两个对象上运行键提取器并比较它们.(更准确地说,它返回一个执行此操作的函数.)我们可以直接使用它来进一步简化:
objectList.stream().sorted(Comparator.comparing(this::getSortingDate));
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2758 次 |
| 最近记录: |