it has nothing to do with threading or concurent modification

Its really a simple test just run this:

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 Test
{
    public static void main(String[] args)
    {
        TreeSet<MyObject> set1 = new TreeSet<MyObject>(new
Comparator<MyObject>(){

            public int compare(MyObject o1, MyObject o2)
            {
                return o1.aString.compareToIgnoreCase(o2.aString);
            }
        });

        set1.add(new MyObject("johan"));
        set1.add(new MyObject("rob"));

        HashSet<MyObject> set2 = new HashSet<MyObject>();
        set2.add(new MyObject("johan"));


        set1.removeAll(set2);

        System.err.println("this works: " + set1.size() + " == 1, and
remainng object is " + set1.iterator().next() + " == rob");

        // add removed back in
        set1.add(new MyObject("johan"));

        // increase the size of set2 with some other random others
        set2.add(new MyObject("random1"));
        set2.add(new MyObject("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.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 = new MyFixedTreeSet<MyObject>(new Comparator<MyObject>(){

            public int compare(MyObject o1, MyObject o2)
            {
                return o1.aString.compareToIgnoreCase(o2.aString);
            }
        });

        set1.add(new MyObject("johan"));
        set1.add(new MyObject("rob"));

        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.add(new MyObject("johan"));

        set1.retainAll(set2);

        System.err.println("set1 is now correct, it has 1 left: " + set1);

    }

    public static class MyObject
    {
        private final String aString;

        MyObject(String str)
        {
            aString = str;
        }

        @Override
        public String toString()
        {
            return aString;
        }
    }

    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;
        }
    }
}

johan



On Wed, Mar 4, 2009 at 15:35, Brill Pappin <[email protected]> wrote:

> if "xxx" is a mutable Set then it should work.
>
> However you have to be careful about how you remove elements from the
> collection you working with, depending on your you do it, you'll get an
> exception about  concurrent modification.
>
> - Brill
>
>
> On 3-Mar-09, at 5:44 PM, Johan Compagner wrote:
>
>  Is this the same?
>>
>> Set set1 = xxx
>> Collection col1 = xxx;
>>
>> foreach (col in col1)
>> set1.remove(col)
>>
>> or
>>
>> set1.removeAll(col1);
>>
>>
>> ???
>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [email protected]
> For additional commands, e-mail: [email protected]
>
>

Reply via email to