I have a map.
Map<Integer,String> map = ...
There are n elements in the map (take these 9 for this example)
map.put(1,"one"); map.put(2,"two"); map.put(3,"three"); map.put(4,"four"); map.put(5,"five"); map.put(6,"six"); map.put(7,"seven"); map.put(8,"eigth"); map.put(9,"nine");
Now I want to iterate over this map and remove the nth element using an iterator.
private void remove(int num, final Map<Integer, String> map) { Iterator<Map.Entry<Integer,String>> it = map.entrySet().iterator(); Map.Entry<Integer,String> entry; while(it.hasNext()){ entry = it.next(); if(Integer.valueOf(num).equals(entry.getKey())){ it.remove(); System.out.println(entry.getValue());
From javadoc, I would suggest the removal semantics are well defined.
But depending on the implementation of the card - i.e. HashMap vs TreeMap there is a difference whether it.remove() is executed before or after entry.getValue() .
for HashMaps map = new HashMap<>() behavior
... remove(4, map); //output: four //or remove(5, map); //output: five
for TreeMap map = new TreeMap<>() behavior is the same when I delete the current record from the iterator after I access it:
System.out.println(entry.getValue()); it.remove();
leads to
remove(4, map); //output: four //or remove(5, map); //output: five
so good, but if I delete the item before I access the record:
it.remove(); System.out.println(entry.getValue());
Exit unexpectedly
remove(4, map); //output: five !!! //or remove(5, map); //output: five ok
Apparently, it.remove() from TreeMap modifies Entries because TreeMap consists of Entries , and the iterator actually returns the actual elements of the map. And depending on the current position in the tree, the internal links are the entry points to the next or current (deleted) element.
But I'm not sure if this is a mistake, or if it is intentional. If the latter is the case, I wonder about the rationale?
Edit: Source code TreeMap iterator.remove ()