我们在流上有 peek 函数,它是接受消费者的中间函数。那么就我而言,为什么不将“r”替换为“x”。 peek 应该理想地用于调试目的,但我只是想知道为什么它在这里不起作用。
List<String> genre = new ArrayList<String>(Arrays.asList("rock", "pop", "jazz", "reggae"));
System.out.println(genre.stream().peek(s-> s.replace("r","x")).peek(s->System.out.println(s)).filter(s -> s.indexOf("x") == 0).count());
因为
peek()
接受 Consumer
。Consumer
旨在接受参数但不返回结果。 例如这里:
genre.stream().peek(s-> s.replace("r","x"))
s.replace("r","x")
确实执行了,但它不会改变流的内容。String
实例,在调用 peek()
后超出了范围。
要进行测试,请将
peek()
替换为 map()
:
List<String> genre = new ArrayList<String>(Arrays.asList("rock", "pop", "jazz", "reggae"));
System.out.println(genre.stream().map(s -> s.replace("r", "x"))
.peek(s -> System.out.println(s))
.filter(s -> s.indexOf("x") == 0).count());
假设您正在尝试调试流中的操作管道,您可以使用 forEach 来打印或记录流的结果。
这就是流操作 peek 可以提供帮助的地方。其目的是在消耗流的每个元素时对其执行操作。 但它不会像 forEach 那样消耗整个流;它将执行操作的元素转发到管道中的下一个操作。
就您而言,您应该喜欢这个。
List<String> genre = new ArrayList<String>(Arrays.asList("rock", "pop",
"jazz","reggae"));
genre.stream()
.peek(s -> System.out.println("from stream:" + s))
.map(x -> x.replace("r", "x"))
.peek(s -> System.out.println("from replace stream:" + s))
.filter(y -> y.indexOf("y") == 0)
.peek(s -> System.out.println("from stream:" + s ))
.collect(toList());