8

According to this post:

http://coding-geek.com/how-does-a-hashmap-work-in-java/

java 8 hashmaps use a treenode instead of a linkedlist (as in java 7) as elements of the array.

TreeNodes have the special property of acting as a linkedlist if the number of elements are small, and acting as a red black tree if there is a large number of elements. (Since operations involving a red black tree are log(n)).

However, doesn't this require the key to be Comparable or some ordering of the keys to exist?

Is this enforced in the java 8 hashmap? Will it only use red black trees if the keys are Comparable (ordering of keys exist)?

Anik Rahman
  • 89
  • 1
  • 2
  • "However, doesn't this require the key to be Comparable or some ordering of the keys to exist?" no off course not – Shahzeb Jul 12 '15 at 23:43
  • 4
    _Tree bins (i.e., bins whose elements are all TreeNodes) are ordered primarily by hashCode, but in the case of ties, if two elements are of the same "class C implements Comparable", type then their compareTo method is used for ordering._ – Sotirios Delimanolis Jul 12 '15 at 23:47
  • 2
    Shahzeb, why not? @SotiriosDelimanolis, are you referring to the key as class C? what if it doesn't implement Comparable? i understand that the tree bins are ordered by their hashcode, i'm talking about the searching within the TreeNodes – Anik Rahman Jul 13 '15 at 00:28
  • Look at http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/classes/java/util/HashMap.java, around line 1877. – ajb Jul 13 '15 at 00:35
  • 1
    It looks like the algorithm uses `System.identityHashCode` to order the tree nodes. This is the hash code that's used by default if you don't supply your own `hashCode()`, and it's based on the reference (sort of like the "address"). All that matters is that _some_ consistent value be used, and `identityHashCode` is good enough. – ajb Jul 13 '15 at 00:41
  • Well, you can look at the other source around it. But it should provide a sufficient answer to your question, no? It shows how the algorithm orders the tree nodes when the objects are not `Comparable`, which is what you wanted to know, I think. – ajb Jul 13 '15 at 01:02
  • @ajb, according to that comment, it claims that "Tie-breaking utility for ordering insertions when hashCodes and non-comparable" However, from looking at the code, it uses System.identityhashcode for the two objects being compared and if they are equal, it returns -1. Isn't that inconsistent? As in, tieBreakOrder(a,b) returns -1 and tieBreakOrder(b,a) also returns -1. I don't really understand how this could help with finding the element. Thanks for the help so far though – Anik Rahman Jul 13 '15 at 01:06
  • @ajb, maybe i wasn't clear earlier, but the whole point is that the hashCode returns the same value for both objects which is why they are in the same treeNode. So using it again doesn't really seem to create an ordering – Anik Rahman Jul 13 '15 at 01:16
  • 3
    That isn't true. A hash table contains a limited number of buckets. To determine what bucket to put the object in, you typically compute `hashCode() % bucketCount`. If two objects are going into the same bucket, that means that `hashCode() % bucketCount` will be the same--but it does **not** mean that the `hashCode()` is the same. Therefore the `hashCode()` can still be used for comparison. And even if the `hashCode()` is the same, the `System.identityHashCode` will still most likely be different. – ajb Jul 13 '15 at 05:53
  • `identityHashCode` almost always returns different values for different objects, even if `.equals()` on those objects is `true`. – ajb Jul 13 '15 at 05:53
  • ah woops, yeah that makes sense. So, they pretty much make a random but consistent ordering of the key. thanks for the help! – Anik Rahman Jul 14 '15 at 01:52
  • check library code here - http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8u40-b25/java/util/HashMap.java#HashMap.TreeNode – roottraveller Aug 10 '17 at 18:11

1 Answers1

3

Will it only use red black trees if the keys are Comparable (ordering of keys exist)?

No, when HashMap is small all collisions are resolved as LinkedList. Look at the source:

/**
* Replaces all linked nodes in bin at index for given hash unless
* table is too small, in which case resizes instead.
*/

if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st, TREEIFY_THRESHOLD = 8
    treeifyBin(tab, hash);
    break;

treeifyBin() method will convert all collisions to treemap when threshold is reached.

However, doesn't this require the key to be Comparable or some ordering of the keys to exist?

You can put any keys to hashmap. According to the java doc, null is a valid key, and since null is not Comparable, keys do not have to be Comparable. If a key is not Comparable it will be put as LinkedList (through inner table if array already converted as tree).

dantiston
  • 5,161
  • 2
  • 26
  • 30
Eugene Kirin
  • 568
  • 3
  • 16