|
Quick Lists
|
|
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.
+ *
+ * <p>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 <i>compatible with equals</i> 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 <tt>true</tt> if this collection changed as a result of the
Posted Date : 2007-08-09 22:06:30.0
|
|
Comments
|
PLEASE NOTE: JDK6 is formerly known as Project Mustang
|
|
|
 |