Reputation: 637
I have two Collections in a Java class.The first collection contains previous data, the second 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
Upvotes: 19
Views: 65675
Reputation: 87
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:
Returns: true if the collections contain the same elements with the same cardinalities.
Upvotes: 0
Reputation: 4262
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;
}
Upvotes: 3
Reputation: 821
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);
Upvotes: 22
Reputation: 6330
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);
}
Upvotes: 2
Reputation: 114777
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;
}
Upvotes: 32
Reputation: 54705
Map<Entity, Integer>
whereby Entity
is the class being stored in your collection and the Integer
represents the number of times it occurs.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.
Upvotes: 6