Java 8 Stream操作类型及peek示例解析
Java 8引入了Stream API,可用于对集合和数组进行函数式操作。本篇攻略将介绍Java 8中Stream API的操作类型,并详细讲解peek()操作的定义、用法和示例。
Stream API操作类型
Stream API包含两种类型的操作:Intermediate(中间操作)和Terminal(终端操作)。
Intermediate操作
Intermediate操作返回一个Stream并可以链式连接,常见Intermediate操作有:filter、map、flatMap、distinct、sorted、peek等。
Terminal操作
Terminal操作将Stream转换为另一个类型的值,并且返回结果,一旦Terminal操作执行完成,Stream将关闭,常见Terminal操作有:forEach、count、reduce、collect、anyMatch、allMatch、noneMatch等。
peek()操作
peek()方法被用于调试和测试,在每个元素恰好消耗一次时,它能够提供Stream操作元素的中间状态信息。
定义
peek()是一个Intermediate操作,它接收一个Consumer类型的lambda参数(void类型),对每个元素执行操作并返回一个新的Stream,并可以继续进行流的操作。peek()方法不会影响原始流中的元素。
用法
Stream.peek()方法的语法如下所示:
Stream<T> peek(Consumer<? super T> action)
其中,action是一个可以应用到每个元素上的void类型Lambda表达式,可以使用peek()方法进行调试和测试。
示例1
下面,让我们来看一下如何使用peek()方法。
List<Integer> numbers = Arrays.asList(new Integer[]{1, 2, 3, 4, 5});
List<Integer> result = numbers.stream()
.peek(x -> System.out.println("From stream: " + x))
.map(x -> x * 2)
.peek(x -> System.out.println("After map: " + x))
.filter(x -> x > 4)
.peek(x -> System.out.println("After filter: " + x))
.collect(Collectors.toList());
代码中,我们使用peek()方法输出每个元素的中间状态信息,例如:从流中、map操作之后、filter操作之后,然后将结果保存在一个List
运行程序,输出结果如下:
From stream: 1
After map: 2
From stream: 2
After map: 4
From stream: 3
After map: 6
From stream: 4
After map: 8
From stream: 5
After map: 10
After filter: 6
After filter: 8
After filter: 10
可以看到,peek()方法在每次操作之后都会输出目前流的中间状态。
示例2
接下来,我们再来看一个稍微复杂一些的示例,演示如何使用peek()方法创建并调试一个自定义Collector。
public class Person {
private String name;
private Integer age;
public Person(String name, Integer age) {
this.name = name;
this.age = age;
}
public Integer getAge() {
return age;
}
}
public class MyCollector<T> implements Collector<T, List<T>, List<T>> {
@Override
public Supplier<List<T>> supplier() {
return ArrayList::new;
}
@Override
public BiConsumer<List<T>, T> accumulator() {
return List::add;
}
@Override
public BinaryOperator<List<T>> combiner() {
return (list1, list2) -> {
list1.addAll(list2);
return list1;
};
}
@Override
public Function<List<T>, List<T>> finisher() {
return Function.identity();
}
@Override
public Set<Characteristics> characteristics() {
return Collections.emptySet();
}
}
List<Person> persons = Arrays.asList(
new Person("Tom", 20),
new Person("James", 18),
new Person("Lucas", 30)
);
List<Person> result = persons.stream()
.peek(x -> System.out.println("From stream: " + x))
.filter(p -> p.getAge() >=20)
.peek(x -> System.out.println("After filter: " + x))
.map(x -> new Person(x.name.toUpperCase(), x.age))
.peek(x -> System.out.println("After map: " + x))
.collect(new MyCollector<>());
System.out.println(result);
代码中,我们定义一个Person类和一个自定义的Collector MyCollector。然后我们想要从列表中选出年龄大于或等于20岁的人物,对他们进行大写名称的转换,最后使用自定义Collector进行收集,并输出结果。
运行程序,输出结果如下:
From stream: Person{name='Tom', age=20}
After filter: Person{name='Tom', age=20}
After map: Person{name='TOM', age=20}
From stream: Person{name='James', age=18}
From stream: Person{name='Lucas', age=30}
After filter: Person{name='Lucas', age=30}
After map: Person{name='LUCAS', age=30}
[Person{name='TOM', age=20}, Person{name='LUCAS', age=30}]
可以看出,peek()方法成功帮助我们调试,并得到需要的结果。
结论
在使用Stream API处理集合和数组时,peek()方法可用于调试和测试,输出每个元素的中间状态信息,方便地追踪操作过程。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java 8 Stream操作类型及peek示例解析 - Python技术站