Spliterator Java 8 - 自定义实现

我正在学习这个 Java 8 特性,我真的发现很难理解Spliterator接口的trySplit()方法实现,如果自定义类用于并行处理生成的Stream.

任何人都可以用一个清晰的例子来帮助我提供一些好的教程吗?


拉风的咖菲猫
浏览 156回答 2
2回答

有只小跳蛙

理想的 trySplit 方法有效地(无需遍历)将其元素精确地一分为二,从而实现平衡的并行计算。许多偏离这一理想的方法仍然非常有效;例如,仅对近似平衡的树进行近似分裂,或者对于叶子节点可能包含一个或两个元素的树,未能进一步分裂这些节点。然而,平衡的大偏差和/或过度低效的 trySplit 机制通常会导致并行性能不佳。以及带有注释的方法结构&nbsp;public Spliterator<T> trySplit() {&nbsp; &nbsp;int lo = origin; // divide range in half&nbsp; &nbsp;int mid = ((lo + fence) >>> 1) & ~1; // force midpoint to be even&nbsp; &nbsp;if (lo < mid) { // split out left half&nbsp; &nbsp; &nbsp;origin = mid; // reset this Spliterator's origin&nbsp; &nbsp; &nbsp;return new TaggedArraySpliterator<>(array, lo, mid);&nbsp; &nbsp;}&nbsp; &nbsp;else&nbsp; &nbsp; &nbsp; &nbsp;// too small to split&nbsp; &nbsp; &nbsp;return null;&nbsp;}更多信息请阅读https://docs.oracle.com/javase/8/docs/api/java/util/Spliterator.html

白衣染霜花

这是实现 Spliterator 的示例。public class Payment {&nbsp; &nbsp; private String category;&nbsp; &nbsp; private double amount;&nbsp; &nbsp; public Payment(double amount, String category) {&nbsp; &nbsp; &nbsp; &nbsp; this.amount = amount;&nbsp; &nbsp; &nbsp; &nbsp; this.category = category;&nbsp; &nbsp; }&nbsp; &nbsp; public String getCategory() {&nbsp; &nbsp; &nbsp; &nbsp; return category;&nbsp; &nbsp; }&nbsp; &nbsp; public double getAmount() {&nbsp; &nbsp; &nbsp; &nbsp; return amount;&nbsp; &nbsp; }}TrySplit 实现:import java.util.List;import java.util.Spliterator;import java.util.function.Consumer;public class PaymentBatchSpliterator implements Spliterator<Payment> {&nbsp; &nbsp; private List<Payment> paymentList;&nbsp; &nbsp; private int current;&nbsp; &nbsp; private int last;&nbsp; // inclusive&nbsp; &nbsp; public PaymentBatchSpliterator(List<Payment> payments) {&nbsp; &nbsp; &nbsp; &nbsp; this.paymentList = payments;&nbsp; &nbsp; &nbsp; &nbsp; last = paymentList.size() - 1;&nbsp; &nbsp; }&nbsp; &nbsp; public PaymentBatchSpliterator(List<Payment> payments, int start, int last) {&nbsp; &nbsp; &nbsp; &nbsp; this.paymentList = payments;&nbsp; &nbsp; &nbsp; &nbsp; this.current = start;&nbsp; &nbsp; &nbsp; &nbsp; this.last = last;&nbsp; &nbsp; }&nbsp; &nbsp; @Override&nbsp; &nbsp; public boolean tryAdvance(Consumer<? super Payment> action) {&nbsp; &nbsp; &nbsp; &nbsp; if (current <= last) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; action.accept(paymentList.get(current));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; current++;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return true;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; return false;&nbsp; &nbsp; }&nbsp; &nbsp; @Override&nbsp; &nbsp; public Spliterator<Payment> trySplit() {&nbsp; &nbsp; &nbsp; &nbsp; if ((last - current) < 100) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return null;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; // first stab at finding a split position&nbsp; &nbsp; &nbsp; &nbsp; int splitPosition = current + (last - current) / 2;&nbsp; &nbsp; &nbsp; &nbsp; // if the categories are the same, we can't split here, as we are in the middle of a batch&nbsp; &nbsp; &nbsp; &nbsp; String categoryBeforeSplit = paymentList.get(splitPosition-1).getCategory();&nbsp; &nbsp; &nbsp; &nbsp; String categoryAfterSplit = paymentList.get(splitPosition).getCategory();&nbsp; &nbsp; &nbsp; &nbsp; // keep moving forward until we reach a split between categories&nbsp; &nbsp; &nbsp; &nbsp; while (categoryBeforeSplit.equals(categoryAfterSplit)) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; splitPosition++;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; categoryBeforeSplit = categoryAfterSplit;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; categoryAfterSplit = paymentList.get(splitPosition).getCategory();&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; // safe to create a new spliterator&nbsp; &nbsp; &nbsp; &nbsp; PaymentBatchSpliterator secondHalf = new PaymentBatchSpliterator(paymentList,splitPosition,last);&nbsp; &nbsp; &nbsp; &nbsp; // reset our own last value&nbsp; &nbsp; &nbsp; &nbsp; last = splitPosition - 1;&nbsp; &nbsp; &nbsp; &nbsp; return secondHalf;&nbsp; &nbsp; }&nbsp; &nbsp; @Override&nbsp; &nbsp; public long estimateSize() {&nbsp; &nbsp; &nbsp; &nbsp; return last - current;&nbsp; &nbsp; }&nbsp; &nbsp; @Override&nbsp; &nbsp; public int characteristics() {&nbsp; &nbsp; &nbsp; &nbsp; return 0;&nbsp; &nbsp; }}是来自 GitHub参考的示例
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java