在Java中比较两个集合

19

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

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

然后根据每个集合中的carType是否相同,我想执行carType方法。

感谢任何帮助。


4
如何在Java中最好地比较两个集合并对它们进行操作? - jmj
你期望从比较中得到什么结果?你想要提取那些没有改变的元素吗?你需要知道它们在集合中的索引吗(两个集合中的索引相同)... - pgras
抱歉,pgras,描述有些模糊。这些集合将按相同的顺序和相同的大小排列。新集合中的一些数据将从先前的集合中更新。基于carType、registrationNo和insurancePolicy在两个集合中相同,然后我将执行其他代码。 - damien535
未来的读者。如果你想比较两个集合……基于集合中项的标量属性的一些(或所有)值:请参阅https://dev59.com/7FkR5IYBdhLWcg3w3AwM#40718320 - granadaCoder
6个回答

31

很难提供帮助,因为您没有告诉我们您喜欢如何比较(相等大小的)集合。以下是一些想法,希望其中一个适用:

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

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

比较两个集合是否包含相同的对象,顺序可以是任意的

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

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

Iterator targetIt = target.iterator();
for (Object obj:source)
  if (!obj.equals(targetIt.next())
    // Element has changed
基于您的评论,以下算法可以实现此功能。它会收集所有已更新的汽车。如果方法结果是一个空列表,则两个集合包含相同顺序的相等条目。该算法依赖于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;
}

你在参数中使用了 new,这是不允许的。另外,在 findUpdatedCars 中,这个 new 是在哪里使用的? - Shervin Asgari
@Shervin和@Andreas_D,感谢你们的帮助。解释得非常清楚。非常感激! - damien535
3
记住,为了使这个方法起作用,你必须在你的Car对象中覆盖hashCode()equals()方法。 - Shervin Asgari

20

从集合论来看,如果A包含于B且B包含于A,则集合A和B相等。因此,在Java中,给定两个集合A和B,您可以使用以下方法检查它们是否相等(无需考虑元素的顺序):

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

4
这个说明对于集合是正确的,但对于允许重复元素的列表或其他结构可能不正确(换句话说,在可能的情况下使用集合可以简化逻辑)。 - cfeduke

6
  • 遍历第一个集合并将其添加到Map<Entity,Integer>中,其中Entity是存储在您的集合中的类,而Integer表示它出现的次数。
  • 遍历第二个集合,并针对每个元素尝试在Map中查找-如果存在,则将Integer值减一,并在找到匹配项时执行任何必要的操作。 如果Integer值已达到零,则从地图中删除(实体,整数)条目。

假设您已经实现了有效的hashCode()方法,此算法将以线性时间运行。


3

稍微更新了一下,考虑到了 null 值:

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

2
如果不担心类似于(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);
}

0
public static boolean isEqualCollection(java.util.Collection a,
                                        java.util.Collection b)

如果给定的集合包含完全相同的元素和基数,则返回true。

也就是说,对于a或b中的每个元素e,当且仅当e在a中的基数等于e在b中的基数时。

参数

  • 第一个集合,不能为空
  • 第二个集合,不能为空

返回值: 如果集合包含相同的元素和基数,则返回true。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接