3 回答

TA貢獻1805條經驗 獲得超10個贊
為了使其更具可讀性,在這種情況下有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);

TA貢獻1810條經驗 獲得超4個贊
首先,你應該爭取正確。對于大多數集合,禁止在迭代時修改源集合。您可能會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);
}
}
替代方法是批量方法。
首先,就像這個和那個答案中所示,創建要首先傳輸的所有元素的副本。
其次,您可以使用
myFirstCollection.removeIf(o -> conditionReturningTrue(o) && mySecondCollection.add(o));
的default實現removeIf使用了Iterator一個類似于上面的循環。但是,像這樣的集合ArrayList提供了它們自己的 實現removeIf,以克服Iterator循環的二次時間復雜度。

TA貢獻1900條經驗 獲得超5個贊
您可以通過避免removeAll(對于某些Collection對象查找需要線性搜索的Lists ,例如s,這可能需要二次時間)來提高性能,方法是使用Collectors.partitioningBy將原始文件拆分Collection為兩個Lists:
Collection<Object> myFirstCollection; //let's consider it instanciated and populated
Collection<Object> mySecondCollection; //same for this one
Map<Boolean,List<Object>> partition =
myFirstCollection.stream()
.collect(Collectors.partitioningBy(o -> conditionReturningTrue(o)));
myFirstCollection.clear();
myFirstCollections.addAll(partition.get(false));
mySecondCollection.addAll(partition.get(true));
另一方面,如果只有少數元素應該從 移動myFirstCollection到,則此解決方案可能效率較低mySecondCollection。
添加回答
舉報