If I change every MyObject in a String, everything is fine. Perhaps the
MyObject is not obeying the necessary contracts?
See adjusted code below:
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.TreeSet;
public class TestWithStrings
{
public static void main(String[] args)
{
TreeSet<String> set1 = getCleanSet();
HashSet<String> set2 = new HashSet<String>();
set2.add("johan");
set1.removeAll(set2);
System.err.println("this works: " + set1.size() + " == 1, and
remaining object is " + set1.iterator().next() + " == rob");
// add removed back in
set1 = getCleanSet();
// increase the size of set2 with some other random others
set2.add("random1");
set2.add("random2");
// now size is bigger then set1, call removeall again:
set1.removeAll(set2);
System.err.println("this doesnt work: " + set1.size() + " != 1,
so now both objects stil remain! This is because " +
"removeAll isnt overwritten by TreeSet and AbstractSet
walks over the smallest set but then compare fails");
// same for retainAll that also compares wrong.
set1 = getCleanSet();
set1.retainAll(set2);
System.err.println("set1 is now completely empty, but it should
have 1 left: " + set1);
// so both methods should always iterator through the colleciton
they get and do the compare on its self
set1 = getCleanFixedSet();
set1.removeAll(set2);
System.err.println("now this works: " + set1.size() + " == 1,
and remainng object is " + set1.iterator().next() + " == rob");
// add removed back in
set1 = getCleanFixedSet();
set1.retainAll(set2);
System.err.println("set1 is now correct, it has 1 left: " + set1);
}
public static TreeSet<String> getCleanSet() {
TreeSet<String> set1 = new TreeSet<String>(new Comparator<String>(){
public int compare(String o1, String o2)
{
return o1.compareToIgnoreCase(o2);
}
});
set1.add("johan");
set1.add("rob");
return set1;
}
public static TreeSet<String> getCleanFixedSet() {
TreeSet<String> set1 = new MyFixedTreeSet<String>(new
Comparator<String>(){
public int compare(String o1, String o2)
{
return o1.compareToIgnoreCase(o2);
}
});
set1.add("johan");
set1.add("rob");
return set1;
}
public static class MyFixedTreeSet<E> extends TreeSet<E>
{
public MyFixedTreeSet(Comparator<? super E> comparator)
{
super(comparator);
}
@Override
public boolean retainAll(Collection<?> c)
{
ArrayList<E> list = new ArrayList<E>();
Iterator<?> e = c.iterator();
while (e.hasNext()) {
Object next = e.next();
if (contains(next)) {
list.add((E)next);
}
}
boolean modified = list.size() < size();
if (modified)
{
clear();
for (E item : list)
{
add(item);
}
}
return modified;
}
@Override
public boolean removeAll(Collection<?> c)
{
boolean modified = false;
for (Iterator<?> i = c.iterator(); i.hasNext(); )
modified |= remove(i.next());
return modified;
}
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]