开发者

Comparing two Collections in Java

I have two Collections in a Java class.The first collection contains previous data, the second开发者_JAVA技巧 contains updated data from the previous collection.

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.

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!

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


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

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.
  • 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. If the Integer value has reached zero then remove the (Entity, Integer) entry from the map.

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


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):

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.

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.

Parameters:

  • the first collection, must not be null
  • the second collection, must not be null

Returns: true if the collections contain the same elements with the same cardinalities.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜