比较 Java 中的两个集合

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4085353/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 11:27:16  来源:igfitidea点击:

Comparing two Collections in Java

javacollections

提问by damien535

I have two Collections in a Java class.The first collection contains previous data, the second contains updated data from the previous collection.

我在 Java 类中有两个集合。第一个集合包含以前的数据,第二个包含来自前一个集合的更新数据。

I would like to compare the two collections but I'm not sure of the best way to implement this efficiently.Both collections will contain the same amount of items.

我想比较这两个集合,但我不确定有效实现这一点的最佳方法。两个集合将包含相同数量的项目。

Based then on the carType being the same in each collection I want to execute the carType method.

然后基于每个集合中的 carType 相同,我想执行 carType 方法。

Any help is appreciated

任何帮助表示赞赏

采纳答案by Andreas Dolk

Difficult to help, because you didn't tell us howyou like to compare the (equal-size) collections. Some ideas, hoping one will fit:

很难帮助,因为你没有告诉我们如何你想比较(大小相等)的集合。一些想法,希望一个适合:

Compare both collections if they contain the same objects in the same order

比较两个集合,如果它们以相同的顺序包含相同的对象

Iterator targetIt = target.iterator();
for (Object obj:source)
  if (!obj.equals(targetIt.next()))
    // compare result -> false

Compare both collections if they contain the same objects in the any order

比较两个集合,如果它们以任意顺序包含相同的对象

for (Object obj:source)
  if (target.contains(obj))
    // compare result -> false

Find elements in other collection that has changed

在其他集合中查找已更改的元素

Iterator targetIt = target.iterator();
for (Object obj:source)
  if (!obj.equals(targetIt.next())
    // Element has changed


Based on your comment, this algorithm would do it. It collects all Cars that have been updated. If the method result is an empty list, both collections contain equal entries in the same order. The algorithm relieson a correct implementation of equals()on the Cartype!

根据您的评论,该算法可以做到。它收集所有已更新的汽车。如果方法结果是一个空列表,则两个集合都包含相同顺序的相同条目。该算法依赖equals()Car类型的正确实现!

public List<Car> findUpdatedCars(Collection<Car> oldCars, Collection<Car> newCars)
  List<Car> updatedCars = new ArrayList<Car>();
  Iterator oldIt = oldCars.iterator();
  for (Car newCar:newCars) {
    if (!newCar.equals(oldIt.next()) {
      updatedCars.add(newCar);
    }
  }
  return updatedCars;
}

回答by Adamski

  • Iterate over the first collection and add it into a Map<Entity, Integer>whereby Entityis the class being stored in your collection and the Integerrepresents the number of times it occurs.
  • Iterate over the second collection and, for each element attempt to look it up in the Map- If it exists then decrement the Integervalue by one and perform any action necessary when a match is found. If the Integervalue has reached zero then remove the (Entity, Integer) entry from the map.
  • 迭代第一个集合并将其添加到一个中Map<Entity, Integer>,其中Entity是存储在您的集合中的类,并且Integer表示它出现的次数。
  • 迭代第二个集合,对于每个元素尝试在Map- 如果存在,则将Integer值减一并在找到匹配项时执行任何必要的操作。如果该Integer值已达到零,则从地图中删除 (Entity, Integer) 条目。

This algorithm will run in linear time assuming you've implemented an efficient hashCode()method.

假设您已经实施了一种有效的hashCode()方法,该算法将在线性时间内运行。

回答by gerardw

If not worried about cases like (2,2,3), (2,3,3):

如果不担心像 (2,2,3), (2,3,3) 这样的情况:

static <T> boolean equals(Collection<T> lhs, Collection<T> rhs) {
    return lhs.size( ) == rhs.size( ) && lhs.containsAll(rhs)  && rhs.containsAll(lhs);
}

回答by RedXIII

From the set arithmetics, the sets A and B are equal iff A subsetequal B and B subsetequal A. So, in Java, given two collections A and B you can check their equality without respect to the order of the elements with

从集合算术来看,集合 A 和 B 是相等的,仅当 A 子集等于 B 和 B 子集等于 A。因此,在 Java 中,给定两个集合 A 和 B,您可以检查它们的相等性,而不考虑元素的顺序

boolean collectionsAreEqual = A.containsAll(B) && B.containsAll(A);

回答by Rakesh

Slightly updated one considering null values:

考虑到空值,稍微更新了一个:

static <T> boolean equals(Collection<T> lhs, Collection<T> rhs) {
    boolean equals = false;
    if(lhs!=null && rhs!=null) {
       equals = lhs.size( ) == rhs.size( ) && lhs.containsAll(rhs)  && rhs.containsAll(lhs);
    } else if (lhs==null && rhs==null) {
       equals = true;
    }
 return equals;
}