Why won't he be removed from the set?

This error helped me find ...

Consider this method:

public void foo(Set<Object> set) { Object obj=set.iterator().next(); set.remove(obj) } 

I call a method with a non-empty set of hashes, but not a single item will be deleted!

Why should it be?

+4
source share
6 answers

For a HashSet, this can happen if the hashCode object changes after it is added to the set. The HashSet.remove () method may then look in the wrong Hash bucket and not find it.

It may not happen if you did iterator.remove (), but in any case, storing objects in a HashSet whose hash code might change is a random wait (as you discovered).

+7
source

Puzzle? If Object.hashCode , Object.equals or the "hash set" were implemented incorrectly (see, for example, java.net.URL - use URI ).

Also, if the set (directly or indirectly) contains itself, something strange can happen (exactly what the implementation and phase of dependence on the moon are).

+3
source

What is the type of implementation of the collection and what objects are inside the collection?

  • If it is a HashSet, make sure that the value of the hashCode () method of the object remains constant between set.put(...) and set.remove(...) .
  • If it is a TreeSet, make sure that no changes have been made to the object that affects the installed comparator or method of the compareTo object.

In both cases, the code between set.put(...) and set.remove(...) violates the contract defined by the corresponding implementation of the class. As a general rule, it is recommended that you use immutable objects as the specified content (and as map keys). By their very nature, such objects cannot be modified while they are stored inside a set.

If you use any other set implementation, check its JavaDoc for your contract; but usually equals or hashCode should remain unchanged while the object is contained in the set.

+2
source

Besides the missing ';' after set.remove(obj) , This can happen in three situations (quoted from javadoc).

 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. 

You can also try:

 public void foo(Set<Object> set) { Object obj=set.iterator().next(); iterator.remove(); } 
+1
source

Should it be:

 public void foo(Set<Object> set) { Iterator i = set.iterator(); i.next(); i.remove(); } 

?

The error may be related to:

public void remove ()

The behavior of the iterator is undefined, if the main collection changes, the iteration continues in some way other than calling this method.

( Link )

+1
source

I cannot help but feel that (part of) the problem is that the set is passed by value, not by reference. I don't have much experience with Java, so I could be completely wrong.

-3
source

All Articles