Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is resize implemented the way it is?

I have several questions about rebuilding HashMaps when adding new key-values pair. I will ask questions based on these facts (they are true for Oracle JVM, not sure if they are correct for other JVMs):

  1. Resize rebuilds HashMap to have a bigger inner table array every time when you grow HashMap bigger than threshold (threshold = loadFactor*numberOfEntries). It does not matter in which bucket the newly created Entry is put - Map will still grow bigger. Even if all of the Entries go into one bucket (i.e. their keys' hashCode() return the same number).
  2. HashMap does not shrink when data is removed. Even if all keys are removed from HashMap, the inner size of it's table does not change.

Now the questions:

  1. Are these facts correct?

If they are, then:

  1. Why resize implemented this way? Is it the intention to grow the inner table even when it is obviously not necessary? Or a bug?
  2. Why it does not shrink?
like image 436
deemson Avatar asked Jan 22 '14 17:01

deemson


1 Answers

Yes, these facts are correct.

  1. Detecting whether it is "obviously not necessary" would take a lot of time, and it's almost always redundant, since the case where all the keys have the same hash code is rare. In short, you're paying a significant expense (tracking how common one particular hash code is) for everybody just to save some work in an extremely rare case, which will end up costing more than it saves.
  2. Because removing is a somewhat less common operation, and it's usually followed by refilling the map. If you want to start the map over with a smaller table, you can just assign it to a new HashMap and let the old one be garbage-collected.
like image 124
Louis Wasserman Avatar answered Oct 22 '22 06:10

Louis Wasserman