Thi*_*sse 3 java collections java-8 java-stream
首先,我希望以前没有问过这个问题.我看了一下,找不到合适的答案:s
当特定条件成立时,我正在寻找一种将一些对象从一个集合移动到另一个集合的有效方法.
目前,我会以非常简单的方式做到这一点,但我担心这可能不是最佳的:
Collection<Object> myFirstCollection; //let's consider it instanciated and populated
Collection<Object> mySecondCollection; //same for this one
myFirstCollection.stream().forEach(o -> {
if ( conditionReturningTrue(o) ) {
mySecondCollection.add(o);
myFirstCollection.remove(o);
}
});
Run Code Online (Sandbox Code Playgroud)
你知道更好的方式/更有效率吗?
为了使其更具可读性,也有Collection::addAll和Collection::removeAll在这种情况下使用,你的代码可以是:
// create a new Collection where you use filter to search only the Object you want
Collection<Object> filterdCollection = myFirstCollection.stream()
.filter(o -> conditionReturningTrue(o))
.collect(Collectors.toCollection(LinkedHashSet::new));
// use allAll to add all the filtered Object to the second collection
mySecondCollection.addAll(filterdCollection);
// use removeAll to remove all the filtered Object from the first collection
myFirstCollection.removeAll(filterdCollection);
Run Code Online (Sandbox Code Playgroud)
首先,你应该努力争取正确性.对于大多数集合,禁止在迭代时修改源集合.您可能会ConcurrentModificationException尝试一段时间,但即使它碰巧运行没有异常,代码仍然是不正确的.只是这个错误并不总是被检测到(这是一次尽力而为的检查,试图避免浪费太多的性能).这适用于forEach(…),以及stream().forEach(…)for-each循环(for(variable declaration: collection))
迭代时删除元素的唯一支持是通过手动Iterator使用:
for(Iterator<Object> it = myFirstCollection.iterator(); it.hasNext(); ) {
Object o = it.next();
if(conditionReturningTrue(o)) {
it.remove();
mySecondCollection.add(o);
}
}
Run Code Online (Sandbox Code Playgroud)
替代方法是批量方法.
首先,像显示在这个和那个答案,创建所有元素的副本将被首先转移.
其次,你可以使用
myFirstCollection.removeIf(o -> conditionReturningTrue(o) && mySecondCollection.add(o));
Run Code Online (Sandbox Code Playgroud)
所述default的实施removeIf采用了Iterator以类似于上述的一个循环.但是,集合ArrayList提供了自己的实现removeIf,以克服Iterator循环的二次时间复杂度.
| 归档时间: |
|
| 查看次数: |
200 次 |
| 最近记录: |