How to subtract comparator collections instead of overriding equal

I want to calculate the differences between collections. When using CollectionUtils.subtract () for custom comparison, I need to override the equals () method of the object. But what if I need to compare collections of objects of the same type but with different comparison criteria? What about the comparator interface, does it seem to fit perfectly? The AFAIK comparator is mainly used for sorting. Is there a method that uses comparators to subtract?

+4
source share
2 answers

If you have an ArrayList, multiple deletions may be more expensive than copying.

List<Type> list = /* ArrayList */ Set<Type> toRemove = /* HashSet */ List<Type> copy = new ArrayList<Type>(list.size()); for(Type t: list) if(!toRemove.contains(t)) copy.add(t); list = copy; 

Personally, I would use a loop. It will probably be shorter and clearer.

 Collection<Type> collection = for(Iterator<Type> i=collection.iterator(); i.hasNext();) if (i.next() is to be removed) i.remove(); 

The reason iterator is used explicitly is to use iterator.remove (), which throws a ConcurrentModificationException. Another way to avoid this is to use a copy of the collection, which may be preferable.

 for(Type t : new ArrayList<Type>(collection)) if (t is to be removed) collection.remove(t); 

This does not work, but may work quite well.

+2
source
 static <Type> Collection<Type> subtract(Collection<Type> a, Collection<Type> b, Comparator<Type> c) { Set<Type> subtrahend = new TreeSet<Type>(c); subtrahend.addAll(b); Collection<Type> result = new ArrayList<Type>(); for (Type item: a) { if (!subtrahend.contains(item)) result.add(item); } return result; } 

The subtrahent set subtrahent not required, but will improve performance for large b .

+3
source