java - Unintuitive behavior of removeAll method in sets -
i discovered weird behavior of removeall method of abstractsets when working individual comparators.
depending on size of compared collections different comparator used.
it documented in api still cannot see reason behind it.
here code:
import java.util.comparator; import java.util.set; import java.util.stack; import java.util.treeset; public class test { public static void main(string[] args) { // comparator. example, length of string compared set<string> set = new treeset<string>(new comparator<string>() { @override public int compare(string o1, string o2) { return o1.length() - o2.length(); } }); set.add("a"); set.add("aa"); set.add("aaa"); set.add("aaaa"); system.out.println(set); // output: [a, aa, aaa, aaaa] stack<string> stack = new stack<string>(); stack.push("b"); stack.push("bb"); stack.push("bbb"); stack.push("bbbb"); set.removeall(stack); // no items removed set system.out.println(set); // output: [a, aa, aaa, aaaa] // let's see happens if remove object stack stack.pop(); set.removeall(stack); // items stack removed // set system.out.println(set); // output: [aaaa] /* reason strange behaviour: depending on size of * passed collection, treeset uses either remove() function of * itself, or collection object passed. while * remove() method of treeset uses comparator determine * equality, remove() method of passed determines * equality calling equals() on objects. */ } }
you have created undefined behavior since sets have different criteria of equality. combining collections in way can work if have same. violating contract a.equals(b) must yield same result b.equals(a).
comparable: recommended (though not required) natural orderings consistent equals. because sorted sets (and sorted maps) without explicit comparators behave "strangely" when used elements (or keys) natural ordering inconsistent equals. in particular, such sorted set (or sorted map) violates general contract set (or map), defined in terms of equals method.
Comments
Post a Comment