jOOQ / jOOL

jOOλ - The Missing Parts in Java 8 jOOλ improves the JDK libraries in areas where the Expert Group's focus was elsewhere. It adds tuple support, function support, and a lot of additional functionality around sequential Streams. The JDK 8's main efforts (default methods, lambdas, and the Stream API) were focused around maintaining backwards compatibility and implementing a functional API for parallelism.
http://www.jooq.org/products
Apache License 2.0
2.08k stars 167 forks source link

Add Seq<T> onEmptySwitch(Supplier<? extends Stream<? extends T>>) #179

Open lukaseder opened 8 years ago

lukaseder commented 8 years ago

As suggested by @johnmcclean-aol (https://github.com/jOOQ/jOOL/issues/177#issuecomment-170689447), an onEmptySwitch(Supplier<? extends Stream<? extends T>>) method might be useful in some situations.

Criticism:

tlinkowski commented 7 years ago

Sample implementation:

default Seq<T> onEmptySwitch(Supplier<? extends Stream<T>> supplier) {
    Supplier<? extends Stream<T>> lazy = () -> {
        Iterator<T> it = iterator();
        return it.hasNext() ? seq(it) : supplier.get();
    };
    return of(lazy).flatMap(Supplier::get);
}

As for your question about overloads, maybe different names like: onEmptyGetStream, onEmptyGetSeq, and onEmptyGetIterable?

lukaseder commented 7 years ago

Thank you for your suggestion, @tlinkowski. Hmm, I'm not sure it is correct, though. Why are you flatmapping your "lazy" stream with Supplier get? If the this stream contains 3 elements, for instance, that would call Supplier.get() 3 times.

But still, the fact that we'll need these wonky overloads to be sure we can get around type erasure, I'm still a bit hesitant to add this at all.

tlinkowski commented 7 years ago

Why are you flatmapping your "lazy" stream with Supplier get? If the this stream contains 3 elements, for instance, that would call Supplier.get() 3 times.

No, no - this Supplier::get is called only on the lazy variable, and not on the given supplier. So it's always called only once because there is only one lazy variable. But perhaphs I shouldn't have provided this implementation in such form, and I should have provided it using the proposed Seq.lazy [#302]:

default Seq<T> onEmptySwitch(Supplier<? extends Stream<T>> supplier) {
    return lazy(() -> {
        Iterator<T> it = iterator();
        return it.hasNext() ? seq(it) : supplier.get();
    });
}
lukaseder commented 7 years ago

Oh yeah, my bad. I get it. I was confused about the casing of supplier vs. Supplier :)