Hi everyone. I noticed that different Iterator implementations behave differently when an Exception is thrown inside a Consumer passed to forEachRemaining():
private static void test(List<Integer> list) { Iterator<Integer> iterator = list.iterator(); try { iterator.forEachRemaining(i -> { if (i == 3) { throw new RuntimeException(); } else { System.out.print(i); } }); } catch (RuntimeException ex) { } iterator.forEachRemaining(System.out::print); } public static void main(String... args) throws Throwable { test(List.of(1, 2, 3, 4, 5)); // Prints 1245 System.out.println(); test(Arrays.asList(1, 2, 3, 4, 5)); // Prints 1245 System.out.println(); test(new LinkedList<>(List.of(1, 2, 3, 4, 5))); // Prints 12345 (BAD) System.out.println(); test(new ArrayList<>(List.of(1, 2, 3, 4, 5))); // Prints 1212345 (BAD) } Is this a bug? I think yes because an overridden forEachRemaining() should behave the same as the default implementation: while (hasNext()) { action.accept(next()); } So, in this case, List.of() and Arrays.asList() are correct while LinkedList and ArrayList are not.