Java Forum / General / March 2008
Generics on map.
Ravi - 14 Mar 2008 15:52 GMT Hi,
The following code compiles in eclipse 3.3.1. Shouldn't the compiler throw an exception as the key doesn't pass instanceof check?
class Test { public static void main(String args[]) { Map<String,String> testmap = new HashMap<String, String>(); testmap.get(new StringBuffer()); } }
Regards, Ravi.
Eric Sosman - 14 Mar 2008 16:04 GMT > Hi, > [quoted text clipped - 7 lines] > } > } No. The get() method of the Map interface takes any Object reference as its argument, not a parameterized type. Since testmap will only accept entries that have Strings as keys, querying for a key of any other type will return null. It's legal to ask, even when the answer will be "No."
 Signature Eric.Sosman@sun.com
Mark Space - 14 Mar 2008 16:52 GMT >> Hi, >> [quoted text clipped - 13 lines] > keys, querying for a key of any other type will return null. > It's legal to ask, even when the answer will be "No." Good one. Reading the OP's example, I assumed that get() took a parameterized type as well, and I couldn't figure out why an exception wouldn't be throw.
"When all else fails, read the documentation."
Eric Sosman - 14 Mar 2008 18:35 GMT >>> Hi, >>> [quoted text clipped - 19 lines] > > "When all else fails, read the documentation." Or as in my case, "Learn from your blunders." I'd tried to write a Map with case-insensitive Strings as keys:
Map<String,Thing> map = new HashMap<String,Thing>() { public Thing put(String key, Thing value) { return super.put(key.toLowerCase(), value); } public Thing get(String key) { return super.get(key.toLowerCase()); } }
... and then I got splinters in my fingers from scratching my head over why it didn't work. After the penny dropped, I changed the second method to
public Thing get(Object key) { if (key instanceof String) key = ((String)key).toLowerCase(); return super.get(key); }
... and things worked a whole lot better. (The `if' isn't necessary, but given my state of confusion at the time it's perhaps forgivable.) Having been through this, I am now "Once burned, twice shy."
 Signature Eric.Sosman@sun.com
Ravi - 14 Mar 2008 18:29 GMT Its quite obvious that runtime return value from the get() is null. But the very idea of generics is to avoid these runtime mistakes(??) and push them to design (compile) time. Wont it make sense to throw up at least a warning that the key is of incompatible type ?? btw, put() does care about the type check for Key and Value .
Regards, Ravi.
> > Hi, > [quoted text clipped - 16 lines] > -- > Eric.Sos...@sun.com Eric Sosman - 14 Mar 2008 20:14 GMT Putting the response before the stimulus. What is "top-posting?" Please don't top-post.
> Its quite obvious that runtime return value from the get() is null. > But the very idea of generics is to avoid these runtime mistakes(??) > and push them to design (compile) time. Wont it make sense to throw up > at least a warning that the key is of incompatible type ?? btw, put() > does care about the type check for Key and Value . Of course put() is parameterized, because it needs to ensure that you don't insert a String key into a Map that expects only Integers. But get() doesn't need to be so picky: If you search that Map for an entry with the key "Mongo", get() reports that no such entry exists. Nothing odd about that, is there?
Consider this pre-generics situation: I've got a Map
Map squares = new HashMap();
... and I populate it with some data
for (int n = 0; n < 10; ++n) squares.put(new Integer(n), new Integer(n*n));
Now I make some queries:
Integer value1 = (Integer)squares.get(new Integer(5)); Integer value2 = (Integer)squares.get(new Integer(42)); Integer value3 = (Integer)squares.get("Mongo");
The first query returns a reference to an Integer with the value 25. The second returns null because the Map has no entry with the key 42. And the third returns null because the Map has no entry with the key "Mongo". What difference is there between the second and third outcomes? None; they both declare "key not found," and there's an end on't.
Remember, too, that generics are a compile-time hint and not a run-time enforcement. By ignoring enough warnings you can in fact put a String key and a BigDecimal value into a Map<Integer,Integer> -- and if you were to do so, and then turn around and search for the String key, shouldn't get() find the BigDecimal for you?
I imagine that the design decisions might have been made differently if generics had been part of Java from the start and if they were backed up by run-time enforcement. But for whatever reason that's not the way things have turned out.
 Signature Eric.Sosman@sun.com
thufir - 29 Mar 2008 00:46 GMT > class Test { > public static void main(String args[]) { > Map<String,String> testmap = new HashMap<String, String>(); > testmap.get(new StringBuffer()); > } > } What's a good book to explain this method? Not a beginner's book. Is this "map" similar to the "map" in ruby?
thanks,
Thufir
Mark Space - 29 Mar 2008 03:52 GMT > What's a good book to explain this method? Not a beginner's book. Is > this "map" similar to the "map" in ruby? Well, _Learning Java_ by O'Reilly is a good book that goes into a fair amount of detail too. It is a beginner's book, but Learning Java has a huge amount of info that it works well as a reference. Learning Java has one of the best explanations of generics I've ever seen.
It definitely gets a thumbs up from me.
However, there is also the online Java tutorial from Sun, and don't ignore Google. Search for "java classname se 6" will take you directly to the Javadocs in most cases.
<http://java.sun.com/docs/books/tutorial/collections/index.html>
<http://java.sun.com/javase/6/docs/api/java/util/Map.html>
I don't know enough Ruby to tell you if Java maps and Ruby maps are similar.
Lew - 29 Mar 2008 05:21 GMT thufir wrote:
>> What's a good book to explain this method? Not a beginner's book. Is >> this "map" similar to the "map" in ruby?
> Well, _Learning Java_ by O'Reilly is a good book ... > It definitely gets a thumbs up from me. [quoted text clipped - 3 lines] > > <http://java.sun.com/javase/6/docs/api/java/util/Map.html> Bird's-eye view of the Java Map, from that link:
> public interface Map<K,V> > > An object that maps keys to values. A map cannot contain duplicate keys; > each key can map to at most one value. Some scripting languages, including Java EE's own Expression Language (EL), depict maps as associative arrays: ${ranches ["BelongaMick"]}.
The "<K, V>" in the interface are the key and value types, respectively. Any two object types can be associated in a Map.
Map <String, Entity> namedEntities = new HashMap <String, Entity> (); namedEntities.put( "Mjolnir", new MagicHammerEntity( "Mjolnir", "Thor" ) );
 Signature Lew
Roedy Green - 29 Mar 2008 19:34 GMT >What's a good book to explain this method? Not a beginner's book. Is >this "map" similar to the "map" in ruby? Map in just the interface for the commonality of TreeMap and HashMap.
See http://mindprod.com/jgloss/hashmap.html http://mindprod.com/jgloss/treemap.html http://mindprod.com/jgloss/hashtable.html http://mindprod.com/jgloss/hashcode.html
to understand deeper than that, have a look at the source code in src.zip. It is simpler than you might expect.
 Signature
Roedy Green Canadian Mind Products The Java Glossary http://mindprod.com
Roedy Green - 29 Mar 2008 19:41 GMT >What's a good book to explain this method? Not a beginner's book. Is >this "map" similar to the "map" in ruby? see http://mindprod.com/jgloss/gettingstarted.html
 Signature Roedy Green Canadian Mind Products The Java Glossary http://mindprod.com
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|