比较两个列表以进行更新,删除和添加

简单的问题。

我有一个新列表和一个旧列表。 在Java中是否有标准的方法/库,允许我比较这两个列表并确定哪些项目已更新/删除或是全新的? 例如,我最终应该有三个列表 – 已删除的项目(旧的但不是新的项目),更新的项目(两者中的项目),新项目(新项目(不是旧项目)。

我自己可以写这个,但想知道是否有标准的方法来做到这一点。

列表中的对象实现正确等于。

没有标准方式抱歉。 您可以使用标准JDK轻松地完成它,而无需依赖于对Apache Commons的依赖(正如其他人所建议的那样)。 假设您的列表是List实例:

 List oldList = ... List newList= ... List removed = new ArrayList(oldList); removed.removeAll(newList); List same = new ArrayList(oldList); same.retainAll(newList); List added = new ArrayList(newList); added.removeAll(oldList); 

标准库中没有任何内容。

但是,Apache Commons CollectionUtils类为您提供了交叉和减法方法的function:

 Collection old = ...; Collection neww = ...; Collection deleted = (Collection)CollectionUtils.subtract(old, new); Collection updated = (Collection)CollectionUtils.intersection(old, new); Collection newResult = (Collection)CollectionUtils.subtract(new, old); 

(您需要(未经检查)强制转换,因为CollectionUtils未被广泛化。)

我将使用Apache CollectionUtils并使用union(两者中的项)和析取函数(更改顺序以获取一个或另一个)。

理想情况下,你只需要通过所有元素而不是3,但如果这不是你的瓶颈,我现在不会担心效率。

就个人而言,我认为解释两个列表之间差异的唯一合理方法是使用完整的diff算法(类似于unix diff命令)。

但是, 集合是一个更简单的故事。 Google Collections提供了Sets.difference(Set,Set)方法,以及union和intersection。

我认为你也可以用标准的java库来实现这一点。 看一下java.util.Collection的以下方法:

retainAll(collectionsc)

仅保留此集合中包含在指定集合中的元素(可选操作)。 换句话说,从此集合中删除未包含在指定集合中的所有元素。

removeAll(Collection c)

删除所有此集合的元素,这些元素也包含在指定的集合中(可选操作)。 此调用返回后,此集合将不包含与指定集合相同的元素。

如果有标准方式,我不知道…
我查看了Collections,但只看到了disjoint()(这已经是一个信息……)和indexOfSubList()(不确定它是否有用)。
我还查看了Google Collections ,如果显然没有这样的工具,那里有一些有用的工具,比如Collections2的filter()函数,如果你制作一个合适的谓词,它可以帮助你。

[编辑]我错过了removeAll和retainAll方法的收集……我不删除这个答案,即使有点可怜,因为它在某种程度上是对其他答案的补充……(我认为Google Collections至少值得也罢!)