提问1: max()
或min()
总能取到最大最小值吗?
不能, 这取决于集合是如何排序的,
max()
的含义是取出的是最后一个, 而min()
的含义是取出第一个, 不一定是最大最小值
提问2: 如下代码, 若要取出userList
中最大的年龄即19, 那么4个选项中哪些是正确的?
@Test
public void streamTest() {
User user_1 = new User("饱饱", 18);
User user_2 = new User("爆爆", 19);
User user_3 = new User("包包");
List<User> userList = Lists.newArrayList(user_1, user_2, user_3);
// 选项1
userList.stream().max(Comparator.comparing(User::getAge)).ifPresent(
item -> System.out.println(item.getAge())
);
// 选项2
userList.stream().max(Comparator.comparing(User::getAge, Comparator.nullsLast(Comparator.naturalOrder()))).ifPresent(
item -> System.out.println(item.getAge())
);
// 选项3
userList.stream().max(Comparator.comparing(User::getAge, Comparator.nullsFirst(Comparator.naturalOrder()))).ifPresent(
item -> System.out.println(item.getAge())
);
// 选项4
userList.stream().map(User::getAge).filter(ObjectUtil::isNotNull)
.max(Comparator.naturalOrder()).ifPresent(System.out::println);
}
思考之后, 往下滚动查看答案~
解析:
- 选项1, 错误, 所有
age
属性都不为空时正常执行,一旦age
有空值就会报错
userList.stream().max(Comparator.comparing(User::getAge)).ifPresent(item -> System.out.println(item.getAge()));
- 选项2, 错误, 把
userList
按age
排序, 把age
为空的放到最后面,max
是取出最后一个值, 因此结果反而是null
userList.stream().max(Comparator.comparing(User::getAge, Comparator.nullsLast(Comparator.naturalOrder()))).ifPresent(
item -> System.out.println(item.getAge())
);
- 选项3, 正确, 把
userList
按age
排序, 把age
为空的放到最前面,max
是取出最后一个值, 因此结果正确userList.stream().max(Comparator.comparing(User::getAge, Comparator.nullsFirst(Comparator.naturalOrder()))).ifPresent( item -> System.out.println(item.getAge()) );```
- 选项4, 正确, 最直白的写法, 过滤掉空
age
一了百了, 不用顾虑nullsLast
或者nullsFirst
userList.stream().map(User::getAge).filter(ObjectUtil::isNotNull).max(Comparator.naturalOrder()).ifPresent(
System.out::println
);
结论:
-
max
应配合nullsFirst
使用,min
应配合nullsLast
使用 - 使用
max
或min
之前, 先map().filter(ObjectUtil::isNotNull)
过滤掉空值, 这样来得直截了当, 还不易出错