Updating Map Entries
A map is not frozen once you build it. You can replace the value behind a key, grow a value that is already there, or drop a pair completely.
put() Replaces Instead of Duplicating
Calling put() with a key the map already holds does not add a second pair. The new value takes the place of the old one and size() stays the same.
Map<String, Integer> stock = new Map<String, Integer>{ 'pens' => 12 };
stock.put('pens', 20);
System.debug(stock.get('pens')); // 20
System.debug(stock.size()); // 1
Growing a Value That Is Already There
To change a value based on what is already stored, read it with get(), work out the new value, and put it back under the same key.
stock.put('pens', stock.get('pens') + 5);
System.debug(stock.get('pens')); // 25
Counting with containsKey()
The most common update pattern is a tally. Because get() returns null for a key the map has never seen, check with containsKey() first and start that key at 1.
List<String> visits = new List<String>{ 'apex', 'soql', 'apex' };
Map<String, Integer> tally = new Map<String, Integer>();
for (String pageName : visits) {
if (tally.containsKey(pageName)) {
tally.put(pageName, tally.get(pageName) + 1);
} else {
tally.put(pageName, 1);
}
}
System.debug(tally.get('apex')); // 2
remove() Drops a Pair
remove() deletes the pair and hands back the value it was holding.
Integer removedCount = tally.remove('soql'); // 1
System.debug(tally.size()); // 1
Common Mistakes
Do not skip the containsKey() check when you are counting. Adding 1 to the null that a missing key returns throws a null pointer exception on the very first word.
Why This Matters
Tallying is everywhere: how many opportunities each owner has, how many errors of each type a job hit, how many contacts sit under each account. One map plus one loop answers all of them.