Monday, November 25, 2013

Java8 HashMap is not compatible with Java7... in a way...

One of the things that shine in Java (not the only one!) is its performance. And it constantly improving. One of the performance improving features of Java8 is an improvement to HashMap and many related standard hashing collections. Actually from the title of this JEP (JDK Enhancement Proposal) "Handle Frequent HashMap Collisions with Balanced Trees" it is clear that this enhancement uses Comparable and Comparator functionality. If class do not implement Comparable interface or not Comparable with each other classes are stored in the map - Comparator based on the hashcode is used. But if class implements Comparable - this implementation is used.

So based on all this here is the very simple question. What does this code output on the JVM version 7 and on the JVM version 8?

package com.sopovs.moradanen;

import java.util.HashSet;
import java.util.Set;

public class HashMapTest {
 public static void main(String[] args) {
  Set<Foo> hashSet = new HashSet<>();
  for (int i = 0; i < 1000; i++) {
   hashSet.add(new Foo(i));
  for (Foo foo : hashSet) {
   if (!hashSet.contains(foo)) {

 public static class Foo implements Comparable<Foo> {
  private final int id;

  public Foo(int id) { = id;

  public int compareTo(Foo o) {
   // This is badly broken compareTo method
   return 1;

  public int hashCode() {
   // This is valid hashcode but that will leave only 4 buskets
   return id % 4;

  public boolean equals(Object obj) {
   // This is default equals() method generated by Eclipse
   if (this == obj)
    return true;
   if (obj == null)
    return false;
   if (getClass() != obj.getClass())
    return false;
   Foo other = (Foo) obj;
   if (id !=
    return false;
   return true;



On JVM version 7 this code outputs nothing. But on the JVM version 8 it outputs "Bingo!". Actually the very first object tested (with id=0) can not be found in the Set based on the broken Comparable implementation.

No comments:

Post a Comment