如何使用Comparator接口减去集合而不是覆盖equals

时间:2011-09-08 12:32:24

标签: java collections comparator

我想计算集合之间的差异。当使用CollectionUtils.subtract()进行自定义比较时,我需要覆盖对象的equals()方法。但是,如果我需要比较相同类型但不同比较标准的对象集合呢?那么Comparator界面怎么样呢? AFAIK Comparator主要用于分类。是不是有使用比较器进行减法的方法?

2 个答案:

答案 0 :(得分:4)

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

subtrahent树集不是必需的,但会提高大型b的效果。

答案 1 :(得分:2)

如果你有一个ArrayList,多次删除可能比复制更昂贵。

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;

我个人会使用一个循环。它可能更短更清晰。

Collection<Type> collection =

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

显式使用Iterator的原因是使用Iterator.remove()来避免ConcurrentModificationException。另一种避免它的方法是使用可能首选的集合副本。

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

效果不佳,但表现可能不错。