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?

War es hilfreich?

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(...) und set.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.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top