0

我有这样的结构:

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 ;
}

我尝试使用 a TreeSet < Foo >,它可以确保唯一性,但我无法从 TreeSet 中获取引用(只有它是否在集合中的布尔值),所以我无法将该引用传递给Bar. 我尝试将 aTreeMap < Foo , Integer >与 an 一起使用ArrayList < Foo >,这可以确保唯一性并允许我获取对对象的引用,但它会浪费大量时间和内存来维护 theArrayListIntegers。

我需要一种方式来说“如果Foo集合中还没有这个,添加它;否则,给我Foo已经在集合中的,而不是我创建的,以检查它在集合中的存在。”。

(我突然想到我可以做类似的事情TreeMap < Foo , Foo >,这会做我想做的事,但它似乎仍然是一种浪费,即使它远不及一个,所以我会继续这个问题,希望启示。)

(是的,我确实实现Comparable了在树中进行唯一性检查;那部分已经起作用了。)

4

4 回答 4

1

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

于 2012-11-10T20:44:28.253 回答
0

为了确保 a 的唯一性Set,您需要覆盖Fooequals()hashcode()两个具有相同 A、B、C 的实例.equals()

理想情况下,您放入 Set 中的任何内容都应该是不可变的(即您的三个整数应该是final. 从文档中:

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

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

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

于 2012-11-10T20:43:24.317 回答
0

Neil Coffey在 Java 中的 Sorted collection 中的一个解决方案给出了我需要的东西,它正在使用ArrayList < Foo >并且总是在Collections . binarySearch获取列表中已经存在的元素的索引,或者应该将元素插入到列表中的点。

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

于 2012-11-10T20:53:07.347 回答
0

显然 aTreeList基于 aTreeMap因此使这种方法变得多余,但我想我还是为了完整性而对其进行评论。

If a copy of a Foo object exists in the TreeList (e.g. as returned by contains) then you can retrieve the copy using the tailSet and first methods.

于 2012-11-11T00:35:43.210 回答