
在使用 Java Stream API 时,collect() 方法是一个强大的工具,可以将流中的元素收集到不同的数据结构中。当需要将流中的元素收集到 EnumSet 时,可能会遇到一些问题,特别是关于 Supplier 的使用。
问题在于 Stream.collect() 方法有一个重载版本,它接受三个参数:一个 Supplier,一个 BiConsumer 和另一个 BiConsumer。 很多人容易混淆 Supplier 的作用,导致编译错误。
理解 Stream.collect() 的三个参数版本
Stream.collect(Supplier, BiConsumer, BiConsumer) 方法的三个参数分别代表:
Supplier supplier: 一个函数,用于创建一个新的可变结果容器。 每次调用都会创建一个新的容器。BiConsumer accumulator: 一个函数,用于将流中的元素合并到结果容器中。BiConsumer combiner: 一个函数,用于合并两个结果容器。 在并行流处理中,多个结果容器会被合并成一个。
关键在于 Supplier 必须是一个函数,它提供一个新的可变对象,用于累积流中的元素,并作为流执行的结果返回。
正确使用 Supplier 创建 EnumSet
以下是一个正确的示例,展示了如何使用 Stream.collect() 将流中的元素收集到 EnumSet 中:
集简云
软件集成平台,快速建立企业自动化与智能化
22 查看详情
import java.util.EnumSet;import java.util.HashSet;import java.util.Set;import java.util.stream.Collectors;import java.util.stream.Stream;enum ScConstraint { CONSTRAINT_1, CONSTRAINT_2, CONSTRAINT_3}public class EnumSetCollector { public static void main(String[] args) { HashSet nlsCandidates = new HashSet(); nlsCandidates.add(1); nlsCandidates.add(2); EnumSet[] rowConstraints = new EnumSet[20]; for (int i = 0; i < 20; i++) { rowConstraints[i] = EnumSet.of(ScConstraint.CONSTRAINT_1, ScConstraint.CONSTRAINT_2); } Set s = EnumSet.of(ScConstraint.CONSTRAINT_1); int k = 0; EnumSet tbd = nlsCandidates.stream() .flatMap(p -> rowConstraints[10 * k + p].stream()) .filter(cstr -> !s.contains(cstr)) .collect( () -> EnumSet.noneOf(ScConstraint.class), Set::add, Set::addAll ); System.out.println(tbd); // 输出: [CONSTRAINT_2] }}
在这个例子中,() -> EnumSet.noneOf(ScConstraint.class) 是 Supplier,它返回一个空的 EnumSet。Set::add 将流中的元素添加到 EnumSet 中,Set::addAll 合并两个 EnumSet。
使用 Collectors.toCollection() 简化代码
另一种更简洁的方式是使用 Collectors.toCollection() 方法:
import java.util.EnumSet;import java.util.HashSet;import java.util.Set;import java.util.stream.Collectors;import java.util.stream.Stream;enum ScConstraint { CONSTRAINT_1, CONSTRAINT_2, CONSTRAINT_3}public class EnumSetCollector { public static void main(String[] args) { HashSet nlsCandidates = new HashSet(); nlsCandidates.add(1); nlsCandidates.add(2); EnumSet[] rowConstraints = new EnumSet[20]; for (int i = 0; i < 20; i++) { rowConstraints[i] = EnumSet.of(ScConstraint.CONSTRAINT_1, ScConstraint.CONSTRAINT_2); } Set s = EnumSet.of(ScConstraint.CONSTRAINT_1); int k = 0; EnumSet tbd = nlsCandidates.stream() .flatMap(p -> rowConstraints[10 * k + p].stream()) .filter(cstr -> !s.contains(cstr)) .collect(Collectors.toCollection(() -> EnumSet.noneOf(ScConstraint.class))); System.out.println(tbd); // 输出: [CONSTRAINT_2] }}
Collectors.toCollection(() -> EnumSet.noneOf(ScConstraint.class)) 创建一个 Collector,它将流中的元素收集到一个新的 EnumSet 中。 Supplier 仍然是必需的,用于创建空的 EnumSet。
注意事项
确保 Supplier 提供的是一个新的实例,而不是一个静态的实例。 如果使用静态实例,可能会导致多个流操作共享同一个 EnumSet,从而产生意想不到的结果。在使用并行流时,combiner 函数是必需的。 它用于合并多个线程产生的中间结果。
总结
正确使用 Stream.collect() 收集 EnumSet 的关键在于理解 Supplier 的作用。 Supplier 必须提供一个新的可变结果容器。 Collectors.toCollection() 提供了一种更简洁的方式来收集 EnumSet。 通过理解这些概念,可以避免常见的编译错误,并编写出更清晰、更高效的代码。
以上就是使用 Stream.collect() 正确收集 EnumSet的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/222423.html
微信扫一扫
支付宝扫一扫