gpt4 book ai didi

如果列表为空,Java lambda 返回 null,否则返回值的总和?

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:43:12 24 4
gpt4 key购买 nike

如果我想汇总一个账户的当前余额列表,我可以这样做:

accountOverview.setCurrentBalance(account.stream().
filter(a -> a.getCurrentBalance() != null).
mapToLong(a -> a.getCurrentBalance()).
sum());

但是这个表达式将返回 0,即使所有余额都为空。如果所有余额都为空,我希望它返回 null,如果有非空 0 余额,则返回 0,否则返回余额之和。

如何使用 lambda 表达式执行此操作?

非常感谢

最佳答案

一旦从流中过滤掉它们,就无法知道是否所有余额都是 null (除非检查 count() 返回的内容,否则您将无法使用该流,因为它是终端操作)。

对数据进行两次传递可能是直接的解决方案,我可能会首先采用:

boolean allNulls = account.stream().map(Account::getBalance).allMatch(Objects::isNull);

Long sum = allNulls ? null : account.stream().map(Account::getBalance).filter(Objects::nonNull).mapToLong(l -> l).sum();

您可以使用 reduce 的解决方案摆脱过滤步骤,尽管可读性可能不是最好的:

Long sum = account.stream()
.reduce(null, (l1, l2) -> l1 == null ? l2 :
l2 == null ? l1 : Long.valueOf(l1 + l2));

注意 Long.valueOf称呼。这是为了避免条件表达式的类型是long。 ,因此在某些边缘情况下是 NPE。


另一种解决方案是使用 Optional应用程序接口(interface)。首先,创建一个 Stream<Optional<Long>>从余额值中减去它们:

Optional<Long> opt = account.stream()
.map(Account::getBalance)
.flatMap(l -> Stream.of(Optional.ofNullable(l)))
.reduce(Optional.empty(),
(o1, o2) -> o1.isPresent() ? o1.map(l -> l + o2.orElse(0L)) : o2);

这会给你一个 Optional<Long>如果所有值都是 null,那将是空的,否则它将为您提供非空值的总和。

或者您可能想为此创建一个自定义收集器:

class SumIntoOptional {

private boolean allNull = true;
private long sum = 0L;

public SumIntoOptional() {}

public void add(Long value) {
if(value != null) {
allNull = false;
sum += value;
}
}

public void merge(SumIntoOptional other) {
if(!other.allNull) {
allNull = false;
sum += other.sum;
}
}

public OptionalLong getSum() {
return allNull ? OptionalLong.empty() : OptionalLong.of(sum);
}
}

然后:

OptionalLong opt = account.stream().map(Account::getBalance).collect(SumIntoOptional::new, SumIntoOptional::add, SumIntoOptional::merge).getSum();


如您所见,有多种方法可以实现这一点,所以我的建议是:首先选择最易读的。如果您的解决方案出现性能问题,请检查它是否可以改进(通过并行转换流或使用其他替代方案)。但是测量,不要猜测。

关于如果列表为空,Java lambda 返回 null,否则返回值的总和?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31785082/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com