主题
Java8 filter的坑
对于Java8
中的Stream
用法,大家肯定再熟悉不过了。
我们通过对集合
的Stream
操作,可以实现:遍历集合、过滤数据、排序、判断、转换集合等等,N多功能。
这里重点说说数据的过滤。
在没有Java8之前,我们过滤数据一般是这样做的:
java
public List<User> filterUser(List<User> userList) {
if(CollectionUtils.isEmpty(userList)) {
return Collections.emptyList();
}
List<User> resultList = Lists.newArrayList();
for(User user: userList) {
if(user.getId() > 1000 && user.getAge() > 18) {
resultList.add(user);
}
}
return resultList;
}
通常需要另一个集合辅助完成这个功能。
但如果使用Java8的filter
功能,代码会变得简洁很多,例如:
java
public List<User> filterUser(List<User> userList) {
if(CollectionUtils.isEmpty(userList)) {
return Collections.emptyList();
}
return userList.stream()
.filter(user -> user.getId() > 1000 && user.getAge() > 18)
.collect(Collectors.toList());
}
代码简化了很多,完美。
但如果你对过滤后的数据,做修改了:
java
List<User> userList = queryUser();
List<User> filterList = filterUser(userList);
for(User user: filterList) {
user.setName(user.getName() + "测试");
}
for(User user: userList) {
System.out.println(user.getName());
}
你当时可能只是想修改过滤后的数据,但实际上,你会把元素数据一同修改了。
意不意外,惊不惊喜?
其根本原因是:过滤后的集合中,保存的是对象的引用,该引用只有一份数据。
也就是说,只要有一个地方,把该引用对象的成员变量
的值,做修改了,其他地方也会同步修改。
如下图所示: