Mar*_*zzi 65 java lambda java-8 java-stream
鉴于元素的列表,我想用一个给定的属性来获取元素,并从列表中删除.我找到的最佳解决方案是:
ProducerDTO p = producersProcedureActive
.stream()
.filter(producer -> producer.getPod().equals(pod))
.findFirst()
.get();
producersProcedureActive.remove(p);
Run Code Online (Sandbox Code Playgroud)
是否可以在lambda表达式中组合get和remove?
小智 104
要从列表中删除元素
objectA.removeIf(x - > conditions);
例如:objectA.removeIf(x - > blockedWorkerIds.contains(x));
objectA.removeIf(x -> conditions);
Run Code Online (Sandbox Code Playgroud)
输出: A B C.
asi*_*d88 29
虽然线程很老,但仍然认为提供解决方案 - 使用Java8
.
使用removeIf
功能.时间复杂性是O(n)
producersProcedureActive.removeIf(producer -> producer.getPod().equals(pod));
Run Code Online (Sandbox Code Playgroud)
API参考:removeIf docs
假设:producersProcedureActive
是一个List
注意:使用此方法,您将无法保留已删除的项目.
Vas*_*sky 15
考虑使用vanilla java迭代器来执行任务:
public static <T> T findAndRemoveFirst(Iterable<? extends T> collection, Predicate<? super T> test) {
T value = null;
for (Iterator<? extends T> it = collection.iterator(); it.hasNext();)
if (test.test(value = it.next())) {
it.remove();
return value;
}
return null;
}
Run Code Online (Sandbox Code Playgroud)
优点:
Iterable
甚至可以在没有stream()
支持的情况下完成它(至少那些remove()
在它们的迭代器上实现).缺点:
至于
是否可以在lambda表达式中组合get和remove?
其他答案清楚地表明它是可能的,但你应该知道
ConcurrentModificationException
从正在迭代的列表中删除元素时可能会抛出Tun*_*aki 10
直接的解决方案是调用ifPresent(consumer)
Optional返回的findFirst()
.当optional不为空时,将调用此使用者.好处还在于,如果find操作返回一个空的可选项,它将不会抛出异常,就像您当前的代码一样; 相反,什么都不会发生.
如果你想返回删除值,你可以map
在Optional
调用的结果remove
:
producersProcedureActive.stream()
.filter(producer -> producer.getPod().equals(pod))
.findFirst()
.map(p -> {
producersProcedureActive.remove(p);
return p;
});
Run Code Online (Sandbox Code Playgroud)
但请注意,该remove(Object)
操作将再次遍历列表以查找要删除的元素.如果你有一个随机访问列表,比如a ArrayList
,最好在列表的索引上创建一个Stream,并找到与谓词匹配的第一个索引:
IntStream.range(0, producersProcedureActive.size())
.filter(i -> producersProcedureActive.get(i).getPod().equals(pod))
.boxed()
.findFirst()
.map(i -> producersProcedureActive.remove((int) i));
Run Code Online (Sandbox Code Playgroud)
使用此解决方案,remove(int)
操作直接在索引上运行.
使用可以使用Java 8的过滤器,如果您不想更改旧列表,则创建另一个列表:
List<ProducerDTO> result = producersProcedureActive
.stream()
.filter(producer -> producer.getPod().equals(pod))
.collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)
我确信这将是一个不受欢迎的答案,但它有效......
ProducerDTO[] p = new ProducerDTO[1];
producersProcedureActive
.stream()
.filter(producer -> producer.getPod().equals(pod))
.findFirst()
.ifPresent(producer -> {producersProcedureActive.remove(producer); p[0] = producer;}
Run Code Online (Sandbox Code Playgroud)
p[0]
将保存找到的元素或为空。
这里的“技巧”是通过使用有效最终的数组引用来规避“有效最终”问题,但设置其第一个元素。
归档时间: |
|
查看次数: |
96812 次 |
最近记录: |