Sorry, I have to correct myself. According to the API-docs, the compare
method in a TreeSet must be consistent with equals. In Johan's example
it is not.

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

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

Reply via email to