简体   繁体   English

比较 Java 中的两个集合

[英]Comparing two Collections in Java

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任何帮助表示赞赏

Difficult to help, because you didn't tell us how you 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 relies on a correct implementation of equals() on the Car type!该算法依赖Car类型上equals()的正确实现!

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

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

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

This algorithm will run in linear time assuming you've implemented an efficient hashCode() method.假设您已经实现了一个高效的hashCode()方法,该算法将在线性时间内运行。

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

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);
}
public static boolean isEqualCollection(java.util.Collection a,
                                        java.util.Collection b)

Returns true if the given Collections contain exactly the same elements with exactly the same cardinalities.如果给定的 Collections 包含具有完全相同基数的完全相同的元素,则返回 true。

That is, iff the cardinality of e in a is equal to the cardinality of e in b, for each element e in a or b.也就是说,如果 a 中 e 的基数等于 b 中 e 的基数,对于 a 或 b 中的每个元素 e。

Parameters :参数

  • the first collection, must not be null第一个集合,不能为空
  • the second collection, must not be null第二个集合,不能为空

Returns : true iff the collections contain the same elements with the same cardinalities.返回: true 如果集合包含具有相同基数的相同元素。

return collection1.toString().equals(collection2.toString());

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM