以单线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 ,返回给定集合的最大元素。 […]