我有一个大约一百万个元素的有序列表
,我正在寻找与特定条件匹配的最后一个元素,但是条件计算起来很重,所以如果我从头开始会更好。总是有大致的 log(n)
匹配元素,最小值为 1。
我可以手动操作:
List<Element> elements = ...;
Element element = null;
for (var it = elements.listIterator(elements.size()); it.hasPrevious(); ) {
var candidate = it.previous();
if (heavyConditionPredicate.test(candidate)) {
element = candidate;
break;
}
}
有没有办法用< code>Streams来写这个,这样< code > heavyConditionPredicate 就不用对列表的每个元素进行测试了?如果heavyConditionPredicate计算起来不那么重,我会使用其他方法,但我没有那么幸运。
注意,< code>elements可以是任何类型的< code>List,我得到的那个不一定实现< code>RandomAccess,所以通过它们的索引访问列表可能也是代价很高的。
Stream
的当前实现(从Java11开始)的缺点是它不允许以相反的顺序处理项目。您必须为其提供具有指定顺序的源:
List<Element> elements = new ArrayList<>();
List<Element> reversedElements = new ArrayList<>(elements);
Collections.reverse(reversedElements);
Element element = reversedElements.stream().filter(heavyConditionPredicate).findFirst().orElse(null);
另一种方法是利用Deque
接口的优势,该接口提供Deque::descendingIterator
:
Deque<Element> elements = new ArrayDeque<>();
Iterator<Element> it = elements.descendingIterator()
使用Deque::推送
,您可以创建一个自定义StreamUtils
方法来反转传递的Stream
,而无需使用外部库:
class StreamUtils {
static <T> Stream<T> reverse(Stream<T> stream) {
Deque<T> deque = new ArrayDeque<>();
stream.forEach(deque::push);
return deque.stream();
}
}
...
Element element = StreamUtils.reverse(elements.stream())
.filter(heavyConditionPredicate)
.findFirst().orElse(null);
Guava的< code>Lists::reverse在这里肯定有帮助,因为它是一个视图,它不修改我的列表,也不通过索引访问元素:
Lists.reverse(elements).stream()
.filter(heavyConditionPredicate)
.findFirst();
问题内容: 如何在以下代码中获取流或列表的最后一个元素? 哪里是: 如您所见,获得第一个元素一定并不困难。 但是,获得单线的最后一个元素确实是一个痛苦: 看来我无法直接从。(仅对有限的流有意义) 这似乎也不能得到像和从接口,这实在是一种痛苦。 我看不到在接口中不提供and 方法的任何参数,因为其中的元素是有序的,而且大小是已知的。 但是按照原始答案:如何获得有限的最后一个元素? 就个人而言,这是我
问题内容: 我的情况是: 我想知道是否有一个名字和年龄相同但不在乎的人。 什么是最快的方法? 问题答案: 为自己定义一个关键对象,该对象可以保存并比较所需的属性。在这种简单情况下,您可以使用一个小的列表,而每个索引对应一个属性。对于更复杂的情况,可以使用(使用属性名称作为键)或专用类: 具有这种映射功能。您可以使用简单的解决方案: 当您的列表很大时,这可能会导致性能不佳。如果列表很大(或者无法预测
如何在下面的代码中获取流或列表的最后一个元素? 其中是: 正如您所看到的,使用特定的获取第一个元素并不难。 null 我看不出在接口中没有提供和方法的任何理由,因为其中的元素是有序的,而且大小是已知的。 但正如最初的答案:如何获得有限的最后一个元素? 就我个人而言,这是我能得到的最接近的结果:
问题内容: 我想匹配字符串中最后一次出现的简单模式,例如 但是,如果字符串 很 长,则会生成大量匹配项。有没有更直接的方法来匹配第二次出现的“ AAAA”,还是应该使用此替代方法? 问题答案: 您可以使用表示行末字符: 另外,请注意,这是变量的坏名称,因为它隐藏了内置类型。要访问列表的最后一个元素,您可以使用index: