我知道基本的流功能,例如:
mystream.filter(something).map(something)
有没有一种方法可以编写我自己的函数,该函数可以应用于像这样的流:
mystream.something()
链接必须像其他一样能够继续:
mystream.something().map()
最佳答案
您必须实现自己的库,用自己的库包装已经存在的Stream
接口:
interface CustomStream<T> extends Stream<T> {
CustomStream<T> something();
}
这样,您就必须获取
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
}
通过上面的内容,您可以创建如下的
CustomStream
:CustomStream<String> stream = new CustomStreamImpl<>(Stream.of("Hello", "World"));
唯一的坏处是,所有从
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"));
因此,一旦您使用了已经提供的API中的方法,就会“丢失”您的customStream。为了克服这个问题,您必须重写界面中的方法:
interface CustomStream<T> extends Stream<T> {
CustomStream<T> something();
CustomStream<T> filter(Predicate<? super T> tester);
// all the other methods
}
然后当调用原始
CustomStream<T>
API中的方法时,总是创建一个Stream<T>
的新实例:public CustomStreamImpl<T> filter(Predicate<? super T> tester){
return new CustomStreamImpl<T>(stream.filter(tester));
}
最终,您可以实现自己的目标:
CustomStream<String> stream = new CustomStreamImpl<>(Stream.of("Hello", "World"));
stream
.filter(s -> s.equals("Hello"))
.something()
.map(String::length)
.something()
.forEach(System.out::println);
我希望这能为您提供解决方法方面的见识