Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8213038

Inconsistent iterator state when iterator.forEachRemaining throws

    Details

    • Type: Bug
    • Status: Open
    • Priority: P3
    • Resolution: Unresolved
    • Affects Version/s: None
    • Fix Version/s: None
    • Component/s: core-libs
    • Labels:
      None

      Description

      When iterator.forEachRemaining throws in the middle of an iteration, where should the index of the iterator be?

      (reported by Zheka Kozlov on core-libs-dev
      "Exceptions in Iterator.forEachRemaining()")

      Collection implementations exhibit 4 (!) different behaviors:

      -----
      import java.util.*;
      import java.util.concurrent.*;
      import java.util.function.*;

      public class Iterator_ForEachRemaining {
          public static void main(String... args) throws Throwable {
              List<Integer> elts = List.of(1, 2, 3, 4, 5);

              test(elts);
              test(Arrays.asList(1, 2, 3, 4, 5));
              test(new LinkedList<>(elts));
              test(new ArrayList<>(elts));
              test(new Vector<>(elts));
              test(new ArrayDeque<>(elts));
              test(new PriorityQueue<>(elts));
              test(new PriorityBlockingQueue<>(elts));
              ArrayBlockingQueue<Integer> abq = new ArrayBlockingQueue<>(10);
              abq.addAll(elts);
              test(abq);
              test(new LinkedBlockingQueue<>(elts));
              test(new ConcurrentLinkedQueue<>(elts));
              test(new ConcurrentLinkedDeque<>(elts));
              test(new LinkedTransferQueue<>(elts));
              test(new CopyOnWriteArrayList<>(elts));
          }

          static void test(Collection<Integer> coll) {
              System.out.printf("%s: ", className(coll));
              Iterator<Integer> iterator = coll.iterator();
              Consumer<Integer> action = i -> {
                  if (i == 3) {
                      throw new RuntimeException();
                  } else {
                      System.out.print(i);
                  }
              };
              try {
                  iterator.forEachRemaining(action);
              } catch (RuntimeException ex) {}
              iterator.forEachRemaining(System.out::print);
              System.out.println();
          }

          static String className(Object x) {
              return x.getClass().getName().replaceFirst(".*\\.", "");
          }
      }

      =>

      ImmutableCollections$ListN: 1245
      Arrays$ArrayList: 1245
      LinkedList: 12345
      ArrayList: 1212345
      Vector: 1212345
      ArrayDeque: 12
      PriorityQueue: 1245
      PriorityBlockingQueue: 12
      ArrayBlockingQueue: 12
      LinkedBlockingQueue: 12
      ConcurrentLinkedQueue: 1245
      ConcurrentLinkedDeque: 1245
      LinkedTransferQueue: 12345
      CopyOnWriteArrayList: 12

        Attachments

          Activity

            People

            • Assignee:
              martin Martin Buchholz
              Reporter:
              martin Martin Buchholz
            • Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

              • Created:
                Updated: