我有这样的结构:
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
来对树进行唯一性检查;这部分已经有效了。)
答案 0 :(得分:1)
我会使用例如一个TreeMap<Foo, Foo>
个对象。当您在地图中put
新Foo
时,请将其指定为键和值。这样,您就可以使用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}检索副本方法。