如何根据谓词有效地将对象从一个 java 集合转移到另一个 java 集合?

首先,我希望这个问题以前没有被问过。我看了一点,找不到合适的答案: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);

    }

});

你知道有什么更好的方法/更有效的方法吗?


喵喵时光机
浏览 226回答 3
3回答

holdtom

为了使其更具可读性,在这种情况下有Collection::addAll并Collection::removeAll使用,您的代码可以是:// create a new Collection where you use filter to search only the Object you wantCollection<Object> filterdCollection = myFirstCollection.stream()&nbsp; &nbsp; &nbsp; &nbsp; .filter(o -> conditionReturningTrue(o))&nbsp; &nbsp; &nbsp; &nbsp; .collect(Collectors.toCollection(LinkedHashSet::new));// use allAll to add all the filtered Object to the second collectionmySecondCollection.addAll(filterdCollection);// use removeAll to remove all the filtered Object from the first collectionmyFirstCollection.removeAll(filterdCollection);

慕莱坞森

首先,你应该争取正确。对于大多数集合,禁止在迭代时修改源集合。您可能会ConcurrentModificationException尝试一段时间,但即使它碰巧无一例外地运行,代码仍然不正确。只是这个错误并不总是被检测到(这是一个尽力而为的检查,试图避免浪费太多的性能)。这适用于forEach(…)、 以及stream().forEach(…)和 for-each 循环 ( for(variable declaration: collection))在迭代时删除元素的唯一支持是通过手动Iterator使用:for(Iterator<Object> it = myFirstCollection.iterator(); it.hasNext(); ) {&nbsp; &nbsp; Object o = it.next();&nbsp; &nbsp; if(conditionReturningTrue(o)) {&nbsp; &nbsp; &nbsp; &nbsp; it.remove();&nbsp; &nbsp; &nbsp; &nbsp; mySecondCollection.add(o);&nbsp; &nbsp; }}替代方法是批量方法。首先,就像这个和那个答案中所示,创建要首先传输的所有元素的副本。其次,您可以使用myFirstCollection.removeIf(o -> conditionReturningTrue(o) && mySecondCollection.add(o));的default实现removeIf使用了Iterator一个类似于上面的循环。但是,像这样的集合ArrayList提供了它们自己的 实现removeIf,以克服Iterator循环的二次时间复杂度。

梵蒂冈之花

您可以通过避免removeAll(对于某些Collection对象查找需要线性搜索的Lists ,例如s,这可能需要二次时间)来提高性能,方法是使用Collectors.partitioningBy将原始文件拆分Collection为两个Lists:Collection<Object> myFirstCollection;&nbsp; //let's consider it instanciated and populatedCollection<Object> mySecondCollection; //same for this oneMap<Boolean,List<Object>> partition =&nbsp;&nbsp; &nbsp; myFirstCollection.stream()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.collect(Collectors.partitioningBy(o -> conditionReturningTrue(o)));myFirstCollection.clear();myFirstCollections.addAll(partition.get(false));mySecondCollection.addAll(partition.get(true));另一方面,如果只有少数元素应该从 移动myFirstCollection到,则此解决方案可能效率较低mySecondCollection。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java