支持唯一性自定义标准的现有Java集合?

时间:2013-01-10 17:06:00

标签: java collections unique guava apache-commons-collection

我想利用一个独特的java集合,它可以接受一个策略来确定成员对象在集合初始化时是否“相等”。

我需要这样做的原因是因为我需要添加到此集合的类的equals方法已经实现以满足其他(更合适的)功能。在特定情况下,此集合实例中唯一性的标准只需要检查类的一个变量,而不是检查在equals方法中检查的多个变量。我宁愿避免装饰这些物品,因为我是从不同的库中收集它们的,因此装饰它会很费劲(而且它可能使我的代码变得混乱)。

我意识到这不会是一个Set,因为它会破坏Java contract for Set,但我觉得好像以前遇到过这个问题。我认为GuavaApache Collections会提供一些东西,但似乎没有运气。 是否有人知道任何提供此类功能的库?我应该完全享受不同的解决方案吗?

3 个答案:

答案 0 :(得分:3)

您可以使用自定义比较器和TreeSet或TreeMap吗?或者使用Key符合您标准的地图? HashSet只是HashMap的包装器,因此使用地图应该要贵得多。

答案 1 :(得分:1)

这不太实际。例如,考虑一下您认为等效的类C的两个实例。

现在你做:

set.add(c1);
set.remove(c2);

之后该套装是否应为空?那么.retainAll().removeAll()呢?

这里最好的选择是创建自己的类,它包装了类C,删除了需要委派的任何内容,并且这个包装类实现.hashCode().equals()(也可能是Comparable)。通过这样的课程,您可以继续使用经典集和地图。

答案 2 :(得分:1)

Guava具有等效性,可让您定义两个对象是否等效。

它还有Equivalence.Wrapper,它包装任意对象并将equals()和hashCode()委托给等价的实现,而不是它们自己的。

所以你可以这样做:

public class MySet<T> implements Set<T> {

    private final Equivalence<T> equivalence;

    private final Set<Wrapper<T>> delegate = new HashSet<Wrapper<T>>();

    public MySet(Equivalence<T> equivalence) {
        this.equivalence = equivalence;
    }

    public boolean add(T t) {
        return delegate.add(equivalence.wrap(t));
    }

    // other Set methods

}