TreeSet giving incorrect output - Java8
java, treeset
Solution
This happens because a SortedSet’s Comparator is used for sorting, but removeAll relies on the `equals` method of each element. From the SortedSet documentation:
Note that the ordering maintained by a sorted set (whether or not an explicit comparator is provided) must be consistent with equals if the sorted set is to correctly implement the `Set` interface. (See the `Comparable` interface or `Comparator` interface for a precise definition of consistent with equals.) This is so because the `Set` interface is defined in terms of the `equals` operation, but a sorted set performs all element comparisons using its `compareTo` (or `compare`) method, so two elements that are deemed equal by this method are, from the standpoint of the sorted set, equal. The behavior of a sorted set is well-defined even if its ordering is inconsistent with equals; it just fails to obey the general contract of the `Set` interface.
The explanation of “consistent with equals” is defined in the Comparable documentation:
The natural ordering for a class `C` is said to be consistent with equals if and only if `e1.compareTo(e2) == 0` has the same boolean value as `e1.equals(e2)` for every `e1` and `e2` of class `C`. Note that `null` is not an instance of any class, and `e.compareTo(null)` should throw a `NullPointerException` even though `e.equals(null)` returns `false`.
It is strongly recommended (though not required) that natural orderings be consistent with equals. This is so because sorted sets (and sorted maps) without explicit comparators behave "strangely" when they are used with elements (or keys) whose natural ordering is inconsistent with equals. In particular, such a sorted set (or sorted map) violates the general contract for set (or map), which is defined in terms of the `equals` method.
In summary, your Set’s Comparator behaves differently than the elements’ `equals` method, causing unusual (though predictable) behavior.
Problem
While working with a tree set, I found very peculiar behavior. As per my understanding following program should print two identical lines: ``` public class TestSet { static void test(String... args) { Set<String> s = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER); s.addAll(Arrays.asList("a", "b")); s.removeAll(Arrays.asList(args)); System.out.println(s); } public static void main(String[] args) { test("A"); test("A", "C"); } } ``` but strangely it prints: ``` [b] [a, b] ``` I am unable to understand - Why is tree set behaving like this?