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]
