Warum wird es nicht aus der Menge entfernen?
Frage
Dieser Fehler hat mir eine Weile zu finden ...
Betrachten Sie diese Methode:
public void foo(Set<Object> set)
{
Object obj=set.iterator().next();
set.remove(obj)
}
Ich rufe die Methode mit einem nicht leeren Hash-Set, aber kein Element entfernt werden!
Warum sollte das sein?
Lösung
Für eine HashSet, kann dies, wenn die hashCode des Objekts ändert auftreten, nachdem es zu dem Satz hinzugefügt wurde. Die HashSet.remove () -Methode in der falschen Hash Eimer dann suchen Sie und nicht zu finden ist.
Dies würde wahrscheinlich nicht passieren, wenn Sie iterator.remove tat (), aber in jedem Fall können Objekte in einem HashSet deren hashCode Speicherung ist wartet ein Unfall ändern geschehen (wie Sie haben entdeckt).
Andere Tipps
Puzzle? Wenn Object.hashCode
, Object.equals
oder das "Hash-Set" falsch implementiert wurden (siehe zum Beispiel java.net.URL
- Verwendung URI
).
Auch wenn der Satz (direkt oder indirekt) enthält selbst, etwas seltsam ist wahrscheinlich passieren (genau das, was die Umsetzung und die Phase des Mondes abhängig ist).
Was ist die Implementierung Art des Satzes und welche Objekte in der Reihe?
- Wenn es ein HashSet ist, stellen Sie sicher, dass der Wert des Objekts hashCode () -Methode zwischen
set.put(...)
undset.remove(...)
konstant bleibt. - Wenn es ein TreeSet ist, stellen Sie sicher, dass keine Änderungen an das Objekt vorgenommen wurden, dass der Set Komparator beeinflussen oder das
compareTo
Methode des Objekts.
In beiden Fällen wird der Code zwischen set.put(...)
und set.remove(...)
gegen den Vertrag durch die jeweilige Klassenimplementierung definiert. Als Faustregel ist es eine gute Idee, unveränderliche Objekte als Set Inhalt (und als Map-Tasten) zu verwenden. Aufgrund ihrer Art können solche Objekte nicht geändert werden, während sie in einem Satz gespeichert werden.
Wenn Sie eine andere Satz Implementierung verwenden, überprüft seine JavaDoc für den Vertrag; aber in der Regel entweder equals
oder hashCode
muss gleich bleiben, während das Objekt in dem Satz enthalten ist.
Beyond the fehlen; nach set.remove(obj)
, kann es in drei Situationen passieren (von javadoc zitiert).
ClassCastException - if the type of the specified element is incompatible with this set (optional). NullPointerException - if the specified element is null and this set does not support null elements (optional). UnsupportedOperationException - if the remove method is not supported by this set.
Sie können auch versuchen:
public void foo(Set<Object> set)
{
Object obj=set.iterator().next();
iterator.remove();
}
Sollte es sein:
public void foo(Set<Object> set)
{
Iterator i = set.iterator();
i.next();
i.remove();
}
Der Fehler könnte etwas zu tun mit:
public void remove ()
Das Verhalten eines Iterators nicht näher bezeichnet, wenn der Basiswert Sammlung wird, während die modifizierte Iteration wird ausgeführt in irgendeiner Weise anders als durch diese Methode aufrufen.
( Referenz )
Ich kann nicht helfen, aber das Gefühl, dass (zum Teil) das Problem ist, dass die eingestellte Wert übergeben wird, nicht verweisen. Ich habe nicht viel Erfahrung in Java obwohl haben, so konnte ich völlig falsch sein.