Hi,

 

I did some testing where one gatherer (doNothingReturnTrue) does not handle the downStream.push(element) returning false correctly.

 

The stream processing is terminated in one case and not in the two other.

Especially see the difference between output from handling «efgh» and «EFGH» below.

 

Is this an error, or is it as expected (Since the doNothingReturnTrue is incorrectly implemented) ?

 

 

Hilsen

Svein Otto Solem

Retired programmer

 

Trace:

splitText('1234')

GatherDoNothingReturnTrue('1')

GatherDoNothingReturnTrue('2')

GatherDoNothingReturnTrue('3')

GatherDoNothingReturnTrue('4')

Optional[1]

 

splitText('efgh')

GatherDoNothingReturnTrue('e')

PeekDoNothing('e')

GatherDoNothingReturnTrue('f')

GatherDoNothingReturnTrue('g')

GatherDoNothingReturnTrue('h')

Optional[e]

 

splitText('EFGH')

GatherDoNothingReturnTrue('E')

GatherDoNothing('E')

Optional[E]

 

Code:

package org.example;

 

import java.util.Iterator;

import java.util.Optional;

import java.util.function.Consumer;

import java.util.function.Function;

import java.util.function.Predicate;

import java.util.stream.Gatherer;

import java.util.stream.Stream;

 

import static java.lang.StringTemplate.STR;

 

public class GatherTestWhereDownStreamPushResultIsNotRespected {

 

    public static void main(String[] args) {

        Optional<String> f1 = Stream.of("1234")

                .gather(logElement("splitText", splitText()))

                .gather(logElement("GatherDoNothingReturnTrue", doNothingReturnTrue()))

                .findFirst();

        System.out.println(f1 +"\n");

 

        Optional<String> f2 = Stream.of("efgh")

                .gather(logElement("splitText", splitText()))

                .gather(logElement("GatherDoNothingReturnTrue", doNothingReturnTrue()))

                .peek(logElement("PeekDoNothing", s -> {}))

                .findFirst();

        System.out.println(f2+"\n");

 

        Optional<String> f3 = Stream.of("EFGH")

                .gather(logElement("splitText", splitText()))

                .gather(logElement("GatherDoNothingReturnTrue", doNothingReturnTrue()))

                .gather(logElement("GatherDoNothing", doNothing()))

                .findFirst();

        System.out.println(f3+"\n");

    }

 

    public static <T> Gatherer<T, ?, T> doNothing() {

        // This is correct impl of doNothing

        return Gatherer.of((_, element, downstream) -> downstream.push(element));

    }

    public static <T> Gatherer<T, ?, T> doNothingReturnTrue() {

        // This is erronous since it does not respect the downstream.push's return value

        return Gatherer.of((_, element, downstream) -> { downstream.push(element); return true; });

    }

    public static Gatherer<String, ?, String> splitText() {

        Gatherer.Integrator<Void, String, String> integrator = (_, s, downstream) -> {

            Iterator<String> iterator = s.chars().mapToObj(Character::toString).iterator();

            while (iterator.hasNext()) {

                String next = iterator.next();

                if (!downstream.push(next)) {

                    return false;

                }

            }

            return true;

        };

        return Gatherer.of(integrator);

    }

 

 

 

    private static void println(String name, Object s) {

        System.out.println(STR. "\{ name }('\{ s }')" );

    }

 

    private static <T> Consumer<T> logElement(String name, Consumer<? super T> c) {

        return x -> {

            println(name, x);

            c.accept(x);

        };

    }

 

    private static <T, A, R> Gatherer<T, A, R> logElement(String name, Gatherer<T, A, R> gatherer) {

        return new Gatherer<T, A, R>() {

            // Still only logs in integrator

            @Override

            public Integrator<A, T, R> integrator() {

                return (state, elem, downstream) -> {

                    println(name, elem);

                    return gatherer.integrator().integrate(state, elem, downstream);

                };

            }

        };

    }

}

 

Reply via email to