用于确保唯一性的Java集合,同时提供参考

时间:2012-11-10 20:35:45

标签: java collections reference unique-key

我有这样的结构:

public class Foo
{
    public int A ;
    public int B ;
    public int C ;
}

我需要逐个将这些添加到集合中,这样我最终只会得到一个副本,其中A,B和C都相等。我还需要引用另一个类的对象,如下所示:

public class Bar
{
    public Foo A ;
    public Foo B ;
    public Foo C ;
}

我尝试使用TreeSet < Foo >,这有助于确保唯一性,但我无法从TreeSet中获取引用(只是它是否是/在集合中的布尔值),所以我可以将该引用传递给Bar。我尝试使用TreeMap < Foo , Integer >ArrayList < Foo >,这有助于确保唯一性并允许我获取对象的引用,但它浪费了大量的时间和内存来维护{{ 1}}和ArrayList s。

我需要一种方式来说“如果此Integer尚未包含在集合中,请添加它;否则,请在集合中提供Foo而不是我创建的Foo来检查它存在于收藏中。“。

(我突然意识到我可以做TreeMap < Foo , Foo >这样的事情,这会做我想要的事情,但它看起来仍然是浪费,即使它没有那么多,所以我'继续这个问题,希望启蒙。)

(是的,我确实实现了Comparable来对树进行唯一性检查;这部分已经有效了。)

4 个答案:

答案 0 :(得分:1)

我会使用例如一个TreeMap<Foo, Foo>个对象。当您在地图中putFoo时,请将其指定为键和值。这样,您就可以使用get返回集合中已有的Foo。请注意,您必须自己处理Foo已经在地图中的情况。

答案 1 :(得分:0)

为确保Set的唯一性,您需要覆盖equals()hashcode(),以便具有相同A,B,C的两个Foo实例为{{1} }。

理想情况下,您放入套装中的任何内容都应该是不可变的(即您的三个整数应为.equals()。来自documentation

  

如果将可变对象用作set,则必须非常小心   元素。如果a的值,则不指定集合的​​行为   对象以影响等于比较的方式改变   对象是集合中的元素。

不幸的是,final没有提供任何允许您获取实际实例的方法 - 您需要一个Set或其他已经尝试过的集合。

更新另一种方法是根据JDK source code创建自己的TreeSet修改版本,添加一个方法来获取所需的实例(扩展标准TreeSet不会做你需要的,因为相关的字段是Map,除非你使用反射来访问它们。)

答案 2 :(得分:0)

Neil Coffey在Sorted collection in Java中的解决方案提供了我需要的内容,即使用ArrayList < Foo >并始终使用Collections . binarySearch来获取列表中已有元素的索引,或者应将元素插入列表中的点。

它在O(log n)时间像树一样维护一个不断排序的列表,但允许同时检索现有实例。不幸的是,它有O(n)插入时间,但在这种情况下,这不是世界末日,尽管它仍然不是最理想的。

答案 3 :(得分:0)

显然TreeList基于TreeMap因此使这种做法变得多余,但我认为我只是为了完整性而对其进行评论。

如果Foo中存在TreeList对象的副本(例如,由contains返回),则可以使用tailSet和{{1}检索副本方法。