在TreeSet中有一个名为contains的方法,如果元素在集合中,则返回true。我假设这个方法使用二分查找,并且不按升序遍历所有元素。我说的对吗?
我有一个TreeSet,它包含一个类的对象,该类使用两个String实例变量来区分它与同一类的其他对象。我希望能够创建一个方法,通过比较对象的两个实例变量(当然使用get方法)与其他两个字符串变量来搜索TreeSet,如果它们相等,则返回元素。如果实例变量小于,则在右子树中查找第一个元素,或者在左子树中查找更大的元素等。有办法做到这一点吗?
我知道我可以将对象存储在ArrayList中,然后使用二进制搜索来查找对象,但这不会像只搜索TreeSet那么快。
set.tailSet(obj).first();
与其使用TreeSet
,不如将对象存储在TreeMap<Foo, Foo>
或TreeMap<FooKey, Foo>
中(如果每次想要搜索时不能轻松创建新的实际Foo
)。Set
不是真正用于查找的。
对于FooKey
的例子,FooKey
将是一个简单的不可变类,它只包含两个String
和Comparable
。找到两个String
的Foo
的值将是treeMap.get(new FooKey(firstString, secondString))
的简单问题。这当然需要使用树遍历来查找值。
你应该在你的对象上实现Comparable,或者创建一个单独的Comparator类,在构造TreeSet时传入。这允许您插入自定义条目比较逻辑,并让TreeSet执行其优化的存储/搜索操作。
我想知道的一件事是为什么你想搜索到一个排序集?如果您希望能够按顺序迭代并快速查找,那么将对象存储在两个单独的数据结构中可能会受益。一个像你的SortedSet<Foo>
,然后还有一个类似ColinD提到的HashMap<FooKey,Foo>
。然后你得到常数时间的查找而不是在TreeMap上的log(n)您必须对两个结构都进行写操作,这将带来写损失,同时拥有两个数据结构也会带来内存资源损失,但是您已经完全优化了对数据的访问。
同样,如果内存资源受限,并且您的字符串是区分对象的真正原因,那么您可以在对象Foo
上实现hashcode()
和equals()
,然后将它们用作键和值(如HashMap<Foo,Foo>
)。需要注意的是,必须构造一个Foo
来调用getter。
您得到了关于使用comparable/comparator的答案,但我想我应该补充一下,您是对的,contains()进行二进制搜索,尽管您不需要知道这些细节