Frage

I have the code:

System.out.println("before: " + clusters.size());

        Iterator it = clusters.iterator();
        while (it.hasNext()) {
            Set<Place> set = (Set<Place>) it.next();
            if (set == max2) {
                System.out
                        .println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
                it.remove();
                break;
            }
        }

        System.out.println("after: " + clusters.size());

I made this because clusters.remove(max2) returned false. Now it prints

before: 96
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
after: 96

How is it possible?

War es hilfreich?

Lösung

While your code should (intuitively) work, you're hitting a limitation of the way sets are designed. The hash of a set is the sum of all the hashes of its items, and a hash set's items MUST have consistent hashes, or it is unable to find them during lookups. You're using a set of sets, and I believe you have modified your child sets while they were in the set-of-sets, so it now cannot find them to remove them. This is undefined behaviour territory, so you may find it behaves differently when compiled against different versions and implementations of the standard library.

You would be better off using a map of key->set. In general, remember that after adding an item to a set (or using it as a key in a map), you should do nothing which would change its hash (of course, this is for HashSets and HashMaps, which are easily the most common. For other types, follow the specific rules given in their docs, but it often boils down to: don't change it once added).

Edit: seems that KEYSER beat me to it with his information in a comment. Oh well.

Also, the notes on your use of == instead of equals are sort-of valid, but if you know that the object is certainly the exact same reference then your code is OK (and faster!). From the log statements you're seeing, this appears to be the case.

Andere Tipps

About Iterator.remove():
Removes from the underlying collection the last element returned by the iterator (optional operation). This method can be called only once per call to next. The behavior of an iterator is unspecified if the underlying collection is modified while the iteration is in progress in any way other than by calling this method.

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