我知道基本的流函数,如:
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)
你必须实现你自己的库,它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)
我希望这可以让您深入了解如何解决您的问题