< prev index next >

src/java.base/share/classes/java/util/AbstractSet.java

Print this page
rev 54827 : 6394757: AbstractSet.removeAll semantics are surprisingly dependent on relative sizes
Reviewed-by: XXX

*** 1,7 **** /* ! * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this --- 1,7 ---- /* ! * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this
*** 63,86 **** protected AbstractSet() { } // Comparison and hashing /** * Compares the specified object with this set for equality. Returns ! * {@code true} if the given object is also a set, the two sets have ! * the same size, and every member of the given set is contained in ! * this set. This ensures that the {@code equals} method works ! * properly across different implementations of the {@code Set} ! * interface.<p> * * This implementation first checks if the specified object is this * set; if so it returns {@code true}. Then, it checks if the * specified object is a set whose size is identical to the size of ! * this set; if not, it returns false. If so, it returns * {@code containsAll((Collection) o)}. * * @param o object to be compared for equality with this set * @return {@code true} if the specified object is equal to this set */ public boolean equals(Object o) { if (o == this) --- 63,93 ---- protected AbstractSet() { } // Comparison and hashing + // FIXME: the first paragraph below is copied from Set.equals, because + // {@inheritDoc} inherits text from superclasses, not interfaces (see JDK-6376959). /** * Compares the specified object with this set for equality. Returns ! * {@code true} if the specified object is also a set, the two sets ! * have the same size, and every member of the specified set is ! * contained in this set. This operation uses the membership semantics ! * of this set. This definition ensures that the {@code equals} method ! * works properly across different implementations of the ! * {@code Set} interface. * + * @implSpec * This implementation first checks if the specified object is this * set; if so it returns {@code true}. Then, it checks if the * specified object is a set whose size is identical to the size of ! * this set; if not, it returns {@code false}. If so, it returns * {@code containsAll((Collection) o)}. * + * @implNote + * {@inheritDoc} + * * @param o object to be compared for equality with this set * @return {@code true} if the specified object is equal to this set */ public boolean equals(Object o) { if (o == this)
*** 123,184 **** if (obj != null) h += obj.hashCode(); } return h; } - - /** - * Removes from this set all of its elements that are contained in the - * specified collection (optional operation). If the specified - * collection is also a set, this operation effectively modifies this - * set so that its value is the <i>asymmetric set difference</i> of - * the two sets. - * - * <p>This implementation determines which is the smaller of this set - * and the specified collection, by invoking the {@code size} - * method on each. If this set has fewer elements, then the - * implementation iterates over this set, checking each element - * returned by the iterator in turn to see if it is contained in - * the specified collection. If it is so contained, it is removed - * from this set with the iterator's {@code remove} method. If - * the specified collection has fewer elements, then the - * implementation iterates over the specified collection, removing - * from this set each element returned by the iterator, using this - * set's {@code remove} method. - * - * <p>Note that this implementation will throw an - * {@code UnsupportedOperationException} if the iterator returned by the - * {@code iterator} method does not implement the {@code remove} method. - * - * @param c collection containing elements to be removed from this set - * @return {@code true} if this set changed as a result of the call - * @throws UnsupportedOperationException if the {@code removeAll} operation - * is not supported by this set - * @throws ClassCastException if the class of an element of this set - * is incompatible with the specified collection - * (<a href="Collection.html#optional-restrictions">optional</a>) - * @throws NullPointerException if this set contains a null element and the - * specified collection does not permit null elements - * (<a href="Collection.html#optional-restrictions">optional</a>), - * or if the specified collection is null - * @see #remove(Object) - * @see #contains(Object) - */ - public boolean removeAll(Collection<?> c) { - Objects.requireNonNull(c); - boolean modified = false; - - if (size() > c.size()) { - for (Object e : c) - modified |= remove(e); - } else { - for (Iterator<?> i = iterator(); i.hasNext(); ) { - if (c.contains(i.next())) { - i.remove(); - modified = true; - } - } - } - return modified; - } - } --- 130,135 ----
< prev index next >