that is then the wrong spec that i talk about That is completely stupid With a comparator you just OVERRIDE the equals, thats the whole point!
johan On Thu, Mar 5, 2009 at 13:44, Pointbreak <[email protected]<pointbreak%[email protected]> > wrote: > 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] <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] > >
