以单线forms获取Stream / List的最后一个元素

如何获得下面的代码中的stream或列表的最后一个元素?

where 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获取它。 (这只对有限的stream才有意义)
  • 也似乎你不能从List接口得到first()last()这样的东西,这真的很痛苦。

我没有看到在List接口中没有提供first()last()方法的任何参数,因为那里的元素是有序的,而且大小是已知的。

但按照原来的答案:如何获得有限的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 ,这很可能不是您通常想要的,因为它可能会影响性能。

使用Stream :: reduce方法可以得到最后一个元素。 以下列表包含一般情况的一个简单示例:

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

这个实现适用于所有有序的stream (包括从列表创build的stream)。 对于无序的stream,没有指定哪个元素将被返回是显而易见的原因。

该实现适用于顺序 stream并行stream 。 乍一看,这可能会令人惊讶,不幸的是,文件没有明确说明。 但是,这是stream的重要特征,我试图澄清它:

  • 方法Stream :: reduce状态的Javadoc,它不受限于顺序执行”
  • Javadoc还要求“累加器函数必须是结合两个值的关联无干扰无状态函数” ,这对于lambdaexpression式(first, second) -> second显然是这种情况。
  • 用于约简操作的Javadoc指出: “stream类具有多种forms的通用约简操作,称为reduce()和collect() [..]”,并且“适当构造的约 简操作 本质上是可并行化的 ,只要函数)用来处理元素是联想和无状态的 。“

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


回到原来的问题:下面的代码存储对最后一个variables元素的引用,如果stream为空,则引发exception。 stream的长度的复杂性是线性的。

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

如果你有一个Collection(或者更一般的Iterable),你可以使用Google Guava的

 Iterables.getLast(myIterable) 

作为方便的在线。

一个class轮(不需要stream);

 Object lastElement = list.get(list.size()-1); 

由于目前还不清楚它是否是API规范的一部分,以reduce服从碰撞命令,那么:

 CArea last = data.careas.stream() .filter(c -> c.bbox.orientationHorizontal) .max((e1, e2) -> data.careas.indexOf(e1) - data.careas.indexOf(e2)).get(); 

正如@nosid提到的那样,可以使用reduce来完成。 这样做的另一种方法是倒转stream,然后得到第一个元素

 CArea last = data.careas.stream() .filter(c -> c.bbox.orientationHorizontal) .sorted((a, b)-> -1) .findFirst().get(); 

您可以使用以下静态方法使用java.util.Collections

 Collections.max(yourList); 

从文档:

根据元素的自然sorting ,返回给定集合的最大元素。 […]