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

takeWhile produces incorrect result with elements produced by flatMap

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P2 P2
    • 10
    • 9
    • core-libs
    • None

        The following code:

                String[][] ss = {{"a", "b"}, {"c", "d"}};
                Stream.of(ss).
                        flatMap(Arrays::stream).
                        takeWhile(
                                e -> e != "c").
                        forEachOrdered(System.out::println);

        will output:

            a
            b
            d

        takeWhile is incorrectly assuming that an upstream operation supports and honors cancellation, which unfortunately is not the case for flatMap. (It's tricky to support given flatMap operates on a public Stream whose implementation may not be known. forEach variants supporting cancellation is required).

        The current implementation of while op Sink::accept is:

                            @Override
                            public void accept(T t) {
                                if (take = predicate.test(t)) {
                                    downstream.accept(t);
                                }
                            }

        it should be:

                            @Override
                            public void accept(T t) {
                                if (take && (take = predicate.test(t))) {
                                    downstream.accept(t);
                                }
                            }

              psandoz Paul Sandoz
              psandoz Paul Sandoz
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

                Created:
                Updated:
                Resolved: