在一行中获取 Stream/List 的最后一个元素

新手上路,请多包涵

如何在以下代码中获取流或列表的最后一个元素?

其中 data.careas 是一个 List<CArea>

 CArea first = data.careas.stream()
                  .filter(c -> c.bbox.orientationHorizontal).findFirst().get();

CArea last = data.careas.stream()
                 .filter(c -> c.bbox.orientationHorizontal)
                 .collect(Collectors.toList()).; //how to?

如您所见,使用某个 filter 获取第一个元素并不难。

然而,获取单行中的最后一个元素是一个真正的痛苦:

  • 看来我无法直接从 Stream 获得它。 (这只对有限流有意义)
  • 似乎您也无法从 List 界面获得诸如 first()last() 之类的东西,这真的很痛苦。

我没有看到任何关于不提供 first()last() 方法的 List 接口中的方法和更多的元素,如众所周知。

但根据原始答案:How to get the last element of a finite Stream

就个人而言,这是我能得到的最接近的:

 int lastIndex = data.careas.stream()
        .filter(c -> c.bbox.orientationHorizontal)
        .mapToInt(c -> data.careas.indexOf(c)).max().getAsInt();
CArea last = data.careas.get(lastIndex);

但是,它确实涉及在每个元素上使用 indexOf ,这很可能不是您通常想要的,因为它会影响性能。

原文由 skiwi 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.5k
2 个回答

可以使用 Stream::reduce 方法获取最后一个元素。以下清单包含一般情况的最小示例:

 Stream<T> stream = ...; // sequential or parallel stream
Optional<T> last = stream.reduce((first, second) -> second);

此实现适用于所有 有序流(包括从 Lists 创建的流)。对于 无序 流,由于显而易见的原因,未指定将返回哪个元素。

该实现适用于 顺序 流和 并行流。乍一看这可能令人惊讶,不幸的是文档没有明确说明。然而,它是流的一个重要特性,我试着澄清一下:

  • Stream::reduce 方法的 Javadoc 指出,它 不受 限于 按顺序 执行”
  • Javadoc 还要求 “累加器函数必须是 关联 的、 非干扰的无状态 的函数,用于组合两个值” ,这显然是 lambda 表达式 (first, second) -> second 的情况。
  • 用于 缩减操作 的 Javadoc 指出: “流类具有多种形式的通用缩减操作,称为 reduce()collect() [..]”“正确构造的缩减操作 本质上是可并行化 的,只要函数(s ) 用于处理元素是 关联 的和 无状态 的。”

密切相关的 收集器 的文档更加明确: “为了确保 顺序 执行和 并行执行 产生 相同的结果,收集器函数必须满足身份和 关联性 约束。”


回到最初的问题:下面的代码存储了对变量中最后一个元素的引用 last ,如果流为空则抛出异常。复杂度与流的长度成线性关系。

 CArea last = data.careas
                 .stream()
                 .filter(c -> c.bbox.orientationHorizontal)
                 .reduce((first, second) -> second).get();

原文由 nosid 发布,翻译遵循 CC BY-SA 4.0 许可协议

如果您有一个集合(或更一般的 Iterable),您可以使用 Google Guava 的

Iterables.getLast(myIterable)

作为方便的 oneliner。

原文由 Peti 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题