Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/341.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
支持自定义唯一性条件的现有Java集合?_Java_Collections_Unique_Guava_Apache Commons Collection - Fatal编程技术网

支持自定义唯一性条件的现有Java集合?

支持自定义唯一性条件的现有Java集合?,java,collections,unique,guava,apache-commons-collection,Java,Collections,Unique,Guava,Apache Commons Collection,我想利用一个独特的java集合,它可以接受一种策略来确定成员对象在集合初始化时是否“相等” 我之所以需要这样做,是因为我需要添加到此集合的类的equals方法已经实现,以满足其他(更合适的)功能。在特定情况下,此集合实例中的唯一性条件只需要检查类的一个变量,而不是在equals方法中检查的多个变量。我更愿意避免装饰对象,因为我从不同的库中收集它们,并且循环装饰的成本会很高(这可能会弄脏我的代码) 我意识到这不会是一个集合,因为它会破坏这个集合,但我只是觉得这个问题以前一定遇到过。我想或者会提供一

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

我之所以需要这样做,是因为我需要添加到此集合的类的equals方法已经实现,以满足其他(更合适的)功能。在特定情况下,此集合实例中的唯一性条件只需要检查类的一个变量,而不是在equals方法中检查的多个变量。我更愿意避免装饰对象,因为我从不同的库中收集它们,并且循环装饰的成本会很高(这可能会弄脏我的代码)


我意识到这不会是一个集合,因为它会破坏这个集合,但我只是觉得这个问题以前一定遇到过。我想或者会提供一些东西,但似乎没有运气有人知道提供这种功能的可用库吗?我是否应该完全使用不同的解决方案?

您可以使用自定义比较器和树集或树映射吗?或者在关键点有您的标准的地方使用地图?HashSet只是HashMap的包装器,因此使用map应该要昂贵得多。

这并不实际。例如,考虑一个类“代码>代码< >代码>,您认为它是等价的。

现在你可以:

set.add(c1);
set.remove(c2);
在那之后,集合应该是空的吗?那么
.retainal()
.removeAll()


在这里,最好的办法是创建自己的类,该类封装在类
C
上,删除需要委派的任何内容,并让这个封装类实现
.hashCode()
.equals()
(也可能是自身的
可比
)。有了这样一个类,您可以继续使用经典的集合和映射。

Guava有一个等价性,它允许您定义两个对象是否等价

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

所以你可以这样做:

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

}
公共类MySet实现Set{
私有最终等价;
私有最终集委托=新HashSet();
公共MySet(等价){
这个。等价=等价;
}
公共布尔加法(T){
返回delegate.add(equality.wrap(t));
}
//其他集合方法
}

为什么不使用包装器类和经典的
集呢?或者这不是一个选项?Guava@fge是成员对象的包装器类?我有疑问地解释了。(尽管如此,我最终可能会决定这是一条路)@smp7d我在最初的问题中没有看到任何东西促使我认为这是不可能的。例如,只有当苹果和橘子的颜色相同时,才比较它们是否相等。在我看来,你想要的是一个可以比较颜色的类——这并不能阻止潜在的苹果和橘子的存在。@Louis-hmm——这就是我刚才给出的答案。我认为,在这种情况下——实施将局限于问题的范围——没有太多的空间造成广泛的混乱。好的文档也会有帮助!是的,我可以,谢谢你的实施。但是,还没有库提供这样的实现吗?我可以使用自定义比较器。我并没有真的这么认为,因为我总是认为比较器是一种排序手段,我不需要。看这些文件,我发现TreeSet违反了既定合同。我希望避免使用映射,因为我在概念上不需要键值对。如果我决定实现自己的集合,我可能会在内部使用映射。您需要对对象的独特性有一个自定义的概念。这是关键。您还希望原封不动地存储原始对象。这就是价值。有一种常见的租赁方式,即使用具有复杂规则的集合或列表,而不是使用简单的映射。