有一个List,里面有一个字段是开始时间,一个字段是结束时间,需求是按完成时间升序排序,若完成时间为空,则按开始时间升序排序。需求很常见,不想用循环来判断,想到用java8的stream应该可以搞定。查了下相关资料后,写法如下:
list.stream().sorted( Comparator.comparing(TaskDto::getEndTime) .thenComparing(TaskDto::getStartTime)) .collect(Collectors.toList());
感觉没啥问题,但是一跑起来就会报空指针异常。好吧,百度后得出原因是默认的comparing只能对非空字段排序,如果有null的情况,需要加上nullsLast,所以变成了下面的写法:
list.stream().sorted( Comparator.comparing(TaskDto::getEndTime, Comparator.nullsLast(String::compareTo)) .thenComparing(TaskDto::getStartTime, Comparator.nullsLast(String::compareTo))) .collect(Collectors.toList());
这下是不报空指针的错了,但是错误变了。non-static method cannot be referenced from a static context。这个错就有点奇怪了,非静态方法不能被一个静态context引用。但问题是我这里都不是静态方法啊,而且是加了nullsLast这个参数后出现的问题,所以肯定是这里的写法有问题,而nullsLast这个函数是有的,那就是里面的参数不对咯,参数有什么问题?这里的String::compareTo,我的理解是前面应该是类型,而::后面应该是固定的,表示比较。
看到这里,我想大家应该知道问题所在了,这里的StartTime和EndTime是Date型,但我从网上的写法复制过来用的是String,所以就会报上面的错。修改为Date后问题解决。最终写法如下:
list.stream().sorted( Comparator.comparing(TaskDto::getEndTime, Comparator.nullsLast(Date::compareTo)) .thenComparing(TaskDto::getStartTime, Comparator.nullsLast(Date::compareTo))) .collect(Collectors.toList());