开发者

Returning an element from a TreeSet using binary search

In TreeSet there is a method called contains that returns true if an element is in the set. I assume that this method uses binary search and does not 开发者_如何学Citerate through all the elements in ascending order. Am I right?

I have a TreeSet that contains objects of a class that uses two String instance variables to distinguish it from other objects of the same class. I want to be able to create a method that searches the TreeSet by comparing the objects two instance variables (using get methods of course) with two other String variables and if they are equal, return the element. If the instance variables are less than go to the first element in the right subtree or if they are greater search in the left subtree etc. Is there a way to do this?

I know I could just store the objects in an ArrayList and use binary search to find the object, but this wouldn't be as fast as just searching the TreeSet.


set.tailSet(obj).first();

does what you want.


Rather than using a TreeSet, you could store your objects in a TreeMap<Foo, Foo> or TreeMap<FooKey, Foo> (if you can't easily create a new actual Foo each time you want to search). Sets are not really intended for lookup.

For the FooKey example, FooKey would be a simple immutable class that just contains the two Strings and is Comparable. Finding the value of Foo for two Strings would then be a simple matter of treeMap.get(new FooKey(firstString, secondString)). This does of course use the tree traversal you want to find the value.


You should either implement Comparable on your object or create a separate Comparator class that you pass in at the time TreeSet is constructed. This allows you to interject your custom entry comparison logic and let the TreeSet do its optimized store/search thing.


One thing I was wondering is why you want to search into a sorted set? If you want to be able to iterate in order as well as lookup quickly you may benefit from storing your objects in two separate data structures. One like your SortedSet<Foo> and then also a HashMap<FooKey,Foo> similar to what ColinD mentioned. Then you get constant time lookups instead of log(n) on the TreeMap. You have a write penalty of having to write to both structures, and a memory resource penalty of having the two data structures, but you have fully optimized your access to the data.

Also if memory resources are constrained, and your strings are really what differentiate the objects, then you can just implement hashcode() and equals() on your object Foo and then just use them as both the key and value (like HashMap<Foo,Foo>. The caveat there is that you have to construct a Foo to call the getter.


You got the answer about using comparable/comparator, but I thought I would add that you are right that contains() does a binary search, though you shouldn't need to know those details

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜