Go Back   Velocity Reviews > Newsgroups > Java
User Name
Password
Register FAQ Members List Calendar Search Today's Posts Mark Forums Read

Reply

Java - HashMap get/put

 
Thread Tools Search this Thread
Old 10-28-2009, 09:59 PM   #1
Default HashMap get/put


If I have the following:

HashMap<MyKey,MyValue> map = new HashMap<MyKey,MyValue>();
MyKey myKey = new MyKey();

Then I can put in a value by:

map.put(myKey, new MyValue() );

The compiler enforces the use of these two types.

However to do a get I can do the following and the compiler does not
complain:

map.get(myKey); // this is right
map.get(myKey.toString()); // this is wrong yet legal
map.get(new Long(20)); // this is wrong yet legal

All of these are legal according to the compiler. Why is it that the
compiler does not enforce type checking on the get()?

Or rather, why does the spec not say get(K key) instead of get(Object
o)

http://java.sun.com/javase/6/docs/ap...va.lang.Object)

--
Wojtek




Wojtek
  Reply With Quote
Old 10-28-2009, 10:11 PM   #2
Stefan Ram
 
Posts: n/a
Default Re: HashMap get/put
Wojtek <> writes:
>All of these are legal according to the compiler. Why is it that the
>compiler does not enforce type checking on the get()?


Setting with a wrong type can result in a Map that breaks
its contract. Therefore, it is forbidden. Getting with a
wrong type cannot do such harm, so, it is not forbidden.
After all, you can meaningfully and correctly detect at run
time that for a wrong key, there is no value in the map.



Stefan Ram
  Reply With Quote
Old 10-28-2009, 10:21 PM   #3
Ken
 
Posts: n/a
Default Re: HashMap get/put
On Oct 28, 4:11*pm, r...@zedat.fu-berlin.de (Stefan Ram) wrote:
> Wojtek <nowh...@a.com> writes:
> >All of these are legal according to the compiler. Why is it that the
> >compiler does not enforce type checking on the get()?

>
> * Setting with a wrong type can result in a Map that breaks
> * its contract. Therefore, it is forbidden. Getting with a
> * wrong type cannot do such harm, so, it is not forbidden.
> * After all, you can meaningfully and correctly detect at run
> * time that for a wrong key, there is no value in the map.


I don't understand. If the type is not the same as the type used in
the map there is no chance of success. Clearly this is an error. I'm
of the mind of the OP.


Ken
  Reply With Quote
Old 10-28-2009, 10:45 PM   #4
Stefan Ram
 
Posts: n/a
Default Re: HashMap get/put
Ken <> writes:
>I don't understand. If the type is not the same as the type used in
>the map there is no chance of success.


Look at the following example:

public class Main
{ public static void main( final java.lang.String[] args )
{
final java.util.Map<java.lang.String,java.lang.String> value0
= new java.util.HashMap<java.lang.String,java.lang.Strin g>();

final java.util.Map<java.lang.Object,java.lang.Integer> value1
= new java.util.HashMap<java.lang.Object,java.lang.Integ er>();

final java.util.Map
<java.util.Map<java.lang.String,java.lang.String>, java.lang.String> map
= new java.util.HashMap
<java.util.Map<java.lang.String,java.lang.String>, java.lang.String>();

map.put( value0, "alpha" );

java.lang.System.out.println( map.get( value1 )); }}

alpha

»value1« has not the type used in the map, yet the »get« succeeds.



Stefan Ram
  Reply With Quote
Old 10-28-2009, 10:49 PM   #5
Wojtek
 
Posts: n/a
Default Re: HashMap get/put
Stefan Ram wrote :
> Wojtek <> writes:
>> All of these are legal according to the compiler. Why is it that the
>> compiler does not enforce type checking on the get()?

>
> Setting with a wrong type can result in a Map that breaks
> its contract. Therefore, it is forbidden. Getting with a
> wrong type cannot do such harm, so, it is not forbidden.
> After all, you can meaningfully and correctly detect at run
> time that for a wrong key, there is no value in the map.


No it is not an error. Just will never retrieve ANY value if you use
the wrong type (see below).

This came about because I changed the key for a HashMap to one that is
more specific (such as String to MyKey). All the "put" statements were
caught. However ALL the get statements were not. I had to manually go
through the code to locate each occurrence and change it.

And of course I missed some and the code broke during runtime. I had
assumed that generics would solve this type of issue.


Caveat: Yes it is possible to get the same hashcode with two different
types, however it would be highly unlikely.

--
Wojtek




Wojtek
  Reply With Quote
Old 10-28-2009, 11:05 PM   #6
Stefan Ram
 
Posts: n/a
Default Re: HashMap get/put
(Stefan Ram) writes:
>Look at the following example: (...)
>final java.util.Map<java.lang.String,java.lang.String> value0
>= new java.util.HashMap<java.lang.String,java.lang.Strin g>(); (...)
>»value1« has not the type used in the map, yet the »get« succeeds.


Above, both types were the same after type erasure and were
types of empty containers.

Here is a program with types that differ even after type
erasure and non-empty containers.

public class Main
{ public static void main( final java.lang.String[] args )
{
final java.util.ArrayList< java.lang.String >list0
= new java.util.ArrayList< java.lang.String >();
list0.add( "text" );

final java.util.LinkedList< java.lang.String >list1
= new java.util.LinkedList< java.lang.String >();
list1.add( "text" );

final java.util.Map
< java.util.ArrayList< java.lang.String >, java.lang.String >map
= new java.util.HashMap
< java.util.ArrayList< java.lang.String >, java.lang.String >();

map.put( list0, "value" );

java.lang.System.out.println( map.get( list1 )); }}

value



Stefan Ram
  Reply With Quote
Old 10-28-2009, 11:13 PM   #7
Joshua Cranmer
 
Posts: n/a
Default Re: HashMap get/put
On 10/28/2009 05:59 PM, Wojtek wrote:
> Or rather, why does the spec not say get(K key) instead of get(Object o)


I can think of some cases where it might be desirable to use gets with
other objects; this requires, of course, that the objects be designed
with this use case in mind, namely that the hash codes and equals work
correctly.

One example that came up in some code was where I had a parameter
accessible in two different fashions, and the conversion between the two
forms became a hotspot in the code.

--
Beware of bugs in the above code; I have only proved it correct, not
tried it. -- Donald E. Knuth


Joshua Cranmer
  Reply With Quote
Old 10-29-2009, 01:00 AM   #8
Lew
 
Posts: n/a
Default Re: HashMap get/put
Stefan Ram wrote :
>> Setting with a wrong type can result in a Map that breaks
>> its contract. Therefore, it is forbidden. Getting with a
>> wrong type cannot do such harm, so, it is not forbidden.
>> After all, you can meaningfully and correctly detect at run
>> time that for a wrong key, there is no value in the map.


Wojtek wrote:
> No it is not an error. Just will never retrieve ANY value if you use the
> wrong type (see below).
>
> This came about because I changed the key for a HashMap to one that is
> more specific (such as String to MyKey). All the "put" statements were
> caught. However ALL the get statements were not. I had to manually go
> through the code to locate each occurrence and change it.
>
> And of course I missed some and the code broke during runtime. I had
> assumed that generics would solve this type of issue.


Generics only handle what is declared generically. 'Map#get()' is not so
declared. Assumptions based on falsehood will yield false conclusions.

<http://java.sun.com/javase/6/docs/api/java/util/Map.html#get(java.lang.Object)>

> Caveat: Yes it is possible to get the same hashcode with two different
> types, however it would be highly unlikely.


And this is relevant how? 'Map' retrieval is defined in terms of 'equals()',
not 'hashCode()'.

<http://java.sun.com/javase/6/docs/api/java/util/Map.html#get(java.lang.Object)>
> ... formally, if this map contains a mapping from a key k to a value v
> such that (key==null ? k==null : key.equals(k)),
> then this method returns v; otherwise it returns null.
> (There can be at most one such mapping.)


FWIW, if 'Map#get()' had been redefined generically, it would have broken
existing code without providing an improvement. Code that would have not
gotten a value still does not get a value without introducing a new error.
Maybe they erred in this, but they were trying to maintain backward compatibility.

It's a shame that the compiler didn't find your refactoring mistake for you,
but it was your mistake, not Java's.

--
Lew


Lew
  Reply With Quote
Old 10-29-2009, 04:25 AM   #9
Kevin McMurtrie
 
Posts: n/a
Default Re: HashMap get/put
In article <>, Wojtek <>
wrote:

> If I have the following:
>
> HashMap<MyKey,MyValue> map = new HashMap<MyKey,MyValue>();
> MyKey myKey = new MyKey();
>
> Then I can put in a value by:
>
> map.put(myKey, new MyValue() );
>
> The compiler enforces the use of these two types.
>
> However to do a get I can do the following and the compiler does not
> complain:
>
> map.get(myKey); // this is right
> map.get(myKey.toString()); // this is wrong yet legal
> map.get(new Long(20)); // this is wrong yet legal
>
> All of these are legal according to the compiler. Why is it that the
> compiler does not enforce type checking on the get()?
>
> Or rather, why does the spec not say get(K key) instead of get(Object
> o)
>
> http://java.sun.com/javase/6/docs/ap...(java.lang.Obj
> ect)


HashMap.java: public V get(Object key)

There's no generics declared on the key for reading.

Generics is extremely helpful for common source code mistakes but it is
by no means a powerful tool. There have been many, many long threads
about it here.
--
I won't see Goolge Groups replies because I must filter them as spam


Kevin McMurtrie
  Reply With Quote
Old 10-29-2009, 05:28 AM   #10
Lew
 
Posts: n/a
Default Re: HashMap get/put
Kevin McMurtrie wrote:
> Generics is extremely helpful for common source code mistakes but it is
> by no means a powerful tool. There have been many, many long threads
> about it here.


There may have been long threads about it, but generics most assuredly is a
powerful tool. Perhaps you just haven't learned to use it correctly yet.

--
Lew


Lew
  Reply With Quote
Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are Off
Refbacks are Off




SEO by vBSEO 3.3.2 ©2009, Crawlability, Inc.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46