我有一个第一种方法,其任务是根据条件as基本计算属性列表中条目的总和。我正在尝试使用并行流来实现这一点(可以说列表很大)。尽管我在这里使用原子双精度来处理竞争条件,但是我不确定这是否是最好的方法,因为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();
}
答案 0 :(得分:0)
根据注释中的建议并提供第二版代码,您可以使用以下约定。根据来自ToDoubleFunction
和flag1
的条件逻辑,创建一个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();
}
答案 1 :(得分: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();
}