You'd have to implement your own Library which is wrapping the already existant Stream
interface with your own:
interface CustomStream<T> extends Stream<T> {
CustomStream<T> something();
}
That way you then have to aquire an instance of Stream<T>
and then wrap it into an implementation of your own 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
}
With the above you then could create a CustomStream
like the following:
CustomStream<String> stream = new CustomStreamImpl<>(Stream.of("Hello", "World"));
The only bad thing is that all the methods inherited from Stream
will return an instance of Stream<T>
and not one of CustomStream<T>
.
CustomStream<String> stream = new CustomStreamImpl<>(Stream.of("Hello", "World"));
// returns not CustomStream
Stream<String> newStream = stream.filter(s -> s.equals("Hello"));
So once you use a method from the already given API you'll "lose" your customStream. To overcome this you'd have to override the methods in your interface:
interface CustomStream<T> extends Stream<T> {
CustomStream<T> something();
CustomStream<T> filter(Predicate<? super T> tester);
// all the other methods
}
and then create always a new Instance of CustomStream<T>
when a method from the original Stream<T>
API is called:
public CustomStreamImpl<T> filter(Predicate<? super T> tester){
return new CustomStreamImpl<T>(stream.filter(tester));
}
Finally you're able to achieve you're 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);
I hope this gives insight on how to approach your problem