The main problem is backward compatibility.
It was always possible to attempt to do the following, even if you "know" its not going to work
Map map = new HashMap(); map.put("hello", "world"); Object o = map.get(1); // null boolean b = map.contain(2); // false boolean b2 = map.remove(3); // false
As a result these methods still need to be able to take any type even though the generics implies that it will always return null or false.
Also its possible to construct a TreeMap where the keys don't need to be the same type, equals true, have the same hashCode or even compareTo() == 0
Map map = new TreeMap(new Comparator() { @Override public int compare(Object o1, Object o2) { return String.valueOf(o1).compareTo(o2.toString()); } }); map.put("1", "one"); map.put(2, "two"); map.put(3L, "three"); map.put('4', "four"); for(Object o: new Object[] { 1L, '2', 3, "4"}) { System.out.println(o.getClass().getSimpleName()+" "+o+" => "+map.get(o)); }
prints
Long 1 => one Character 2 => two Integer 3 => three String 4 => four