Map.get(Object o) vs Map.get(K k) ?

Hi All,

I hace a question about Map (or may be TreeMap as it comes into my notice whle using TreeMap). I posted it on Collections related forum and got referred here

[url]http://forum.java.sun.com/thread.jspa?threadID=684755[/url]

I was wondering why some methods of Map<k,V> specify Object as type for keys used and not the given type K. problem is that following code will throw a ClassCastException

String key="146564";

TreeMap<String, String> map =new TreeMap<String, String>();

map.put(key,key);/*If you uncomment this line you will get Exception*/

map.containsValue(new Long(key));/*can compile */

map.containsKey(new Long(146564));/*can compile */

String v = map.get("1");

//map.put(new Long(1), "");/*Can't compile*/

Exception in thread"main" java.lang.ClassCastException: java.lang.String

at java.lang.Long.compareTo(Long.java:34)

at java.util.TreeMap.compare(TreeMap.java:1093)

at java.util.TreeMap.getEntry(TreeMap.java:347)

at java.util.TreeMap.containsKey(TreeMap.java:204)

atTestClass.main(TestClass.java:27)

It is suggested that since I am passing a Long to map.containsKey(), where as Map was declared as Map<String,String> I should expect to get such nasty runtime exceptions. My thinking is 'generics' are specifically designed to avoid such situations.

Can any one let me know why 'generics' are implemented such a way that is not orthognal accross various interfaces? i.e. why is it that I need to remember what instance of a Map was created with key/value pairs of Type A/B and which one with C/D, however if I am using Collection, it will be type checked at comple time? I would either expect to remember it always or to expet it to get type checked at compile time always.

[2143 byte] By [haroonzca] at [2007-10-2 5:46:43]
# 1

This was heavily debated during the evaluation phase. The reason that get(Object) was favoured is basically backwards compatibility: the contract of Map talks only in terms of the equals(Object) method, and for many key types K there can be objects which are not of type K but are equal to a key of type K.

My personal view is that if get(K) introduces problems then you've used the wrong type for K, and your entire design is probably shoddy if there isn't a suitable interface type to use. Moreover, having get(K) would save me probably 5+ hours per year chasing bugs due to calling get (or Collection.contains, which is really the same issue) with the wrong object.

If you really want to compile against get(K), it's fairly straightforward to make a jar with a "fixed" java.util package and use this with javac -bootclasspath. I believe that as long as you don't distribute said jar (and you only need it for compilation, so that's fine) the licence permits this, but IANAL and this is not legal advice.

YAT_Archivista at 2007-7-16 1:56:28 > top of Java-index,Core,Core APIs...
# 2

If get() and containsKey() were parameterized with K, they would become useless for any map reference where K is a wildcard capture.

This would be incorrect because get() and contains() do not modify the Map.

I give an example in the other post for this question

http://forum.java.sun.com/thread.jspa?threadID=682252&start=10&tstart=0

dubwaia at 2007-7-16 1:56:28 > top of Java-index,Core,Core APIs...
# 3
Sorry, wrong thread: http://forum.java.sun.com/thread.jspa?threadID=684755&start=10&tstart=0
dubwaia at 2007-7-16 1:56:28 > top of Java-index,Core,Core APIs...