• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Create Immutable HashMap

 
Manjunath An
Greenhorn
Posts: 15
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello - I have a situation where in I need to send a hashmap as an argument to another method. And I do not have any control over this other method and I have to make sure that the HashMap I am passing should not be updated.

I could have used Collections.unModifiableMap() to a get an unmodifiableMap but, the I need to specifically pass HashMap and not just any Map.

Please let me know how to achieve this.

Thanks!
M
 
Hunter McMillen
Ranch Hand
Posts: 492
Firefox Browser Linux VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator


takes a map as an argument and returns it in a context where it can't be modified. If you pass it a HashMap<K,V> it will still return a HashMap<K,V>:



Hope this helps.
Hunter
 
Manjunath An
Greenhorn
Posts: 15
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi - thanks for the reply.

But Collections.unModifiableMap() will always return an object of type Map. Return type does not depend on what type we are passing in.

See javadoc here http://docs.oracle.com/javase/6/docs/api/java/util/Collections.html#unmodifiableMap%28java.util.Map%29

Am I missing something? Is there any other approach ?
 
Hunter McMillen
Ranch Hand
Posts: 492
Firefox Browser Linux VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Map is just an interface, what will actually be returned is a concrete implementation of that interface; which in this case is a HashMap since that is what you are passing in to the method.

The nice thing about the unmodifiableMap(...) returning a Map instead of a HashMap is that if later down the road you decide you don't want to use a HashMap , but instead a HashTable or a TreeMap all of the code should still function the same.

Hunter
 
Manjunath An
Greenhorn
Posts: 15
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hunter - The return type is Map which is an interface and I am sure that concrete implementation would be returned by this method. However the concrete implementation returned will always be of type java.util.Collections$UnmodifiableMap

If we try out below code snippet we get ClassCastException



Without cast, we would get compilation error, with casting to HashMap, we get runtime exception saying Exception in thread "main" java.lang.ClassCastException: java.util.Collections$UnmodifiableMap cannot be cast to java.util.HashMap

 
Hunter McMillen
Ranch Hand
Posts: 492
Firefox Browser Linux VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You're right the left hand side of the statement will need to say Map<K,V> but this will work for any map implementation:




Hunter
 
Manjunath An
Greenhorn
Posts: 15
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thats correct. If on left hand side I use Map instead HashMap, it would work.

But I have to pass this unmodifiable hashmap to aother method whose signature looks like below



If I create a unmodifiable map like you said, I would end up with a Map i.e if I do



the above unmodifiableMap cannot be passed to my transform method as it is expecting specifically HashMap and not just any Map
 
Jesper de Jong
Java Cowboy
Saloon Keeper
Posts: 15452
42
Android IntelliJ IDE Java Scala Spring
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If the method that you have to call takes a HashMap instead of a Map, and you cannot change that method, then what you want is not possible.

Collections.unmodifiableMap wraps a map in a special Map implementation that throws an exception if you try to call any methods on it that modify the map. But it does not, and it cannot, return a java.util.HashMap.

What you can do is make a defensive copy of your HashMap and pass that to the method. Then, if the method modifies the copy, you will have your original HashMap.
 
Manjunath An
Greenhorn
Posts: 15
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
hmm... thanks for the replies Hunter and Jasper..!
 
Jesper de Jong
Java Cowboy
Saloon Keeper
Posts: 15452
42
Android IntelliJ IDE Java Scala Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I just thought of another possibility.

You could create your own class that extends HashMap. Implement all methods that modify the map to throw an exception, for example an UnsupportedOperationException. Then pass that map to the transform method. Since it's a subclass of HashMap, it will work.

Note that this is in principle possible, but you're really stretching and bending your code to make it work with the badly designed transform method. I'd only do something like this if there is really no other possibility.

(To do it right you should ofcourse also use generics).
 
Manjunath An
Greenhorn
Posts: 15
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yes, I thought of this approach too, but it is like doing too much just to obey to transform method's signature...
 
Winston Gutkowski
Bartender
Pie
Posts: 10509
64
Eclipse IDE Hibernate Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Manjunath An wrote:Yes, I thought of this approach too, but it is like doing too much just to obey to transform method's signature...

Yes, because the method's signature is wrong. If it only 'transforms' HashMaps, it should say so in the name, and, to be honest, it strikes me as a very bad piece of design.

I'm with Jesper (his first post). Until you get this design error fixed, use:
transform(new HashMap(data));
and put up with the (probably small) performance hit.

Alternatively, set up your own transform(Map) method that simply forwards to the existing one exactly as above. The advantage of that is that when the author of that method eventually gets it right, you can just change it to a simple direct call.

Also, I strongly suggest that you (and the person that wrote the method) start using generics.

Winston

 
Manjunath An
Greenhorn
Posts: 15
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks Winston!
 
Winston Gutkowski
Bartender
Pie
Posts: 10509
64
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Manjunath An wrote:Thanks Winston!

You're welcome. Hope you saw the addition about using a forwarder; I think that's probably the approach I'd take.

"Every problem in computer science can be solved by a layer of indirection" - David Wheeler

Winston
 
Campbell Ritchie
Sheriff
Pie
Posts: 49849
70
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
One warning about unmodifiable: it doesn’t mean the same as immutable. It returns a read-only view of the original Map. If you change the original Map, the unmodifiable version changes too.
 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Please BeForthrightWhenCrossPostingToOtherSites.(←click) It's rather frustrating to spend time trying to help someone, only to find they've already gotten their answer elsewhere.

https://forums.oracle.com/forums/thread.jspa?threadID=2361539&tstart=0
 
Pat Farrell
Rancher
Posts: 4678
7
Linux Mac OS X VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Use Google's free, open source Guava collections code. They have ImmutableMap, ImmutableList, ImmutableSet, etc.
Wonderful library.
 
Manjunath An
Greenhorn
Posts: 15
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi all - Yes, I did post this topic elsewhere, in future would make sure to add a statement that "I posted this question the other day in SomeOtherForum.com [link], but wasn't able to get a good answer, so now I'm asking here..". Sorry about this and thanks again for all the replies.

 
Campbell Ritchie
Sheriff
Pie
Posts: 49849
70
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Apologies accepted.
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic