我有第一种方法,其任务是基本上根据条件计算属性列表中的条目总和。我试图使用并行流来实现这一点(假设列表很大)。虽然我在这里使用原子双来处理竞争条件,但我不确定这是否是最好的方法,因为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();
}
正如在注释中所建议的并且给出了代码的第二个版本,您可以使用以下约定。根据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();
}
标志一次传递给方法,它们的值在执行期间不会改变,因此不需要为每个项目评估它们。此外,使用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();
}