changeset 16209:841075d55095

8166446: SingletonIterator.forEachRemaining doesn't advance before calling action Reviewed-by: martin
author smarks
date Tue, 06 Dec 2016 17:26:43 -0800
parents 4629fe47e826
children 10b191e1793b
files src/java.base/share/classes/java/util/Collections.java test/java/util/Collections/SingletonIterator.java
diffstat 2 files changed, 24 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/src/java.base/share/classes/java/util/Collections.java	Tue Dec 06 14:44:12 2016 -0800
+++ b/src/java.base/share/classes/java/util/Collections.java	Tue Dec 06 17:26:43 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, 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
@@ -4699,8 +4699,8 @@
             public void forEachRemaining(Consumer<? super E> action) {
                 Objects.requireNonNull(action);
                 if (hasNext) {
+                    hasNext = false;
                     action.accept(e);
-                    hasNext = false;
                 }
             }
         };
--- a/test/java/util/Collections/SingletonIterator.java	Tue Dec 06 14:44:12 2016 -0800
+++ b/test/java/util/Collections/SingletonIterator.java	Tue Dec 06 17:26:43 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 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
@@ -23,6 +23,7 @@
 
 /*
  * @test
+ * @bug 8024500 8166446
  * @run testng SingletonIterator
  */
 
@@ -38,6 +39,15 @@
 
 @Test(groups = "unit")
 public class SingletonIterator {
+    static void assertIteratorExhausted(Iterator<?> it) {
+        assertFalse(it.hasNext());
+        try {
+            it.next();
+            fail("should have thrown NoSuchElementException");
+        } catch (NoSuchElementException success) { }
+        it.forEachRemaining(e -> { throw new AssertionError("action called incorrectly"); });
+    }
+
     public void testForEachRemaining() {
         Iterator<String> it = Collections.singleton("TheOne").iterator();
         AtomicInteger cnt = new AtomicInteger(0);
@@ -48,13 +58,18 @@
         });
 
         assertEquals(cnt.get(), 1);
-        assertFalse(it.hasNext());
+        assertIteratorExhausted(it);
+    }
+
+    static class SingletonException extends RuntimeException { }
+
+    public void testThrowFromForEachRemaining() {
+        Iterator<String> it = Collections.singleton("TheOne").iterator();
 
         try {
-            String str = it.next();
-            fail("Should throw NoSuchElementException at end");
-        } catch (NoSuchElementException ex) {
-            // ignore;
-        }
+            it.forEachRemaining(s -> { throw new SingletonException(); });
+        } catch (SingletonException ignore) { }
+
+        assertIteratorExhausted(it);
     }
 }