亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何根據謂詞有效地將對象從一個 java 集合轉移到另一個 java 集合?

如何根據謂詞有效地將對象從一個 java 集合轉移到另一個 java 集合?

喵喵時光機 2021-09-15 15:23:26
首先,我希望這個問題以前沒有被問過。我看了一點,找不到合適的答案:s我正在尋找一種在特定條件為真時將某些對象從一個集合移動到另一個集合的有效方法。目前,我會以一種非常簡單的方式來做,但恐怕這可能不是最佳的:Collection<Object> myFirstCollection;  //let's consider it instanciated and populatedCollection<Object> mySecondCollection; //same for this onemyFirstCollection.stream().forEach(o -> {     if ( conditionReturningTrue(o) ) {        mySecondCollection.add(o);        myFirstCollection.remove(o);    }});你知道有什么更好的方法/更有效的方法嗎?
查看完整描述

3 回答

?
holdtom

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);


查看完整回答
反對 回復 2021-09-15
?
慕萊塢森

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循環的二次時間復雜度。


查看完整回答
反對 回復 2021-09-15
?
梵蒂岡之花

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。


查看完整回答
反對 回復 2021-09-15
  • 3 回答
  • 0 關注
  • 265 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號