Reputation: 60
I'm looking for a readable way to reuse a chain of stream operations.
The idea is that I have a certain sequence of actions that I want to apply to several streams in between other operations. The other operations are not identical between streams.
So, for example, for every stream, I want to change the case of a String, trim it, nullify empty Strings and then filter out nulls, and lastly, eliminate duplicates, like this:
In both cases, I do this sequence of actions:
.map( String::trim ).map( Strings::emptyToNull ).filter( Objects::nonNull ).distinct()
I currently duplicate that chain and put it between other actions for multiple streams:
myStream1.doSomeStuff().map( String::trim ).map( Strings::emptyToNull ).filter( Objects::nonNull ).distinct().doOtherStuff();
myStream2.doSomethingElse().map( String::trim ).map( Strings::emptyToNull ).filter( Objects::nonNull ).distinct().doSomethingElseStill();
Is there a good way to avoid rewriting that piece of code? Obviously, it's possible for the two map() actions, but is there a way for this combination of actions?
Upvotes: 2
Views: 549
Reputation: 21965
You could wrap your Stream<String>
in a function
public Stream<String> trimAndFilterOutEmptyStringsAndGetDistinctElements(Stream<String> stream) {
return stream.map(String::trim)
.map(Strings::emptyToNull) // or use not(String::isEmpty) like suggested below
.filter(Objects::nonNull)
.distinct();
}
Which could be used like this
Stream<String> myStream1DownStream = trimAndFilterOutEmptyStringsAndGetDistinctElements(myStream1);
Stream<String> myStream2DownStream = trimAndFilterOutEmptyStringsAndGetDistinctElements(myStream2);
myStream1DownStream.doOtherStuff();
myStream2DownStream.doSomethingElseStill();
BTW I'd use
.filter(Predicate.not(String::isEmpty))
instead of
.map(Strings::emptyToNull)
.filter(Objects::nonNull)
There is a more questionnable way, it is to use Lombok's @ExtensionMethod
experimental feature. I would not use it in production
You'll then be able to extend the functionalities of the Stream
class with custom methods
public class Extensions {
public static Stream<String> trimAndFilterOutEmptyStringsAndGetDistinctElements(Stream<String> stream) {
return stream.map(String::trim)
.map(Strings::emptyToNull) // or use not(String::isEmpty) like suggested
.filter(Objects::nonNull)
.distinct();
}
}
The usage is the following
myStream1.trimAndFilterOutEmptyStringsAndGetDistinctElements()
.doOtherStuff();
More info
Upvotes: 5