This week's book giveaways are in the Java EE and JavaScript forums.
We're giving away four copies each of The Java EE 7 Tutorial Volume 1 or Volume 2(winners choice) and jQuery UI in Action and have the authors on-line!
See this thread and this one for details.
The moose likes Java in General and the fly likes HashMap Construction with initial values Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of The Java EE 7 Tutorial Volume 1 or Volume 2 this week in the Java EE forum
or jQuery UI in Action in the JavaScript forum!
JavaRanch » Java Forums » Java » Java in General
Bookmark "HashMap Construction with initial values" Watch "HashMap Construction with initial values" New topic
Author

HashMap Construction with initial values

Benjamin Samuel
Ranch Hand

Joined: Dec 15, 2006
Posts: 33
Hi,

I just came across this code below. I'm not clear how this works. Can you please explain me how this works?



I'm not understanding how this put() is working normally.

Thanks in advance
Binil
David O'Meara
Rancher

Joined: Mar 06, 2001
Posts: 13459

Code that is not easy to understand (and therefore maintain) is silly.

There are several things in play here.

1) an anonymous class
2) an instance block

Breaking it down, the anonymous class can be converted to an inner class:



Then the instance block can be replaced with a no-arg constructor

What it is missing is an unmodifiable Map, so better would be:


But I wouldn't do it in the first place

[Edit - added 'this' for clarity]
[Edit - forgot 'extends HashMap'. Rookie mistake ]
[ October 10, 2008: Message edited by: David O'Meara ]
Ernest Friedman-Hill
author and iconoclast
Marshal

Joined: Jul 08, 2003
Posts: 24183
    
  34

This expression creates an instance of an anonymous class which extends HashMap. The anonymous class includes an instance initializer block which contains the "put" calls. Are you familiar with either of these things yet? An anonymous inner class is a way of defining a subclass without giving it a name. An instance initializer block is basically a way to add code to all the constructors in a class. This code is really equivalent to



In any case, depending on who you ask, this is a cute hack, or a crime against humanity. It's not a very common idiom, and I hope it doesn't become moreso.

[ Edit: DRAT! Beaten! ]
[ October 10, 2008: Message edited by: Ernest Friedman-Hill ]

[Jess in Action][AskingGoodQuestions]
David O'Meara
Rancher

Joined: Mar 06, 2001
Posts: 13459

Normally I wouldn't be so petty but since it's EFH: Woo hoo, a whole two minutes!

One thing is clear though, and that is neither of us would promote this practice. When in doubt, err on the side of legibility.
Benjamin Samuel
Ranch Hand

Joined: Dec 15, 2006
Posts: 33
But how is that the anonymous class extends HashMap even without specifying the 'extends' keyword.
David O'Meara
Rancher

Joined: Mar 06, 2001
Posts: 13459

This is a new HashMap:

This is an anonymous Class that extends HashMap. The bit in the brackets is the 'extension stuff'

eg override default HashMap toString()
Benjamin Samuel
Ranch Hand

Joined: Dec 15, 2006
Posts: 33
Got it!
Thanks for the explanation
Rene Wooller
Greenhorn

Joined: Oct 06, 2010
Posts: 2
Hi All,
A lot of people are saying how they wouldn't do this. Would you mind listing a few alternatives?

All I can think of at the moment is a declarative approach, using a properties file or xml or somesuch, in which case, the benefit would be ease or change.

But this would a bit of hassle. I think the example given would be faster to code, and I personally don't find it hard to read at all.

Cheers,
Rene
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 38441
    
  23
A more conventional approach would look like this:
swapnil kataria
Ranch Hand

Joined: Feb 26, 2011
Posts: 64
it is declaring hm as final variable, that mean you dont need to use variable name to call a function,
it will access directly
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 38441
    
  23
swapnil kataria wrote:it is declaring hm as final variable, that mean you dont need to use variable name to call a function,
it will access directly
Please explain that a bit more; it is by no means clear.
Mike Simmons
Ranch Hand

Joined: Mar 05, 2008
Posts: 3011
    
  10
Rene Wooller wrote:Hi All,
A lot of people are saying how they wouldn't do this. Would you mind listing a few alternatives?

Personally, if I wanted to expose this map as a public field, I would want to ensure that not only is the reference final, but the object itself is immutable. We don't want anyone calling put() or remove(0 on the map once it has been constructed. Traditionally this could be done like this:

Or this:

But nowadays I would prefer to use Guava:


Rene Wooller wrote:All I can think of at the moment is a declarative approach, using a properties file or xml or somesuch, in which case, the benefit would be ease or change.

Yeah, something like that could certainly be useful. If you want to load key-value pairs from some other source, I would put that loading code inside the initializeMap() method. You can do whatever you want there. If it needs more careful testing, it's easy to make the method package-private or some other access. The reason I often prefer a named method to a static initializer is that it's easier to test a named method.

Rene Wooller wrote:But this would a bit of hassle. I think the example given would be faster to code, and I personally don't find it hard to read at all.

Well, it's an unusual syntax that has just started to appear recently. A lot of people don't like it simply because they don't recognize it - or because they figure many other people will not recognize it. Which I think is a fair point. If I'm going to bring in something new that people might not be familiar with, I'd rather it be Guava, because that makes the code look much nicer and gives many other useful methods as well.
 
It is sorta covered in the JavaRanch Style Guide.
 
subject: HashMap Construction with initial values