看以下例子:
package stream; import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; public class Demo { public static void main(String[] args) { List<Person> personList = new ArrayList<>(); personList.add(new Person("a", 10)); personList.add(new Person("b", 20)); personList.add(new Person("c", 30)); List<Person> collect = personList.stream().peek(e -> e.setAge(e.getAge() + 1)).collect(Collectors.toList()); System.out.println(personList == collect); } }
结果为:
false
此时的personList和collect 已经不是同一个对象了。 为什么记录这个呢,是在某些情况下我们只是想让List中元素的属性发生变化(比如上例中person的age都+1),而并不想重新生成一个List对象,这个情况下使用stream就会出现我们不想要的效果。
比如,使用pagehelper分页库的时候,mybatis的拦截器会把返回的集合转为Page对象,如下:
public class Page<E> extends ArrayList<E> implements Closeable { private static final long serialVersionUID = 1L; /** * 页码,从1开始 */ private int pageNum; /** * 页面大小 */ private int pageSize; /** * 起始行 */ private int startRow; /** * 末行 */ private int endRow; /** * 总数 */ private long total; /** * 总页数 */ private int pages; /** * 包含count查询 */ private boolean count = true; /** * 分页合理化 */ private Boolean reasonable; }
可以看出Page类继承了ArrayList,并且额外提供了像查询的total、pageNum等额外信息。查出Page后,我们需要取出total、pageNum等信息返回前端进行分页展示。 试想此时我们对查询返回的List进行Stream操作并生成新的List,那total、pageNum等额外信息都将丢失。 需要注意此类场景。例如:
@Override public List<SysConfig> selectConfigList(SysConfig config) { return configMapper.selectConfigList(config); //configMapper.selectConfigList(config);返回的就是Page对象,假如此处对configMapper.selectConfigList(config)返回的Page进行stream操作聚合后再返回,就会生成新List对象,导致丢失分页信息。 }