HashMap – contains and get methods should not be used together

The architect means that get and containsKey have the same costs and may be accumulated into one check:

Integer val = map.get(c);
if (val != null) {
  ...
} else {
  ...
}

But I wonder why the architect is only concerned about that, as there are more things to improve:

  • Refer to objects by their interfaces (Effective Java 2nd Edition, Item 52)
  • Since Java 1.7 you can use the diamond operator <>
  • Accumulate the autoboxing operations of the characters
  • If you use AtomicInteger (or any other modifiable number class) instead of Integer you can even merge the get with one of the puts

So from my point of view the best performance, when using a HashMap, would offer:

Map<Character, AtomicInteger> map = new HashMap<>();
for (Character c : characters) {
    AtomicInteger val = map.get(c);
    if (val != null) {
        val.incrementAndGet();
    } else {
        map.put(c, new AtomicInteger(1));
    }
}

If the range of your characters is small (and known in advance), you could use an int array for counting. This would be the fastest of all possible solutions:

char firstCharacter="a";
char lastCharacter="z";
int[] frequency = new int[lastCharacter - firstCharacter + 1];
for (char c : characters) {
  frequency[c - firstCharacter]++;
}

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)