如何编写自定义流函数

Gra*_* D. 3 java

我知道基本的流函数,如:

mystream.filter(something).map(something)
Run Code Online (Sandbox Code Playgroud)

有没有办法让我编写自己的函数,该函数可以应用于如下流:

mystream.something()
Run Code Online (Sandbox Code Playgroud)

链接必须能够像等那样继续:

mystream.something().map()
Run Code Online (Sandbox Code Playgroud)

Lin*_*ica 7

你必须实现你自己的库,它Stream用你自己的接口包装已经存在的接口:

interface CustomStream<T> extends Stream<T> {
    CustomStream<T> something();
}
Run Code Online (Sandbox Code Playgroud)

这样,您就必须获得一个实例,Stream<T>然后将其包装到您自己的实现中interface

class CustomStreamImpl<T> implements CustomStream<T>{
    private final Stream<T> stream;

    public CustomStreamImpl(Stream<T> stream){
        this.stream = stream;
    }

    public CustomStreamImpl<T> something(){
        // your action below
        Stream<T> newStream = stream
            .filter(o -> o != null)
            .collect(Collectors.toList())
            .stream(); 
        return new CustomStreamImpl<T>(newStream);
    }

    // delegate all the other methods to private stream instance
}
Run Code Online (Sandbox Code Playgroud)

有了上面的内容,您就可以创建CustomStream如下所示的内容:

CustomStream<String> stream = new CustomStreamImpl<>(Stream.of("Hello", "World"));
Run Code Online (Sandbox Code Playgroud)

唯一不好的是,所有继承自的方法Stream都将返回 的实例Stream<T>而不是的实例CustomStream<T>

CustomStream<String> stream = new CustomStreamImpl<>(Stream.of("Hello", "World"));
// returns not CustomStream
Stream<String> newStream = stream.filter(s -> s.equals("Hello")); 
Run Code Online (Sandbox Code Playgroud)

因此,一旦您使用已给定 API 中的方法,您将“丢失”您的 customStream。为了克服这个问题,您必须覆盖界面中的方法:

interface CustomStream<T> extends Stream<T> {
    CustomStream<T> something();

    CustomStream<T> filter(Predicate<? super T> tester);
    // all the other methods
}
Run Code Online (Sandbox Code Playgroud)

然后CustomStream<T>Stream<T>调用原始API 中的方法时始终创建一个新实例:

public CustomStreamImpl<T> filter(Predicate<? super T> tester){
    return new CustomStreamImpl<T>(stream.filter(tester));
}
Run Code Online (Sandbox Code Playgroud)

最后,你能够实现你正在 chanining:

CustomStream<String> stream = new CustomStreamImpl<>(Stream.of("Hello", "World"));
stream
    .filter(s -> s.equals("Hello"))
    .something()
    .map(String::length)
    .something()
    .forEach(System.out::println); 
Run Code Online (Sandbox Code Playgroud)

我希望这可以让您深入了解如何解决您的问题