Stream<T> peek(Consumer<? super T> action)
生成一个新的流,该流中的元素由当前流的元素组成,新流中每个元素都绑定一个操作,当新流中的元素被使用或被消费的时候该操作被触发执行。
看一个例子:
void stream_peek() {
Stream.of("Mr.zhangsan","Mr.lisi","Mr.wanger","Mr.mazi")
.filter(a -> a.length()>7)
.peek(b -> System.out.println("Name: "+b))
.collect(Collectors.toList());
}
运行结果:
Name: Mr.zhangsan
Name: Mr.wanger
再看一个例子,这个例子中我们使用peek来修改User对象中的数据:
List<User> users = List.of(new User("111@qq.com","beijing"), new User("222@qq.com","shanghai"), new User("333@qq.com","tianjin"));
users.stream().peek(a -> {System.out.println(a.toString());a.setAddr("china - "+a.getAddr());}).forEach(System.out::println);
运行结果:
User [email=111@qq.com, addr=beijing, age=0]
User [email=111@qq.com, addr=china - beijing, age=0]
User [email=222@qq.com, addr=shanghai, age=0]
User [email=222@qq.com, addr=china - shanghai, age=0]
User [email=333@qq.com, addr=tianjin, age=0]
User [email=333@qq.com, addr=china - tianjin, age=0]
下面看看官方文档中的一个示例:
Stream.of("one", "two", "three", "four")
.filter(e -> e.length() > 3)
.peek(e -> System.out.println("Filtered value: " + e))
.map(String::toUpperCase)
.peek(e -> System.out.println("Mapped value: " + e))
.collect(Collectors.toList());
运行结果:
Filtered value: three
Mapped value: THREE
Filtered value: four
Mapped value: FOUR
这个例子绑定操作打印新流中的数据这块没有什么可以说的,但是注意到打印元素的顺序,因为最终消费流元素的方法是collect方法,该方法执行过程大概如下:先new一个空的ArrayList,然后使用该类的add方法逐个把元素添加到ArrayList中,因此当add第一个元素three的时候分别触发绑定在filer方法和map方法生成的新的流上的打印操作,因此这个时候打印一个小写three和一个大写THREE,然后再add第二个元素的时候也和第一个元素一样,因此出现上面例子的运行结果。
我们把上面代码最终消费流元素的方法修改一下,然后看看运行结果:
Stream.of("one", "two", "three", "four")
.filter(e -> e.length() > 3)
.peek(e -> System.out.println("Filtered value: " + e))
.map(String::toUpperCase)
.peek(e -> System.out.println("Mapped value: " + e))
.allMatch(a -> a.length()==4);
运行结果:
Filtered value: three
Mapped value: THREE
看到没有只打印了大小写的three,为什么呢?因为allMacth方法只消费了第一个元素,而没有消费第二个元素,因此只触发第一个元素绑定的两个打印操作。我们执行回顾一下allMacth方法的执行顺序,就以上面例子代码来分析,流中有两个元素分别是“threee”和“four”,allMacth方法中参数函数定义的判断条件是元素字符串长度为4,那就是说要流中全部元素长度都要等于4,有一个不等于就直接中断操作返回false,那我们按顺序分别取流中两个元素进行判断,第一个元素是“three”,长度为5,不等于4,好了,第一个就不满足条件,那后面也没有必要继续判断下去了,直接返回false结果,这就是为什么只打印了大小写的“three”,而没有打印大小写的“four”。