【问题标题】:Compare two lists for updates, deletions and additions比较两个列表的更新、删除和添加
【发布时间】:2010-12-12 15:42:41
【问题描述】:

简单的问题。

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

我可以自己写,但想知道是否有标准的方法。

列表中的对象正确地实现了。

【问题讨论】:

  • 您是否关心列表顺序?例如,迄今为止建议的涉及retainAll / removeAll 的解决方案将无法处理新列表包含与旧列表相同的元素的情况,尽管顺序不同;例如{"foo", "bar"} vs {"bar", "foo"}。
  • 只要实现了equals方法,我不明白为什么顺序会影响removeAll等。当然不会在javadoc中建议:从此列表中删除指定中包含的所有元素收集(可选操作)。

标签: java collections


【解决方案1】:

抱歉,没有标准方法。但是,您可以使用标准 JDK 轻松完成此操作,而无需添加对 Apache Commons 的依赖项(正如其他人所建议的那样)。假设您的列表是 List<T> 实例:

List<T> oldList = ...
List<T> newList= ...

List<T> removed = new ArrayList<T>(oldList);
removed.removeAll(newList);

List<T> same = new ArrayList<T>(oldList);
same.retainAll(newList);

List<T> added = new ArrayList<T>(newList);
added.removeAll(oldList);

【讨论】:

  • 不幸的是,这有点错误...... removeAll 和类似的操作传入的列表并返回一个布尔值。所以不会编译。需要是: List added = new ArrayList(newList);添加.removeAll(oldList);等等...所以毕竟可能有 apache commons 方法的情况...
【解决方案2】:

标准库中什么都没有。

但是,Apache Commons CollectionUtils 类通过交集和减法为您提供了此功能:

Collection<T> old = ...;
Collection<T> neww = ...;

Collection<T> deleted = (Collection<T>)CollectionUtils.subtract(old, new);
Collection<T> updated = (Collection<T>)CollectionUtils.intersection(old, new);
Collection<T> newResult = (Collection<T>)CollectionUtils.subtract(new, old);

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

【讨论】:

    【解决方案3】:

    我会使用 Apache CollectionUtils 并使用联合(两者中的项目)和析取函数(更改顺序以获得其中一个)。

    理想情况下,您应该遍历所有元素而不是 3 个,但如果这不是您的瓶颈,我现在不会担心效率。

    【讨论】:

      【解决方案4】:

      就个人而言,我认为解释两个 列表 之间差异的唯一明智方法是使用成熟的 diff 算法(如 unix diff 命令的算法)。

      但是,

      Sets 是一个简单得多的故事。 Google Collections 提供了Sets.difference(Set, Set) 方法,以及联合和交集。

      【讨论】:

        【解决方案5】:

        我认为您也可以使用标准 java 库来完成此操作。看看java.util.Collection的以下方法:

        retainAll(集合 c)

        只保留 this 中的元素 集合中包含的 指定的集合(可选 手术)。换句话说,删除 从这个集合中,它的所有 不包含在 指定的集合。

        removeAll(集合 c)

        删除此集合的所有元素 也包含在 指定的集合(可选 手术)。此调用返回后, 这个集合将不包含 与指定的共同元素 收藏。

        【讨论】:

          【解决方案6】:

          如果有标准的方法,我不知道...
          我查看了Collections,但只看到了 disjoint() (这已经是一个信息......)和 indexOfSubList() (不确定它是否有用)。
          我还查看了Google Collections,如果显然没有这样的工具,那里有一些有用的工具,比如Collections2 的 filter() 函数,如果你做出正确的谓词,它会有所帮助。

          [编辑] 我错过了 Collection 的 removeAll 和 retainAll 方法......我不会删除这个答案,即使有点可悲,因为它在某种程度上是其他答案的补充......(我认为 Google Collections 是至少值得一提!)

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-07-05
            • 1970-01-01
            • 2016-03-23
            • 1970-01-01
            • 1970-01-01
            • 2016-08-10
            相关资源
            最近更新 更多