我知道基本的流函数,例如:
mystream.filter(something).map(something)
我有没有办法编写自己的函数,可以应用于如下流:
mystream.something()
链接必须能够像等一样继续:
mystream.something().map()
您必须实现自己的Library,它将已经存在的Stream
接口与您自己的接口包装在一起:
interface CustomStream<T> extends Stream<T> {
CustomStream<T> something();
}
这样,您就必须获取Stream的实例
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的实例
CustomStream<String> stream = new CustomStreamImpl<>(Stream.of("Hello", "World"));
// returns not CustomStream
Stream<String> newStream = stream.filter(s -> s.equals("Hello"));
因此,一旦你使用了已经给出的API中的方法,你就会“丢失”你的自定义流。为了克服这个问题,你必须覆盖界面中的方法:
interface CustomStream<T> extends Stream<T> {
CustomStream<T> something();
CustomStream<T> filter(Predicate<? super T> tester);
// all the other methods
}
然后始终创建一个新的CustomStream实例
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);
我希望这能让你了解如何解决你的问题
不,这是不可能的。
这将需要扩展Stream接口。
正如Lino所提到的,您可以定义自己的子接口(或实现类)来添加这些新方法。
interface MyStream<T> extends Stream<T> {
public MyStream<T> something();
}
然后,您可能希望将Stream对象包装到MyStream对象中。