SmallEnumIteratorRemoveResilience.java revision 4248
6853ce5c70efff66131398da552b7c2de99926bemental/*
6853ce5c70efff66131398da552b7c2de99926bemental * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
6853ce5c70efff66131398da552b7c2de99926bemental * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6853ce5c70efff66131398da552b7c2de99926bemental *
6853ce5c70efff66131398da552b7c2de99926bemental * This code is free software; you can redistribute it and/or modify it
6853ce5c70efff66131398da552b7c2de99926bemental * under the terms of the GNU General Public License version 2 only, as
6853ce5c70efff66131398da552b7c2de99926bemental * published by the Free Software Foundation.
6853ce5c70efff66131398da552b7c2de99926bemental *
6853ce5c70efff66131398da552b7c2de99926bemental * This code is distributed in the hope that it will be useful, but WITHOUT
6853ce5c70efff66131398da552b7c2de99926bemental * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
6853ce5c70efff66131398da552b7c2de99926bemental * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
cc7e33931673a5c5caffe0a8ab583aa2a88b85acmental * version 2 for more details (a copy is included in the LICENSE file that
cc7e33931673a5c5caffe0a8ab583aa2a88b85acmental * accompanied this code).
cc7e33931673a5c5caffe0a8ab583aa2a88b85acmental *
cc7e33931673a5c5caffe0a8ab583aa2a88b85acmental * You should have received a copy of the GNU General Public License version
cc7e33931673a5c5caffe0a8ab583aa2a88b85acmental * 2 along with this work; if not, write to the Free Software Foundation,
6853ce5c70efff66131398da552b7c2de99926bemental * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
6853ce5c70efff66131398da552b7c2de99926bemental *
6853ce5c70efff66131398da552b7c2de99926bemental * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
6853ce5c70efff66131398da552b7c2de99926bemental * or visit www.oracle.com if you need additional information or have any
6853ce5c70efff66131398da552b7c2de99926bemental * questions.
6853ce5c70efff66131398da552b7c2de99926bemental */
6853ce5c70efff66131398da552b7c2de99926bemental
04e26df8231b128a0b16be3058051f5b60bd60e2mental/*
04e26df8231b128a0b16be3058051f5b60bd60e2mental * Portions Copyright (c) 2011 IBM Corporation
04e26df8231b128a0b16be3058051f5b60bd60e2mental */
6853ce5c70efff66131398da552b7c2de99926bemental
6853ce5c70efff66131398da552b7c2de99926bemental/*
6853ce5c70efff66131398da552b7c2de99926bemental * @test
6853ce5c70efff66131398da552b7c2de99926bemental * @bug 7014637
6853ce5c70efff66131398da552b7c2de99926bemental * @summary EnumSet's iterator.remove() can be resilient to set's modification.
6853ce5c70efff66131398da552b7c2de99926bemental * @author Neil Richards <neil.richards@ngmr.net>, <neil_richards@uk.ibm.com>
6853ce5c70efff66131398da552b7c2de99926bemental */
6853ce5c70efff66131398da552b7c2de99926bemental
fa0d3e877e4e340c200105e84432f4a6a375143amentalimport java.util.EnumSet;
fa0d3e877e4e340c200105e84432f4a6a375143amentalimport java.util.Iterator;
6853ce5c70efff66131398da552b7c2de99926bementalimport java.util.Set;
6853ce5c70efff66131398da552b7c2de99926bemental
6853ce5c70efff66131398da552b7c2de99926bementalpublic class SmallEnumIteratorRemoveResilience {
6853ce5c70efff66131398da552b7c2de99926bemental // enum with less than 64 values
6853ce5c70efff66131398da552b7c2de99926bemental private static enum SmallEnum { e0, e1, e2 }
6853ce5c70efff66131398da552b7c2de99926bemental
6853ce5c70efff66131398da552b7c2de99926bemental public static void main(final String[] args) throws Exception {
6853ce5c70efff66131398da552b7c2de99926bemental final Set<SmallEnum> set = EnumSet.noneOf(SmallEnum.class);
6853ce5c70efff66131398da552b7c2de99926bemental
6853ce5c70efff66131398da552b7c2de99926bemental set.add(SmallEnum.e0);
6853ce5c70efff66131398da552b7c2de99926bemental set.add(SmallEnum.e1);
6853ce5c70efff66131398da552b7c2de99926bemental
6853ce5c70efff66131398da552b7c2de99926bemental final Iterator<SmallEnum> iterator = set.iterator();
6853ce5c70efff66131398da552b7c2de99926bemental
6853ce5c70efff66131398da552b7c2de99926bemental int size = set.size();
fa0d3e877e4e340c200105e84432f4a6a375143amental SmallEnum element = iterator.next();
fa0d3e877e4e340c200105e84432f4a6a375143amental
6853ce5c70efff66131398da552b7c2de99926bemental iterator.remove();
6853ce5c70efff66131398da552b7c2de99926bemental checkSetAfterRemoval(set, size, element);
6853ce5c70efff66131398da552b7c2de99926bemental
6853ce5c70efff66131398da552b7c2de99926bemental size = set.size();
6853ce5c70efff66131398da552b7c2de99926bemental element = iterator.next();
6853ce5c70efff66131398da552b7c2de99926bemental
6853ce5c70efff66131398da552b7c2de99926bemental set.remove(element);
6853ce5c70efff66131398da552b7c2de99926bemental checkSetAfterRemoval(set, size, element);
6853ce5c70efff66131398da552b7c2de99926bemental
c085c61313b7d55dfcccc6e21ac84a9ef0c43eb4mental // The Java API declares that the behaviour here - to call
6853ce5c70efff66131398da552b7c2de99926bemental // iterator.remove() after the underlying collection has been
6853ce5c70efff66131398da552b7c2de99926bemental // modified - is "unspecified".
6853ce5c70efff66131398da552b7c2de99926bemental // However, in the case of iterators for EnumSet, it is easy to
6853ce5c70efff66131398da552b7c2de99926bemental // implement their remove() operation such that the set is
6853ce5c70efff66131398da552b7c2de99926bemental // unmodified if it is called for an element that has already been
6853ce5c70efff66131398da552b7c2de99926bemental // removed from the set - this being the naturally "resilient"
6853ce5c70efff66131398da552b7c2de99926bemental // behaviour.
6853ce5c70efff66131398da552b7c2de99926bemental iterator.remove();
551da380f9124d13d80fecfbd3f7031da6134361mental checkSetAfterRemoval(set, size, element);
6853ce5c70efff66131398da552b7c2de99926bemental }
6853ce5c70efff66131398da552b7c2de99926bemental
6853ce5c70efff66131398da552b7c2de99926bemental private static void checkSetAfterRemoval(final Set<SmallEnum> set,
6853ce5c70efff66131398da552b7c2de99926bemental final int origSize, final SmallEnum removedElement)
6853ce5c70efff66131398da552b7c2de99926bemental throws Exception {
6853ce5c70efff66131398da552b7c2de99926bemental if (set.size() != (origSize - 1)) {
6853ce5c70efff66131398da552b7c2de99926bemental throw new Exception("Test FAILED: Unexpected set size after removal; expected '" + (origSize - 1) + "' but found '" + set.size() + "'");
6853ce5c70efff66131398da552b7c2de99926bemental }
6853ce5c70efff66131398da552b7c2de99926bemental if (set.contains(removedElement)) {
6853ce5c70efff66131398da552b7c2de99926bemental throw new Exception("Test FAILED: Element returned from iterator unexpectedly still in set after removal.");
6853ce5c70efff66131398da552b7c2de99926bemental }
6853ce5c70efff66131398da552b7c2de99926bemental }
6853ce5c70efff66131398da552b7c2de99926bemental}
6853ce5c70efff66131398da552b7c2de99926bemental