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.

Reply via email to