From 9877170d02bdae715bcb9e213770cfa266ffc157 Mon Sep 17 00:00:00 2001 From: Stuart Marks Date: Tue, 6 Dec 2016 17:26:43 -0800 Subject: [PATCH] 8166446: SingletonIterator.forEachRemaining doesn't advance before calling action Reviewed-by: martin --- .../share/classes/java/util/Collections.java | 4 +-- .../util/Collections/SingletonIterator.java | 29 ++++++++++++++----- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/jdk/src/java.base/share/classes/java/util/Collections.java b/jdk/src/java.base/share/classes/java/util/Collections.java index 9f6ab76a723..7119fff3e89 100644 --- a/jdk/src/java.base/share/classes/java/util/Collections.java +++ b/jdk/src/java.base/share/classes/java/util/Collections.java @@ -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 class Collections { public void forEachRemaining(Consumer action) { Objects.requireNonNull(action); if (hasNext) { - action.accept(e); hasNext = false; + action.accept(e); } } }; diff --git a/jdk/test/java/util/Collections/SingletonIterator.java b/jdk/test/java/util/Collections/SingletonIterator.java index 966cce07414..0f7dfd17252 100644 --- a/jdk/test/java/util/Collections/SingletonIterator.java +++ b/jdk/test/java/util/Collections/SingletonIterator.java @@ -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 @@ import static org.testng.Assert.fail; @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 it = Collections.singleton("TheOne").iterator(); AtomicInteger cnt = new AtomicInteger(0); @@ -48,13 +58,18 @@ public class SingletonIterator { }); assertEquals(cnt.get(), 1); - assertFalse(it.hasNext()); + assertIteratorExhausted(it); + } + + static class SingletonException extends RuntimeException { } + + public void testThrowFromForEachRemaining() { + Iterator 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); } }