views:

287

answers:

5

I want to maintain a collection of objects of type Odp. Odp implements Comparable. I need to be able to refer to an object in the collection with its integer name. This integer must correspond to its sort order (not insertion order). Each integer only applies to one Odp, and vice versa.

I have a function compareOdp(Odp o1, Odp o2) that returns a numeric value representing the similarity of the two arguments. I the Odp collection to be set up in such a way that it's easy to ask questions like "What is the closest Odp to foo in the collection?" or "Of these several collections of Odp objects, how close are they to each other?"

What is the best way to do this? TreeMap? HashBiMap?

Related Question:

Let's say I have the following set of objects: o1, o2, o3 contained in collection col. Their sort order is

o2
o3
o1

I want to ask col: "what is the nth object in the list?" From what I can see, SortedSet and TreeMap don't have a way to do this. I guess I could iterate over, but it feels like there should be an easier way.

+1  A: 

Any implementation of SortedSet will keep the items in order, according to the Comparable interface. TreeSet is an implementation of SortedSet.

yes, but what about mapping the objects to integer names?
Rosarch
+1  A: 

TreeMap is a build-in solution and as far as I've used it. I think it is pretty good.

NawaMan
A: 

I would use the lowly LinkedList. Then use Collections.binarySearch for searching the list. The binary search function will return you the insertion point in your linked list. To find which one is closest, simply use your compareOdp function with the item below and the item above in the linkedlist.

brianegge
`ArrayList` is probably better than `LinkedList` for this, because `Collections.binarySearch()` needs to use a list with random access. So it can just use an `ArrayList` but with `LinkedList` it needs to copy into a temporary array.
newacct
You are correct. I was thinking about the LinkedList for faster insertion. However, the LinkedList would fail for quick binary searches. Alternatively, one could use a TreeSet, and then convert to ArrayList when needing to search.
brianegge
`TreeSet` provides guaranteed O(lg n) search time, just like binary search.
dcrosta
Sorry, fingers faster than brain. `TreeSet` provides guaranteed O(lg n) search time, and therefore there's no need to convert to anything to search it (unless you needed O(1), in which case you would use `new HashSet(myTreeSet)`. `HashSet` will not maintain iteration order.
dcrosta
+3  A: 

If you are using Java 6, the NavigableSet API (implemented by TreeSet) can help.

public static Odp nearest(Odp o, NavigableSet<? extends Odp> set) {
  Odp f = set.floor(o), c = set.ceiling(o);
  if (f == null)
    return c;
  if (c == null)
    return f;
  int df = compareOdp(o, f), dc = compareOdp(c, o);
  return (df <= dc) ? f : c;
}
erickson
A: 
// What is the nth object in the list...

Object oneObject = TreeMap.get(nthKey);

Okay, so far / so good. If you do not care how they are contained in the Data Structure, you can use a ( might have to look it up but it would be called a ) HashMap == in which case there would be a key that you supply, which can easily be:

Object placement= HashMap.put(new Integer(++index),new Object(data));// see docs for exact

if placement is null, the map did not contain the object previously, used in conjuction with containsKey() exact management of data set is obtainable

Which will work find for get and put by ordered key, it's only that if you do toArray() you get a bizarre ordering that is only comprehensible to whomever wrote the HashMap implementation.

Nicholas Jordan