Iterator.remove() - Not!

V

VisionSet

In a single iteration I am doing the following on a Collection with initial
size = 2

next()
size = 2
remove()
size = 1 // success
next()
size = 1
remove()
size = 1 // !!

remove can only be called once per call to next(), it is!
The fact remove() returns nothing is a clue to the fact it should guarantee
to succeed.
 
G

GaryM

In a single iteration I am doing the following on a Collection
with initial size = 2

next()
size = 2
remove()
size = 1 // success
next()
size = 1
remove()
size = 1 // !!

remove can only be called once per call to next(), it is!
The fact remove() returns nothing is a clue to the fact it should
guarantee to succeed.


Are you using obtaining an Iterator for your Collection? I know what
this subject says, but this works fine:

Vector victor = new Vector();
victor.add("1");
victor.add("2");

Iterator iter = victor.iterator();

System.out.println(victor.size());
iter.next();
iter.remove();
System.out.println(victor.size());
iter.next();
iter.remove();
System.out.println(victor.size());

displays -->

2
1
0
 
V

VisionSet

GaryM said:
Are you using obtaining an Iterator for your Collection? I know what
this subject says, but this works fine:

I believe my problem has something to do with the underlying method of
removal.
I am using a Set and (though ill advised) the contents are mutable.
I am mutating objects during iteration and the underlying remove(object)
method is not working correctly for some reason, if I ditch my equals &
hashCode methods it works fine.
So I think those are the culprit.
 
D

Dale King

VisionSet said:
I believe my problem has something to do with the underlying method of
removal.
I am using a Set and (though ill advised) the contents are mutable.
I am mutating objects during iteration and the underlying remove(object)
method is not working correctly for some reason, if I ditch my equals &
hashCode methods it works fine.
So I think those are the culprit.

The culprit is the fact that you are mutating the contents without
removing them from the container. You cannot change the the items in a
HashSet (or the keys for a HashMap which is actually what HashSet uses
for its implementation) in a way that changes the outcome of the equals
or hashcode method. To change the value, you must remove it, change it
and then put it back. Otherwise you will not be able to find it. HashMap
rely on equals and hashCode to be able to retrieve the item.

The same type of thing also applies to TreeSet and TreeMap, but the
important method there is the compareTo method.

Unfortunately you can't do this type of operation using an iterator
because adding an item will kill any iterators with a
ConcurrentModificationException.

By "ditching" your equals and hashCode methods you use the default ones
and their outcomes can never be changed so the fact that you mutate the
object does not result in unretreivable items. But that also means you
can get multiple objects in the set with the same "value". Whether this
is appropriate depends on your application.

-- Dale King
 
V

VisionSet

Dale King said:
The culprit is the fact that you are mutating the contents without
removing them from the container. You cannot change the the items in a
HashSet (or the keys for a HashMap which is actually what HashSet uses
for its implementation) in a way that changes the outcome of the equals
or hashcode method. To change the value, you must remove it, change it
and then put it back. Otherwise you will not be able to find it. HashMap
rely on equals and hashCode to be able to retrieve the item.

The same type of thing also applies to TreeSet and TreeMap, but the
important method there is the compareTo method.

Unfortunately you can't do this type of operation using an iterator
because adding an item will kill any iterators with a
ConcurrentModificationException.

By "ditching" your equals and hashCode methods you use the default ones
and their outcomes can never be changed so the fact that you mutate the
object does not result in unretreivable items. But that also means you
can get multiple objects in the set with the same "value". Whether this
is appropriate depends on your application.

Thanks Dale.
I quickly came to realise this, so I have basically reimplemented Set by
wrapping a List.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,431
Messages
2,571,677
Members
48,796
Latest member
Greg L.

Latest Threads

Top