9

As described in the answer to Double in HashMap, Doubles shouldn't be used in HashMaps because they are difficult to compare for equality. I believe my case is different, but I thought I'd ask to make sure since I didn't see anything about this.

I'm going to have a series of double values associated with objects, and I want them to be sorted by the double values. Is TreeMap an appropriate solution? Would there be a better one? The double values are generated a bunch of math, so the likelihood of a duplicate value is extremely low.

EDIT: I should clarify: all I need is to have this list of objects sorted by the doubles they're associated with. The values of the doubles will be discarded and I'll never call map.get(key)

Community
  • 1
  • 1
MalcolmOcean
  • 2,807
  • 2
  • 29
  • 38
  • Sounds like you should be safe. You might add some fudge factor handling to prevent duplicates from happening just in case they do. – Wug Jul 26 '12 at 19:24

4 Answers4

14

Doubles shouldn't be used in HashMaps because they are difficult to compare for equality.

  • Will you ever try to get the values based on certain keys?

    • If yes, then the reasoning about "difficult to compare" applies and you should probably avoid such data structure (or always rely on tailMap / headMap / submap and fetch ranges of the map).

    • If no (i.e. you'll typically just do for (Double key : map.keySet()) ... or iterate over the entrySet) then I would say you're fine using Double as keys.

The double values are generated a bunch of math, so the likelihood of a duplicate value is extremely low.

  • Is it a bug if you actually do get a duplicate?

    • If yes then it's not the right data structure to use. You could for instance use a Multimap from Guava instead.

    • If no, (i.e. it doesn't matter which of the two values it maps to, because they can only differ by a small epsilon anyway) then you should be fine.

aioobe
  • 413,195
  • 112
  • 811
  • 826
2

The problem with doubles in tree maps is exactly the same as it is with doubles in hash map - comparing for equality. If you avoid calls of treeMap.get(myDouble) and stay with range queries instead (e.g. by using submap) you should be fine.

TreeMap<Double,String> tm = new TreeMap<Double,String>();
tm.put(1.203, "quick");
tm.put(1.231, "brown");
tm.put(1.233, "fox");
tm.put(1.213, "jumps");
tm.put(1.243, "over");
tm.put(1.2301, "the");
tm.put(1.2203, "lazy");
tm.put(1.2003, "dog");
for (Map.Entry<Double,String> e : tm.subMap(1.230, 1.232).entrySet()) {
    System.out.println(e);
}

This prints

1.2301=the
1.231=brown

See this snippet on ideone.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
1

If you only want to sort them, the best thing would be to create a wrapper object around the double and the object, implement the "comparable" interface on this wrapper, and use a simple collection to sort them

cporte
  • 2,191
  • 3
  • 20
  • 30
0

If you just want them sorted, there are better collections (for instance SortedSet). You can also use any list and use the utilities for sorting (I think they are in java.util.Collection).

Only use Maps and Tables when you want to directly access an item by its key.

SJuan76
  • 24,532
  • 6
  • 47
  • 87