Removing an entry
Entries sometimes have to go: a shop stops selling an item, a player leaves the game. HashMap's remove method takes a key and deletes that key together with its value.
HashMap<String, Integer> animals = new HashMap<>();
animals.put("cat", 4);
animals.put("rabbit", 1);
animals.remove("rabbit");
System.out.println(animals.size()); // 1
System.out.println(animals.containsKey("rabbit")); // false
The size drops by 1, and the key is gone, so containsKey("rabbit") is now false.
What remove returns
remove returns the value it deleted. If the key is missing, it changes nothing and returns null; it does not throw.
Integer gone = animals.remove("cat");
System.out.println(gone); // 4
System.out.println(animals.remove("cat")); // null
The return type is Integer rather than int because it may be null. Ignoring the return value, as the first example did, is perfectly fine.
Using the returned value
Because a missing key gives null, the return value tells you whether anything was removed. With one rabbit in the map, if (animals.remove("rabbit") != null) is true the first time. The second time the same condition is false, so a program can print nothing to remove in that case. Most of the time you do not need this and can ignore the result.
The trap: remove on a list takes an index
On an ArrayList, remove(2) removes the item at index 2. A HashMap has no positions, so its remove always takes a key. There is one place where the two look alike: a map with Integer keys. In a HashMap<Integer, String> called byId with the keys 2 (value "two") and 0 (value "zero"), byId.remove(2) removes the entry whose key is 2 and returns "two", leaving {0=zero}. It does not remove the item at position 2, because a map has no positions. Whenever you call remove, ask yourself whether the thing in front of you is a list or a map.
Related methods
remove(key, value)with two arguments deletes the entry only if the key currently has that value. Withapplesat 5,remove("apples", 4)returnsfalseand leaves the entry, whileremove("apples", 5)returnstrueand removes it.clear()removes every entry. Afterwardssize()is 0 andisEmpty()istrue.
The exercise
A pet shop keeps animals: cat 4, dog 2, rabbit 1. The program prints the size (3), and at the bottom checks whether any rabbits are left. The last rabbit has gone home with a family:
- Delete the key with
animals.remove("rabbit"), below the first print. - Print the size again with
System.out.println(animals.size()). One key is gone, so it is 2.
The final if then finds no "rabbit" key and takes its else branch.
HashMap<String, Integer> animals = new HashMap<>();
animals.put("cat", 4);
animals.put("dog", 2);
animals.put("rabbit", 1);
System.out.println(animals.size());
animals.remove("rabbit");
System.out.println(animals.size());
if (animals.containsKey("rabbit")) {
System.out.println("We still have rabbits");
} else {
System.out.println("No rabbits left");
}
Output:
3
2
No rabbits left
Common mistakes
- Setting the count to 0 instead of removing the key. After
animals.put("rabbit", 0)the size is still 3 andcontainsKey("rabbit")is stilltrue, so the program would sayWe still have rabbits. Onlyremovedeletes the key. - Expecting an error for a missing key. Removing a key twice is harmless: the second call returns
nulland changes nothing. - Reading the key after removal.
animals.get("rabbit")isnullonce the key is gone.
Key takeaways
map.remove(key)deletes the key and its value, and the size goes down by 1.- It returns the old value, or
nullif the key was not there. - On a map,
removealways takes a key, never an index.
