我想利用一个独特的java集合,它可以接受一个策略来确定成员对象在集合初始化时是否“相等”。
我需要这样做的原因是因为我需要添加到此集合的类的equals方法已经实现以满足其他(更合适的)功能。在特定情况下,此集合实例中唯一性的标准只需要检查类的一个变量,而不是检查在equals方法中检查的多个变量。我宁愿避免装饰这些物品,因为我是从不同的库中收集它们的,因此装饰它会很费劲(而且它可能使我的代码变得混乱)。
我意识到这不会是一个Set,因为它会破坏Java contract for Set,但我觉得好像以前遇到过这个问题。我认为Guava或Apache Collections会提供一些东西,但似乎没有运气。 是否有人知道任何提供此类功能的库?我应该完全享受不同的解决方案吗?
答案 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
}