7
\$\begingroup\$

What's the neatest way to increment all values in a HashMap by 1? The map is <String, Integer>, but the key doesn't matter as every value will be incremented.

Is it "cleaner" to use lambdas with forEach/compute/etc. or just loop through the entries?

HashMap<String, Integer> map = mobCounter.get(mob);
for (Entry<String, Integer> e : map.entrySet()) {
    map.put(e.getKey(), e.getValue() + 1);
}

This doesn't look too messy to me but I'm wondering if people like seeing lambdas more.

\$\endgroup\$
1
  • \$\begingroup\$ Unless you are specifically bound to use HashMap, you could write Map<String, Integer> map = mobCounter.get(mob); instead of HashMap. \$\endgroup\$
    – user482594
    Commented Nov 27, 2016 at 8:30

2 Answers 2

8
\$\begingroup\$

You must not modify the keys of a HashMap while iterating over it. You are just lucky it worked.

Instead of the put(...), write e.setValue(e.getValue() + 1).

If you have some kind of Multiset available (e.g. when you are using Guava), you could replace your HashMap with a Multiset<String>, which will make your intention clearer.

Using lambdas, your code would look like:

map.replaceAll((k, v) -> v + 1);

This looks very nice to me. It cannot get any shorter.

\$\endgroup\$
1
  • \$\begingroup\$ Never knew that, thank you! The replaceAll does look very clean, I'll use that. Thanks for the suggestions! \$\endgroup\$
    – rococo
    Commented Nov 27, 2016 at 23:51
1
\$\begingroup\$

The solution you've offered is a perfectly fine solution. While it is possible to do it with lambdas, I don't think it's strictly necessary.

The only things I would mention:

  • map is a terrible name for a variable.
  • Your map variable should have the interface type, not the implementation type.
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.