[英]Java-Stream - Using filter and forEach for populating a Set
我有一个Set<Person>
,我需要过滤内容,然后从给定的集合中填充另一个集合。
我对流很陌生。
我能想到的第一个解决方案是链接stream().filter().foreach()
解决方案 1:
private Set<Person> mapPerson(final Set<Student> student) {
final Set<Person> person = new HashSet<>();
student.stream()
.filter(student1 -> Objects.nonNull(student.getAge()))
.forEach(student1 -> person.add(Person.builder()
.id(student1.getId())
.status(student1.getStatus()))
.build()));
return person;
}
但我不确定这是否可以通过链接stream().filter().map()
以某种方式完成?
将不胜感激任何帮助,如果可以两种方式都可以,那是首选方式?
为此,您不需要手动创建一个集合然后对其进行变异。 stream 流水线的执行结果可以获得一个集合。
可以通过链接stream().filter().map()以某种方式完成吗?
首先通过应用map()
操作将 stream 的学生Stream<Student>
转换为 stream 的人员对象Stream<Person>
,它期望 function 将 stream 的元素转换为所需类型的另一个 object。 因此,您需要将用于创建在forEach()
中使用的Person
object 的逻辑放入map()
中。
然后应用collect
传递作为参数Collectors.toSet()
。
private Set<Person> mapPerson(final Set<Student> students) {
return students.stream()
.filter(student -> Objects.nonNull(student.getAge()))
.map(student -> Person.builder()
.id(student.getId())
.status(student.getStatus())
.build())
.collect(Collectors.toSet());
}
如果可以两种方式进行,哪种方式是首选方式?
文档不鼓励您使用的方法。 看看下面的引用(强调是我的)。
作为如何将不适当使用副作用的管道 stream 转换为不使用副作用的示例,以下代码在 stream 字符串中搜索与给定正则表达式匹配的字符串,并将匹配项放入列表中。
ArrayList<String> results = new ArrayList<>(); stream.filter(s -> pattern.matcher(s).matches()).forEach(s -> results.add(s)); // Unnecessary use of side-effects!
... forEach()可以简单地替换为更安全、更高效且更适合并行化的缩减操作:
List<String> results = stream.filter(s -> pattern.matcher(s).matches()).toList(); // No side-effects!
您不应该使用forEach
(以及peek
),它只能在有其他方法可以达到相同结果的情况下通过引起副作用来运行。
在这种情况下,您可以使用collect()
(如上所示)或使用普通for
循环来完成。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.