What is the (kind of) inverse operation to Java's Stream.flatMap()?

前端 未结 5 873
别那么骄傲
别那么骄傲 2021-02-19 05:40

The Stream.flatMap() operation transforms a stream of

a, b, c

into a stream that contains zero or more elements for each input el

5条回答
  •  逝去的感伤
    2021-02-19 06:15

    This is what I came up with:

    interface OptionalBinaryOperator extends BiFunction> {
      static  OptionalBinaryOperator of(BinaryOperator binaryOperator,
              BiPredicate biPredicate) {
        return (t1, t2) -> biPredicate.test(t1, t2)
                ? Optional.of(binaryOperator.apply(t1, t2))
                : Optional.empty();
      }
    }
    
    class StreamUtils {
      public static  Stream reducePartially(Stream stream,
              OptionalBinaryOperator conditionalAccumulator) {
        Stream.Builder builder = Stream.builder();
        stream.reduce((t1, t2) -> conditionalAccumulator.apply(t1, t2).orElseGet(() -> {
          builder.add(t1);
          return t2;
        })).ifPresent(builder::add);
        return builder.build();
      }
    }
    

    Unfortunately, I did not have the time to make it lazy, but it can be done by writing a custom Spliterator delegating to stream.spliterator() that would follow the logic above (instead of utilizing stream.reduce(), which is a terminal operation).


    PS. I just realized you wanted conversion, and I wrote about conversion. If you can first map from T to U, and then use the function above, then that's it (even if it's suboptimal).

    If it's something more complex, the kind of condition for reducing/merging would need to be defined before proposing an API (e.g. Predicate, BiPredicate, BiPredicate, or maybe even Predicate>).

提交回复
热议问题