Java Solaris Communities Sun Store Join SDN My Profile Why Join?
 
Bug Database
Bug Detail
Quick Lists
Top 25 Bugs
Top 25 RFE's
Recently Closed Bugs
Printable Page Printable Page


Bug Database
Bug ID: 6394757
Votes 1
Synopsis (coll) AbstractSet.removeAll is surprisingly dependent on relative collection sizes
Category java:classes_util
Reported Against
Release Fixed
State 5-Cause Known, bug
Priority: 4-Low
Related Bugs 4266874 , 4730113 , 6396943
Submit Date 07-MAR-2006
Description
One would think that the following program
---------------------------
import java.util.*;

public class Bug {
    static void test(String... elts) {
	Set<String> s = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
	s.addAll(Arrays.asList("a", "b"));
	s.removeAll(Arrays.asList(elts));
	System.out.println(s);
    }

    public static void main(String[] args) {
	test("A");
	test("A", "C");
    }
}
---------------------------

would print 2 identical lines, but in fact it prints

[b]
[a, b]

The results are dependent on the relative sizes of the two sets,
violating the Principle of Least Astonishment.
Posted Date : 2006-03-07 06:09:54.0
Work Around
N/A
Evaluation
This is apparently due to a misguided optimization

4266874: java.util.AbstractSet can speed up removeAll

There was a missed opportunity to fix it in

4730113: TreeSet removeAll(), retainAll() don't use comparator; addAll() does

The Right Thing is to simply remove AbstractSet.removeAll.
Some more spec work on Collection.removeAll would also be worthwhile.
Posted Date : 2006-03-07 06:24:59.0

Josh Bloch writes:

"The spec clearly states
that removeAll "Removes all this collection's elements that are also
contained in the specified collection."  So the current behavior is
not just unpredictable, it's broken.  It worked until 1.3, and was
broken in 1.3-1.5.  Sigh..."

(And indeed, AbstractCollection.removeAll does precisely what the
Collection.removeAll spec demands)
Posted Date : 2006-03-07 08:53:36.0

Contribution forum : https://jdk-collaboration.dev.java.net/servlets/ProjectForumMessageView?forumID=1463&messageID=21022
Posted Date : 2007-08-09 21:51:31.0

Jason writes insightfully:

The spec AbstractSet.removeAll and Collections.disjoint should be aligned with each other.
This suggested fix uses the wording from Collections.disjoint and IdentityHashMap and applies it to Collection.removeAll spec.

Jason


Source from jdk7b17
--- c:\temp\Collection.java	2007-08-03 08:54:36.941733500 -0500
+++ c:\temp\6394757\Collection.java	2007-08-08 16:51:39.907991600 -0500
@@ -337,6 +337,15 @@
      * specified collection (optional operation).  After this call returns,
      * this collection will contain no elements in common with the specified
      * collection.
+     *
+     * &lt;p&gt;Care must be exercised if this method is used on collections that
+     * do not comply with the general contract for {@code Collection}.
+     * Implementations may elect to iterate over either collection and test
+     * for containment in the other collection (or to perform any equivalent
+     * computation).  If either collection uses a nonstandard equality test
+     * whose ordering is not &lt;i&gt;compatible with equals&lt;/i&gt; or uses
+     * reference-equality semantics then both collections must use the
+     * same nonstandard equality test, or the result of this method is undefined.
      *
      * @param c collection containing elements to be removed from this collection
      * @return &lt;tt&gt;true&lt;/tt&gt; if this collection changed as a result of the
Posted Date : 2007-08-09 22:06:30.0
Comments
  
  Include a link with my name & email   


PLEASE NOTE: JDK6 is formerly known as Project Mustang