如何使用 lambda、Java 在列表迭代结束时返回值



尝试遍历对象列表以从迭代中获取最后一个参数的值。

long lastSeen = 0L;
for(Object o : list) {
lastSeen = o.getLastSeenId();
}
// will make use of the lastSeen.

我不能对lambda做同样的事情,

long lastSeen = 0L;
list.stream().forEach(o-> {
lastSeen = o.getLastSeenId();
});

因为我将以这个编译时结束。

封闭作用域中定义的局部变量 lastSeenId 必须是 final。 或有效的最终结果

我可以这样做来阅读最大的,但不想:

Set<Long> set = new HashSet<>();
list.stream().forEach(o-> {
set.add(mergeUser.getLastSeenId());
});

有没有更好的方法? 这样做的原因是监视上次看到的值循环处理(如果在发生异常的情况下终止(。

我看不出有任何理由需要迭代整个源代码来检索最后一个 id。这可以在没有迭代的情况下完成:

long lastSeen = list.size() > 0? list.get(list.size()-1).getLastSeenId() : 0L;

但是,如果您打算在每次迭代中做一些其他事情,而不仅仅是上述内容,那么我会坚持您当前的命令式方法。尝试在这里使用流并不合适,也不会为您带来任何好处。

首先reduce元素集以从Stream中获取最后一个元素。然后使用map从归约后的最后一个元素中获取所需的值。

final long lastSeenValue = objects.stream()
.reduce((first, second) -> second)
.map(LastSeen::getLastSeenId)
.orElse(null);

但是,在我看来,流可能不是您的问题陈述的更好选择。在这种情况下,不要犹豫,回到命令式方法。

如果你想继续使用Stream,你可以使用AtomicLong来保存lastSeenValue

final AtomicLong lastSeen = new AtomicLong(0);
list.stream().forEach(o-> {
lastSeen.set(o.getLastSeenId());
});

首先,我不会迭代获取最后一个元素的列表。

如果以防万一,如果你想流式传输并获取最后一个元素,"one.util.StreamEx"有一个更好的方法可以做到这一点:

StreamEx.of(list)
.collect(MoreCollectors.last())
.get();

最新更新