8

在 TreeSet 中有一个名为 contains 的方法,如果元素在集合中则返回 true。我假设此方法使用二进制搜索并且不会按升序遍历所有元素。我对吗?

我有一个 TreeSet,其中包含一个类的对象,该类使用两个 String 实例变量来将其与同一类的其他对象区分开来。我希望能够通过将对象的两个实例变量(当然使用 get 方法)与其他两个 String 变量进行比较来创建一个搜索 TreeSet 的方法,如果它们相等,则返回元素。如果实例变量小于转到右子树中的第一个元素,或者如果它们在左子树中进行更大的搜索等。有没有办法做到这一点?

我知道我可以将对象存储在 ArrayList 中并使用二进制搜索来查找对象,但这不会像搜索 TreeSet 一样快。

4

5 回答 5

15
set.tailSet(obj).first();

做你想做的事。

于 2011-08-30T14:34:08.433 回答
6

而不是使用 a TreeSet,您可以将对象存储在 a TreeMap<Foo, Foo>or中(如果您每次想要搜索时TreeMap<FooKey, Foo>都无法轻松创建新的实际值)。s 并不是真正用于查找的。FooSet

例如FooKeyFooKey将是一个简单的不可变类,只包含两个Strings 和 is Comparable。找到Foo两个Strings 的值将是一个简单的问题treeMap.get(new FooKey(firstString, secondString))。这当然会使用您要查找值的树遍历。

于 2011-04-05T22:00:03.040 回答
2

您应该在对象上实现 Comparable 或创建一个单独的 Comparator 类,在构造 TreeSet 时传入该类。这允许您插入自定义条目比较逻辑并让 TreeSet 进行优化的存储/搜索。

于 2011-04-05T21:27:12.130 回答
1

我想知道的一件事是您为什么要搜索排序集?如果您希望能够按顺序进行迭代并快速查找,您可能会受益于将对象存储在两个单独的数据结构中。一个像你的SortedSet<Foo>,然后也HashMap<FooKey,Foo>类似于 ColinD 提到的。然后,您将在 TreeMap 上获得恒定时间查找而不是 log(n)。您必须写入这两个结构的写入惩罚,以及拥有两个数据结构的内存资源惩罚,但是您已经完全优化了对数据的访问。

此外,如果内存资源受到限制,并且您的字符串确实是区分对象的原因,那么您可以在对象上实现hashcode()and然后将它们用作键和值(例如. 需要注意的是,您必须构造一个调用吸气剂。equals()FooHashMap<Foo,Foo>Foo

于 2011-04-06T01:48:33.957 回答
0

你得到了关于使用可比较/比较器的答案,但我想我会补充一点,你是对的, contains() 进行二进制搜索,尽管你不需要知道这些细节

于 2011-04-05T21:28:40.243 回答