1 /* 2 * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 * @test 26 * @bug 6529795 27 * @summary next() does not change iterator state if throws NoSuchElementException 28 * @author Martin Buchholz 29 */ 30 package test.java.util.Collection; 31 32 import java.util.ArrayDeque; 33 import java.util.ArrayList; 34 import java.util.Collection; 35 import java.util.HashMap; 36 import java.util.Hashtable; 37 import java.util.IdentityHashMap; 38 import java.util.Iterator; 39 import java.util.LinkedHashMap; 40 import java.util.LinkedList; 41 import java.util.List; 42 import java.util.ListIterator; 43 import java.util.Map; 44 import java.util.NoSuchElementException; 45 import java.util.PriorityQueue; 46 import java.util.TreeMap; 47 import java.util.TreeSet; 48 import java.util.Vector; 49 import java.util.WeakHashMap; 50 import java.util.concurrent.ArrayBlockingQueue; 51 import java.util.concurrent.ConcurrentHashMap; 52 import java.util.concurrent.ConcurrentLinkedDeque; 53 import java.util.concurrent.ConcurrentLinkedQueue; 54 import java.util.concurrent.ConcurrentSkipListMap; 55 import java.util.concurrent.ConcurrentSkipListSet; 56 import java.util.concurrent.CopyOnWriteArrayList; 57 import java.util.concurrent.CopyOnWriteArraySet; 58 import java.util.concurrent.LinkedBlockingQueue; 59 import java.util.concurrent.LinkedTransferQueue; 60 import org.testng.Assert; 61 import org.testng.annotations.Test; 62 63 @SuppressWarnings("unchecked") 64 public class IteratorAtEnd { 65 66 private static final int SIZE = 6; 67 68 @Test testArrayList()69 public void testArrayList() { 70 testCollection(new ArrayList()); 71 } 72 73 @Test testVector()74 public void testVector() { 75 testCollection(new Vector()); 76 } 77 78 @Test testLinkedList()79 public void testLinkedList() { 80 testCollection(new LinkedList()); 81 } 82 83 @Test testArrayDeque()84 public void testArrayDeque() { 85 testCollection(new ArrayDeque()); 86 } 87 88 @Test testTreeSet()89 public void testTreeSet() { 90 testCollection(new TreeSet()); 91 } 92 93 @Test testCopyOnWriteArrayList()94 public void testCopyOnWriteArrayList() { 95 testCollection(new CopyOnWriteArrayList()); 96 } 97 98 @Test testCopyOnWriteArraySet()99 public void testCopyOnWriteArraySet() { 100 testCollection(new CopyOnWriteArraySet()); 101 } 102 103 @Test testConcurrentSkipListSet()104 public void testConcurrentSkipListSet() { 105 testCollection(new ConcurrentSkipListSet()); 106 } 107 108 @Test testPriorityQueue()109 public void testPriorityQueue() { 110 testCollection(new PriorityQueue()); 111 } 112 113 @Test testLinkedBlockingQueue()114 public void testLinkedBlockingQueue() { 115 testCollection(new LinkedBlockingQueue()); 116 } 117 118 @Test testArrayBlockingQueue()119 public void testArrayBlockingQueue() { 120 testCollection(new ArrayBlockingQueue(100)); 121 } 122 123 @Test testConcurrentLinkedDeque()124 public void testConcurrentLinkedDeque() { 125 testCollection(new ConcurrentLinkedDeque()); 126 } 127 128 @Test testConcurrentLinkedQueue()129 public void testConcurrentLinkedQueue() { 130 testCollection(new ConcurrentLinkedQueue()); 131 } 132 133 @Test testLinkedTransferQueue()134 public void testLinkedTransferQueue() { 135 testCollection(new LinkedTransferQueue()); 136 } 137 138 @Test testHashMap()139 public void testHashMap() { 140 testMap(new HashMap()); 141 } 142 143 @Test testHashtable()144 public void testHashtable() { 145 testMap(new Hashtable()); 146 } 147 148 @Test testLinkedHashMap()149 public void testLinkedHashMap() { 150 testMap(new LinkedHashMap()); 151 } 152 153 @Test testWeakHashMap()154 public void testWeakHashMap() { 155 testMap(new WeakHashMap()); 156 } 157 158 @Test testIdentityHashMap()159 public void testIdentityHashMap() { 160 testMap(new IdentityHashMap()); 161 } 162 163 @Test testConcurrentHashMap()164 public void testConcurrentHashMap() { 165 testMap(new ConcurrentHashMap()); 166 } 167 168 @Test testConcurrentSkipListMap()169 public void testConcurrentSkipListMap() { 170 testMap(new ConcurrentSkipListMap()); 171 } 172 173 @Test testTreeMap()174 public void testTreeMap() { 175 testMap(new TreeMap()); 176 } 177 testCollection(Collection c)178 static void testCollection(Collection c) { 179 try { 180 for (int i = 0; i < SIZE; i++) { 181 c.add(i); 182 } 183 test(c); 184 } catch (Throwable t) { 185 Assert.fail("Unexpected exception: " + t.getMessage()); 186 } 187 } 188 testMap(Map m)189 static void testMap(Map m) { 190 try { 191 for (int i = 0; i < 3 * SIZE; i++) { 192 m.put(i, i); 193 } 194 test(m.values()); 195 test(m.keySet()); 196 test(m.entrySet()); 197 } catch (Throwable t) { 198 Assert.fail("Unexpected exception: " + t.getMessage()); 199 } 200 } 201 test(Collection c)202 static void test(Collection c) { 203 try { 204 final Iterator it = c.iterator(); 205 THROWS(NoSuchElementException.class, 206 () -> { 207 while (true) { 208 it.next(); 209 } 210 }); 211 try { 212 it.remove(); 213 } catch (UnsupportedOperationException exc) { 214 return; 215 } 216 } catch (Throwable t) { 217 Assert.fail("Unexpected exception: " + t.getMessage()); 218 } 219 220 if (c instanceof List) { 221 final List list = (List) c; 222 try { 223 final ListIterator it = list.listIterator(0); 224 it.next(); 225 final Object x = it.previous(); 226 THROWS(NoSuchElementException.class, it::previous); 227 try { 228 it.remove(); 229 } catch (UnsupportedOperationException exc) { 230 return; 231 } 232 Assert.assertFalse(list.get(0).equals(x)); 233 } catch (Throwable t) { 234 Assert.fail("Unexpected exception: " + t.getMessage()); 235 } 236 237 try { 238 final ListIterator it = list.listIterator(list.size()); 239 it.previous(); 240 final Object x = it.next(); 241 THROWS(NoSuchElementException.class, it::next); 242 try { 243 it.remove(); 244 } catch (UnsupportedOperationException exc) { 245 return; 246 } 247 Assert.assertFalse(list.get(list.size() - 1).equals(x)); 248 } catch (Throwable t) { 249 Assert.fail("Unexpected exception: " + t.getMessage()); 250 } 251 } 252 } 253 254 interface Fun { 255 f()256 void f() throws Throwable; 257 } 258 THROWS(Class<? extends Throwable> k, Fun... fs)259 static void THROWS(Class<? extends Throwable> k, Fun... fs) { 260 for (Fun f : fs) { 261 try { 262 f.f(); 263 Assert.fail("Expected " + k.getName() + " not thrown"); 264 } catch (Throwable t) { 265 if (!k.isAssignableFrom(t.getClass())) { 266 Assert.fail("Unexpected exception: " + t.getMessage()); 267 } 268 } 269 } 270 } 271 } 272