Java Comparator的使用-构建自己的Comparator(Lambda)

引文

在开发的过程中,通常会对一些List进行排序,如果仅仅对某一个数字型的字段进行排序,排序的种类有很多,无论是使用Java 8 新特性的Stream排序,或者是使用Array.sort方法都可以。但有时候我们需要对字符串类型,并且可能会处理null值、空值,并且进行多字段的排序,这时候一行两行的排序很难解决问题,就需要我们将其单独拿出来,写一个排序比较器,通过这个比较器完成我们的比较逻辑。

Comparator 简介

Comparator 接口是Java中的一个函数式接口,支持Lambda表达式,其类似于String中对两个字符串比较的函数s1.compareTo(s2),在这个函数中,如果s1,此函数会返回一个负值,如果s1>s2,此函数将会返回一个正值,如果相等,则返回0。同样,Comparator也是一样的功能,其就是比较两个对象o1,o2,如果o1,返回小于0的数字,相等返回0o1>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)