• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Tim Cooke
  • Campbell Ritchie
  • paul wheaton
  • Ron McLeod
  • Devaka Cooray
Sheriffs:
  • Jeanne Boyarsky
  • Liutauras Vilda
  • Paul Clapham
Saloon Keepers:
  • Tim Holloway
  • Carey Brown
  • Piet Souris
Bartenders:

Map default size Vs Intial size

 
Greenhorn
Posts: 2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
From memory point of view what is the difference between the following 2 declarations?

Map<String,String> myMap = new HashMap<String, String>(2);
Map<String,String> myMap = new HashMap<String, String>();

Is there an advantage of declaring Map size from memory point of view?
 
Master Rancher
Posts: 5161
83
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The one with no declared capacity will have a default capacity of 16, while the one with 2 declared will have 2. Unless, of course, you put enough elements in to expand them beyond their initial capacities. I suppose the size of 2 is a slight advantage in terms of memory, if you don't need any more than that. But it's extremely unlikely to matter to anyone, unless you are creating a LOT of these maps.
 
Mano Pragadeeshwar
Greenhorn
Posts: 2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thank you Mike. I declared the size of the Map since I know for sure that is the number of elements.
 
Bartender
Posts: 10780
71
Hibernate Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Mano Pragadeeshwar wrote:Thank you Mike. I declared the size of the Map since I know for sure that is the number of elements.


That's almost always the best way to go, since it makes loading the Map optimally fast.

However, a HashMap with 2 elements strikes me as possibly over-engineering.

Winston
 
Mike Simmons
Master Rancher
Posts: 5161
83
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Winston Gutkowski wrote:

Mano Pragadeeshwar wrote:Thank you Mike. I declared the size of the Map since I know for sure that is the number of elements.


That's almost always the best way to go, since it makes loading the Map optimally fast.


Well, thing is, if you put 2 entries into such a map, it's going to resize to capacity 4, because the default load factor is .75. It may be tempting to make the load factor 1 instead. But then there's another issue - at size 2 or 4, there's a considerably higher chance of hash collision than there is at at size 16. So if you're talking about speed, rather than memory, the default size 16 will probably work better. Does this really matter? Probably not, except as an example that such micro-optimizations are not as straightforward as they seem.

Winston Gutkowski wrote:However, a HashMap with 2 elements strikes me as possibly over-engineering.


Maybe. But often there are APIs that require a Map for some reason. For the common case that you need to create such a map but it doesn't need to be editable later, I would recommend Google Guava's ImmutableMap:

This is equivalent to the more tedious

but the Google version, aside from being more compact, also creates a map of the appropriate size, automatically.
 
Winston Gutkowski
Bartender
Posts: 10780
71
Hibernate Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Mike Simmons wrote:Well, thing is, if you put 2 entries into such a map, it's going to resize to capacity 4, because the default load factor is .75.


True. I always though that was an odd way to do things. If I supply a size, it seems reasonable to assume that I'm doing so because I know how many elements I'm going to add; and therefore it would seem sensible to allocate a map capacity that won't need re-hashing.

Winston
 
Mike Simmons
Master Rancher
Posts: 5161
83
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Well, capacity isn't exactly the same as the number of elements a hash table can hold, anyway. You could put 100 elements in a table with size 2 for example - it's just that you would have ~50 collisions in each bucket. And you can have collisions even when the size is less than the capacity. That's why they pick 0.75 as a default. No value would really guarantee no collisions - they just try to pick a reasonable value there.
 
Winston Gutkowski
Bartender
Posts: 10780
71
Hibernate Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Mike Simmons wrote:Well, capacity isn't exactly the same as the number of elements a hash table can hold, anyway. You could put 100 elements in a table with size 2 for example - it's just that you would have ~50 collisions in each bucket. And you can have collisions even when the size is less than the capacity. That's why they pick 0.75 as a default. No value would really guarantee no collisions - they just try to pick a reasonable value there.


I think maybe we're talking at cross-purposes here. If I say
new HashSet(50);
I think it can be reasonably assumed that I want to load 50 values into the resulting Set.

If that's the case, then it would seem sensible to me to make the initial capacity of the Set sufficient to be able to do that without having to re-hash, which I suspect would require space of at least (50 / load-factor) + 1 buckets. However, last time I looked, the class didn't seem to do that.

Winston

 
Sheriff
Posts: 3837
66
Netbeans IDE Oracle Firefox Browser
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Mike Simmons wrote:


I would dobut I agree that the Guava version is still more pleasant.
 
Sheriff
Posts: 22849
132
Eclipse IDE Spring Chrome Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I hate that code. You're creating an anonymous inner class only to automatically add some entries.
 
Martin Vashko
Sheriff
Posts: 3837
66
Netbeans IDE Oracle Firefox Browser
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Rob Spoor wrote:I hate that code. You're creating an anonymous inner class only to automatically add some entries.


Yes, but what's the deal?

One more anonymous class? That in itself cannot be a problem; I've got tens, if not hundreds others in my code, mostly Swing listeners. And some of them are created for very simple purposes, certainly classifiable as "only to ...".

In this case, the benefit is that I don't publish the modifiable version of the map anywhere. That alone is a very good reason to me. But I'd be tempted to do this even for simple (modifiable) map, since the declaration and initialization would be completely tied together; I always try to keep them together whenever possible.

On the other hand, I don't remember actually constantly initializing a map ever. I'd be still eager to hear your reasoning, though
 
Rob Spoor
Sheriff
Posts: 22849
132
Eclipse IDE Spring Chrome Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
It's just personal style. If this is for constructing a static field, I would use a static initializer block. If it is for an instance field or local variable, I'd probably create a method. Both will shield the temporary map variable.
 
Mike Simmons
Master Rancher
Posts: 5161
83
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Winston, you might appreciate this. On JavaPosse's latest podcast, Tor just discovered the same thing we were talking about, that using HashSet's constructor as if you're telling it the number of elements do expect does not avoid resizing. They rant on it a bit, agreeing with you about what they expected it should do. It's in the Aug 10 podcast, around 0:59-1:07. Bottom line: use Guava, which does what you want here.
 
Winston Gutkowski
Bartender
Posts: 10780
71
Hibernate Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Mike Simmons wrote:Winston, you might appreciate this. On JavaPosse's latest podcast, Tor just discovered the same thing we were talking about, that using HashSet's constructor as if you're telling it the number of elements do expect does not avoid resizing. They rant on it a bit, agreeing with you about what they expected it should do. It's in the Aug 10 podcast, around 0:59-1:07. Bottom line: use Guava, which does what you want here.


Ah. Cheers for that. I kind of figured it did; but it's always nice to be vindicated. I'll have to check out Guava one of these days.

Winston
reply
    Bookmark Topic Watch Topic
  • New Topic