案例
List<User> children = Lists.newArrayList(new User("bcd", 1, null));
children.add(new User("a", 1, null));
children.add(new User("d", 1, null));
children.add(new User(null, 1, null));
children.sort(Comparator.nullsLast(Comparator.comparing(User::getName)));
定位原因
此处看到这个是否是null是针对的集合本身元素,而并不是mapping之后的值!!!
当元素本身不是null的时候, 也就是else里面,还是会去走mapping之后的compare,见下。
可以看到String的CompareTo方法入参是@NotNull的,所以报错了。
结论
nullFirst 和 nullLast 和我正常理解的null的值会放在最前面和最后面不一样,根据源码可以看出,针对是还是元素本身。当元素不是null的时候,最终会对keyExtractor.apply得到的值的比较,此时如果存在null,就会报NPE。
解决
重写Comparator
children.sort((u1,u2) -> {
if (StringUtils.isEmpty(u1.getName())) {
return 1;
}
if (StringUtils.isEmpty(u2.getName())) {
return -1;
}
return u1.getName().compareTo(u2.getName());
});