Ich habe eine Karte.TreeMap iterator.remove() ändert den letzten Eintrag
Map<Integer,String> map = ...
Die Karte hat n Elemente (lets für dieses Beispiel dieser 9 nehmen)
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");
Jetzt habe ich über diese Karte iterieren möge, und entfernen Sie das n-te Element des 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());
// vs
// System.out.println(entry.getValue());
// it.remove();
}
}
}
Aus dem Javadoc, ich nehme an, die Semantik des Entfernens sind gut definiert.
Aber je nach Implementierung der Karte - das heißt HashMap vs TreeMap gibt es einen Unterschied, ob die it.remove()
vor oder nachentry.getValue()
erfolgt.
für HashMaps map = new HashMap<>()
das Verhalten
...
remove(4, map); //output: four
//or
remove(5, map); //output: five
für TreeMap map = new TreeMap<>()
das Verhalten ist das gleiche, wenn ich den aktuellen Eintrag aus dem nach Iterator entfernen habe ich es erreicht:
System.out.println(entry.getValue());
it.remove();
Ergebnisse in
remove(4, map); //output: four
//or
remove(5, map); //output: five
so weit, so gut, aber wenn ich das Element vor entfernen greife ich auf den Eintrag:
it.remove();
System.out.println(entry.getValue());
Der Ausgang
remove(4, map); //output: five !!!
//or
remove(5, map); //output: five ok
offenbar unerwartet
ist, dieit.remove()
der
TreeMap
ändert die
Entries
, weil die
TreeMap
besteht aus
Entries
und der Iterator tatsächlich die tatsächlichen Elemente der Karte zurückgibt. Und abhängig von der aktuellen Position im Baum, zeigen die internen Referenzen des Entries auf das nächste oder das aktuelle (entfernte) Element.
Aber ich bin mir nicht sicher, ob das ein Fehler ist oder ob dies beabsichtigt ist. Wenn Letzteres der Fall ist, frage ich mich nach dem Grund dafür?
Edit: Quellcode der TreeMap iterator.remove()
Ich bekomme nicht das Verhalten, das Sie beschreiben in jeder Karte ... welche Java-Version verwenden Sie? Was passiert, wenn Sie den Wert des Eintrags sowohl vor als auch nach dem Entfernen ausgeben()? – daniu
jdk1.8.0_121 ... ist es mit einer TreeMap mit nur 3 Einträgen (1,2,3) reproduzierbar, das mittlere Element (2) entfernend. Aber es erscheint nicht in HashMap –
Drucken es vor und nach den Ergebnissen in "zwei, drei" –