使用并行流执行基于条件的添加

问题描述 投票:2回答:2

我有第一种方法,其任务是基本上根据条件计算属性列表中的条目总和。我试图使用并行流来实现这一点(假设列表很大)。虽然我在这里使用原子双来处理竞争条件,但我不确定这是否是最好的方法,因为Java8内置了许多功能。

码:

public double getSum(List<SomeObject> list, boolean flag1, boolean flag2){
    AtomicDouble sum = new AtomicDouble();
    list.parallelStream().forEach(item -> {
        if(flag1){
            sum.addAndGet(flag2 ? item.getFirstData() : item.getSecondData());
        } else {
            sum.addAndGet(flag2 ? item.getThirdData() :item.getFourthData());
        }
    });
    return sum.doubleValue();
}

对于第二种方法,我们如何做到:

enter code herepublic double getSum(Set<String> keys, HashMap<String, SomeObject> map, boolean flag1, boolean flag2){
    AtomicDouble sum = new AtomicDouble();

    keys.parallelStream().forEach(key -> {
        SomeObject item = map.get(key);
        if(flag1){
            sum.addAndGet(flag2 ? item.getFirstData() : item.getSecondData());
        } else {
            sum.addAndGet(flag2 ? item.getThirdData() :item.getFourthData());
        }
    });
    return sum.doubleValue();
}
java java-stream
2个回答
0
投票

正如在注释中所建议的并且给出了代码的第二个版本,您可以使用以下约定。根据ToDoubleFunctionflag1的条件逻辑创建一个flag2,如下所示:

boolean flag1, flag2; // provided as in your input
// create a ToDoubleFunction for conversion based on the above
ToDoubleFunction<SomeObject> chooseValue = new ToDoubleFunction<>() {
    @Override
    public double applyAsDouble(SomeObject value) {
        return flag1 ?
                flag2 ? value.getFirstData() : value.getSecondData() :
                flag2 ? value.getThirdData() : value.getFourthData();
    }
};

表示为:

ToDoubleFunction<SomeObject> chooseValue = value -> flag1 ?
        flag2 ? value.getFirstData() : value.getSecondData() :
        flag2 ? value.getThirdData() : value.getFourthData();

此后,在现有代码中使用相同的功能,您可以将其更新为:

public double getSum(List<SomeObject> list) {
    return list.parallelStream()
            .mapToDouble(chooseValue)
            .sum();
}

并在您的更新版本中;

public double getSum(Set<String> keys, Map<String, SomeObject> map) {
    return keys.stream()
            .filter(map::containsKey)
            .map(map::get)
            .mapToDouble(chooseValue)
            .sum();
}

0
投票

标志一次传递给方法,它们的值在执行期间不会改变,因此不需要为每个项目评估它们。此外,使用AtomicDouble似乎是多余的。您应该只将项目映射到double并让流汇总它们:

public double getSum(List<SomeObject> list, boolean flag1, boolean flag2){
    ToDoubleFunction<SomeObject> mapper;
    if (flag1) {
        if (flag2) {
            mapper = SomeObject::getFirstData;
        } else {
            mapper = SomeObject::getSecondData;
        }
    } else {
        if (flag2) {
            mapper = SomeObject::getThirdData;
        } else {
            mapper = SomeObject::getFourthData;
        }
    }
    return list.parallelStream().mapToDouble(mapper).sum();
}
© www.soinside.com 2019 - 2024. All rights reserved.