从流本身使用stream参数调用方法

时间:2018-04-23 07:29:10

标签: java java-stream

假设我们有以下情况

Collection<SomeType> someCollection = ..
Stream<SomeType> stream = someCollection.stream();
methodWithStreamArgument(stream)

是否有一个流函数可以传递一个期望流的方法引用?

例如:

Stream<OtherType> streamHandlingMethod(Stream<SomeType> stream){
  return stream
               .filter(...)
               .map(o -> new OtherType(o))
}

Stream<AnotherType> anotherStreamHandlingMethod(Stream<OtherType> stream){
  ...
}


someCollection.stream()
.call(this::streamHandlingMethod) 
.call(this::anotherStreamHandlingMethod)

我希望能够像后者一样使用它,以便它可以在一个语句中表达一个非嵌套的例如map(),filter()等的序列,而不是必须放入流再次变成一个变量或配置它丑陋如:

streamHandlingMethod(someCollection.stream()
 .filter(..)
 .map(..)
 //many other stream returning calls
)

1 个答案:

答案 0 :(得分:1)

java默认库中没有这样的方法。但是,您可以通过将现有流包装在另一个类中来创建自己的扩展。

public class MyStream<T> implements Stream<T> {
    private final Stream<T> original;

    public MyStream(Stream<T> original){
        this.original = original;
    }

    // here your own method
    public <V> MyStream<V> call(Function<? super Stream<T>, ? extends Stream<V>> mapper){
        return new MyStream<>(mapper.apply(this));
    }

    // override/implement every method like the following
    @Override
    public MyStream<T> filter(Predicate<T> predicate){
         return new MyStream<>(stream.filter(predicate));
    }

    ...
}

通过将每个调用包装到自己的实例中,此类充当Stream。因此,在调用filter方法时,original返回的流将包含在新的MyStream实例中。

所以你可以使用它,你必须最初包装一个流,如下例所示:

new MyStream<>(someCollection.stream())   // wrap with MyStream
    .call(this::methodWithStreamArgument) // execute a call
    .forEach(...);                        // terminal operation