首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Spliterator Java 8-定制实现

Spliterator Java 8-定制实现
EN

Stack Overflow用户
提问于 2018-10-26 11:49:12
回答 2查看 1.8K关注 0票数 1

我正在学习这个Java8特性,我发现在使用定制类对生成的Spliterator进行并行处理时,很难理解trySplit()接口的trySplit()方法实现。

谁能帮我一些好的教程与一个明确的例子?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-10-26 12:10:45

理想的trySplit方法有效地(不需要遍历)将其元素精确地分成两部分,允许平衡的并行计算。许多偏离这一理想的方法仍然非常有效;例如,只有大约分割一棵近似平衡的树,或者对于叶节点可能包含一个或两个元素的树,不能进一步分割这些节点。然而,平衡偏差过大和/或trySplit力学效率过低通常导致并行性能较差。

以及方法结构和注释。

代码语言:javascript
复制
 public Spliterator<T> trySplit() {
   int lo = origin; // divide range in half
   int mid = ((lo + fence) >>> 1) & ~1; // force midpoint to be even
   if (lo < mid) { // split out left half
     origin = mid; // reset this Spliterator's origin
     return new TaggedArraySpliterator<>(array, lo, mid);
   }
   else       // too small to split
     return null;
 }

欲了解更多曝光信息,请阅读https://docs.oracle.com/javase/8/docs/api/java/util/Spliterator.html

票数 1
EN

Stack Overflow用户

发布于 2018-10-26 12:21:26

下面是实现Spliterator的示例。

代码语言:javascript
复制
public class Payment {
    private String category;
    private double amount;

    public Payment(double amount, String category) {
        this.amount = amount;
        this.category = category;
    }

    public String getCategory() {
        return category;
    }

    public double getAmount() {
        return amount;
    }
}

TrySplit实现:

代码语言:javascript
复制
import java.util.List;
import java.util.Spliterator;
import java.util.function.Consumer;

public class PaymentBatchSpliterator implements Spliterator<Payment> {

    private List<Payment> paymentList;
    private int current;
    private int last;  // inclusive

    public PaymentBatchSpliterator(List<Payment> payments) {
        this.paymentList = payments;
        last = paymentList.size() - 1;
    }

    public PaymentBatchSpliterator(List<Payment> payments, int start, int last) {
        this.paymentList = payments;
        this.current = start;
        this.last = last;
    }

    @Override
    public boolean tryAdvance(Consumer<? super Payment> action) {
        if (current <= last) {
            action.accept(paymentList.get(current));
            current++;
            return true;
        }
        return false;
    }

    @Override
    public Spliterator<Payment> trySplit() {
        if ((last - current) < 100) {
            return null;
        }

        // first stab at finding a split position
        int splitPosition = current + (last - current) / 2;
        // if the categories are the same, we can't split here, as we are in the middle of a batch
        String categoryBeforeSplit = paymentList.get(splitPosition-1).getCategory();
        String categoryAfterSplit = paymentList.get(splitPosition).getCategory();

        // keep moving forward until we reach a split between categories
        while (categoryBeforeSplit.equals(categoryAfterSplit)) {
            splitPosition++;
            categoryBeforeSplit = categoryAfterSplit;
            categoryAfterSplit = paymentList.get(splitPosition).getCategory();
        }

        // safe to create a new spliterator
        PaymentBatchSpliterator secondHalf = new PaymentBatchSpliterator(paymentList,splitPosition,last);
        // reset our own last value
        last = splitPosition - 1;

        return secondHalf;
    }

    @Override
    public long estimateSize() {
        return last - current;
    }

    @Override
    public int characteristics() {
        return 0;
    }
}

Is是GitHub 参考文献的一个示例。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53008076

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档