引文
在开发的过程中,通常会对一些List进行排序,如果仅仅对某一个数字型的字段进行排序,排序的种类有很多,无论是使用Java 8 新特性的Stream排序,或者是使用Array.sort方法都可以。但有时候我们需要对字符串类型,并且可能会处理null值、空值,并且进行多字段的排序,这时候一行两行的排序很难解决问题,就需要我们将其单独拿出来,写一个排序比较器,通过这个比较器完成我们的比较逻辑。
Comparator 简介
Comparator 接口是Java中的一个函数式接口,支持Lambda表达式,其类似于String中对两个字符串比较的函数s1.compareTo(s2),在这个函数中,如果s1<s2,此函数会返回一个负值,如果s1>s2,此函数将会返回一个正值,如果相等,则返回0。同样,Comparator也是一样的功能,其就是比较两个对象o1,o2,如果o1<o2,返回小于0的数字,相等返回0,o1>o2返回大于0的数字。
构造自己的 Comparator
在开发中有这样的一个业务需求:我需要对数据库查询的结果中,对对象中的字段Zwjb先进行排序,再对Id进行排序,排序规则是Zwjb字段为null的排在最后,然后对Zwjb字段按数值进行降序排序,之后再对Id进行升序排序。其中Zwjb为字符串类型,Id为整形。
根据以上条件,我们需要思考如何构造一个比较器,这里使用了Lambda表达式,如果还没有看过的话可以看一下Lambda表达式这里贴出一个代码:
// RetConsultInfoVo 有一个对象属性为 GzYg
// GzYg 有一个字符串属性 Zwjb
Comparator<RetConsultInfoVo> myComparator = (o1, o2) -> {
// 若两者都为null,即相等,一定返回0,否则会对之后其他字段的排序造成干扰
if(o1.getGzYg().getZwjb() == null && o2.getGzYg().getZwjb() == null)
return 0;
else if(o1.getGzYg().getZwjb() == null){
// 若o1为null,本应该返回一个负值,此处返回正值,即直接使用就是倒序,不需要再额外指定倒序位。
return 1;
}else if(o2.getGzYg().getZwjb() == null) {
// 此处与上面的内容一样
return -1;
}else{
Double d1,d2;
d2 = Double.parseDouble(o2.getGzYg().getZwjb());
d1 = Double.parseDouble(o1.getGzYg().getZwjb());
// 相等的地方返回0必不可少,与上面两者都是null的考虑一样
if (d1.equals(d2)) {
return 0;
}
else {
return d1 - d2 < 0 ? 1 : -1;
}
}
};
我们的构造器写好了,接下来该如何使用呢?那么看接下来的使用方式,这里使用Stream来对List进行排序:
// consults 是数据库返回的一个List结果,这里对consults列表进行排序
List<RetConsultInfoVo> retConsultInfoVos;
// .sorted() 函数的参数需要一个比较器(排序简单的话使用Comparator.comparing()也可以构造一个比较器),之后可以继续比较别的字段,使用thenComparing()函数即可,
// thenComparing()这个函数里面也是一个比较器,也可以使用自己定义的比较器
retConsultInfoVos = consults.stream().sorted(myComparator.thenComparing((RetConsultInfoVo e) -> e.getGzYg().getId())).collect(Collectors.toList());
总结
在进行复杂的排序时,构造一个比较器时有必要的,因为有可能这个比较器会在多个地方用到,可以减少代码的重复,这个构造器中对一个字段进行了排序,但其配合Stream,可以直接将顺序变为倒序,非常方便。其二,可以处理复杂的逻辑,可以处理null值,此处如果直接进行比较的时候,使用nullLast()函数或者nullFirst()函数返回的对null值友好的比较器依然会报空指针错误。
本文介绍如何使用Java的Comparator接口创建一个定制化的比较器,用于对包含null值的字符串和整数字段进行排序,先按Zwjb降序处理null值,再按数值降序,最后按Id升序。展示了Lambda表达式的应用和在Stream API中的使用实例。
&spm=1001.2101.3001.5002&articleId=124156557&d=1&t=3&u=ecd91d3bfb464320b7eb3a7cb6f8f945)
2407

被折叠的 条评论
为什么被折叠?



