Finding myself in a situation of needing to increment values in a map in Java, I was curious to see what the most efficient way to do so. Said piece of code will be looped over thousands of times and I wanted it to run as quickly possible. Yes, I know that pre-optimization is the root of all evil, but in this case it was something I needed to be conscious of.
I found a question/thread on StackOverflow where someone else had already pondered the same thing and got a long list of possible answers to compare to each other, including using Apache Commons and the Google Collections Library. After testing all of them, the fastest way ended-up being implementing a “MutableInt” class and using it as the value data type in the map:
- class MutableInt {
- int value = 0;
- public void inc () { ++value; }
- public int get () { return value; }
- }
- Map<string ,MutableInt> map = new HashMap<string ,MutableInt>();
- MutableInt value = map.get (key);
- if (value == null) {
- value = new MutableInt ();
- map.put (key, value);
- }
- value.inc ();
Pretty interesting stuff! Note that the above code snippet is not very cleanly formatted, but you’ll get the idea.
By Matthew Lesko September 23, 2009 - 11:15 am
Have you looked at java.util.concurrent.atomic.AtomicInteger? It's part of Java 5 and up I believe. It has methods for both incrementing and retrieving values much the way the MutableInt class you've created does.
By Brandon Harper October 4, 2009 - 2:02 pm
Matthew,
I haven't looked at that before, but good find.. seems like there were a lot of minor enhancements in Java 5 that I forget about.
By Dead Beef December 9, 2009 - 12:10 pm
It may be fast, but it's not thread-safe. You're aware of this, right?
By Rod September 29, 2010 - 11:41 am
There's a bug in this, B.
The value.inc() line needs to be NOT in an else. It winds up not counting the first time something is placed in the map the way it's currently written, since the MutableInt starts at 0 instead of 1.
Just used it for some production code and noticed this.
By Maria April 27, 2011 - 9:07 pm
Hey Brandon, thank you for constantly sharing these small guides. This was just what I was looking for.
Kind regards,
Maria
By Brandon Harper December 31, 2011 - 12:36 am
Well shit, I guess that's what I get for not testing it in a unit test. I thought I had edited this post long ago to fix it, but I hadn't. Anyhow, thanks Rod, it's fixed now.