You are missing the point. With a string it will work, because the
elements will actually be the same string objects, so the String.equals
and the overridden compare method will give the same results in the
example. Johan's point is that while set1.removeAll() is called, it is
not the compare method of set1 that is used, which seems
counterintuitive.

On Thu, 05 Mar 2009 13:13 +0100, "Dave Schoorl" <[email protected]>
wrote:
> 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]
> 

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to