1

why does this:

import java.util.*;

public class my {
    public static void main(String[] a) {
        TreeMap<TreeSet<Integer>, String> map = new TreeMap<TreeSet<Integer>, String>();
        TreeSet<Integer> set = new TreeSet<Integer>();
        map.put(set, "lol");
    }
}

work in Java 6? I mean that by specification putting TreeSet as a key of TreeMap without proper Comparator should lead to ClassCastException but it doesn't when running under Java 6. Was it a bug or there were some specification changes in Java 7 that made it work correctly (i.e. throw ClassCastException)?

mykola
  • 1,736
  • 5
  • 25
  • 37

1 Answers1

0

This is allowed in Java 7 too, not just Java 6.

The put method will throw a ClassCastException if the key is not of a type that implements Comparable. The class could have been designed to throw the exception in the constructor, but it doesn't because
(a) generic parameter types are subjected to type erasure, so the actual TreeMap sees everything as a plain Object and can't apply any checks in the constructor;

(b) this way allows you to use any object as a key, as long as it is of a subclass that implements Comparable, even if you don't initially declare the TreeMap to take a comparable key type.

Community
  • 1
  • 1
Klitos Kyriacou
  • 10,634
  • 2
  • 38
  • 70
  • No, this is not allowed in Java 7 (and 8). Just try to run it without any modifications in both environments: you'll get clean finish in Java 6 and ClassCastException in Java 7 and 8. `TreeSet` doesn't implement `Comparable` so `TreeMap`'s `put()` must throw a `ClassCastException` when you try to use `TreeSet` as a key (unless you created `TreeMap` with a comparator that takes `TreeSet`s as parameters). And it does so in Java 7 and 8, but doesn't in Java 6 (just try it). – mykola Nov 11 '15 at 07:33
  • 1
    I see what you mean. Sorry I misread your initial question and answered why it didn't give a compilation error instead. Java 6 allows you to put one non-comparable key into the map because it has nothing to compare it with and therefore no comparison is attempted. Try repeating the put() call; then you'll get the expected exception. Not sure why Java 7 changed the behaviour. – Klitos Kyriacou Nov 11 '15 at 09:29
  • 1
    Further to my above comment, the Javadoc for both 1.7 and 1.8 says the ClassCastException is thrown "if the specified key cannot be compared with the keys currently in the map". There are no keys currently in the map when you do your first put(), so it could be argued this is a bug in 1.7 and 1.8 as it's undocumented behaviour to throw in that specific case. – Klitos Kyriacou Nov 11 '15 at 10:06
  • 1
    That makes sense. Thanks! Concerning whether it's a bug in 1.7 and 1.8, actually you can read in javadoc for `SortedMap` the following words (which caused me to ask this question): `All keys inserted into a sorted map must implement the Comparable interface (or be accepted by the specified comparator)`. – mykola Nov 11 '15 at 11:10