Yes it's stupid. If it was the only stupid thing sun did in the java specs, i might have understood why it is one of the most populair languages around...
On Thu, 05 Mar 2009 13:46 +0100, "Johan Compagner" <[email protected]> wrote: > 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] > > > > --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
