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]

Reply via email to