Mam mapę.TreeMap iterator.remove() modyfikuje ostatni wpis
Map<Integer,String> map = ...
Mapa ma n elementów (Weźmy na ten przykład te 9)
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");
teraz chcę iteracyjne nad tej mapie, a następnie wyjmij n-ty element używając iteratora.
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());
// vs
// System.out.println(entry.getValue());
// it.remove();
}
}
}
Z javadoc, zakładam, semantyka usuwania są dobrze zdefiniowane.
Ale w zależności od wykonania mapie - tj HashMap vs TreeMap istnieje różnica czy it.remove()
odbywa przed lub poentry.getValue()
.
dla HashMaps map = new HashMap<>()
zachowanie jest
...
remove(4, map); //output: four
//or
remove(5, map); //output: five
dla TreeMap map = new TreeMap<>()
zachowanie jest taka sama, kiedy usunąć bieżący wpis z iteracyjnej po Mam obejrzano go:
System.out.println(entry.getValue());
it.remove();
wyników w
remove(4, map); //output: four
//or
remove(5, map); //output: five
tej pory tak dobrze, ale jeśli usunąć element przed uzyskać dostęp do wpisu:
it.remove();
System.out.println(entry.getValue());
wyjście jest nieoczekiwanie
remove(4, map); //output: five !!!
//or
remove(5, map); //output: five ok
Najwyraźniej it.remove()
z TreeMap
modyfikuje Entries
, ponieważ TreeMap
składa się z Entries
, a iterator faktycznie zwraca rzeczywiste elementy mapy. A w zależności od aktualnej pozycji w drzewie wewnętrzne odwołania punktu wejścia do następnego lub bieżącego (usuniętego) elementu.
Ale nie jestem pewien, czy to błąd, czy jest to celowe. Jeśli tak jest, zastanawiam się nad uzasadnieniem?
Edit: Kod źródłowy TreeMap iterator.remove()
Nie widzę zachowania, które opisujesz na którejkolwiek mapie ... jakiej wersji Java używasz? Co się stanie, jeśli wypiszesz wartość pozycji przed i po usunięciu()? – daniu
jdk1.8.0_121 ... jest odtwarzalny z mapą drzewa z tylko trzema wpisami (1,2,3), usuwając środkowy element (2). Ale nie pojawia się w HashMap –
wydrukowanie go przed i po wynikach w "dwóch, trzech" –