String output = names.stream()
.sorted((name1, name2) -> {
String[] parts1 = name1.split(" ");
String lastName1 = parts1[parts1.length - 1];
String[] parts2 = name2.split(" ");
String lastName2 = parts2[parts2.length - 1];
return lastName2.compareTo(lastName1);
})
.map(name -> {
String[] parts = name.split(" ");
return parts[parts.length - 1];
})
.filter(lastName -> lastName.length() >= 5)
.reduce("", (accumulator, element) -> accumulator + element + ", ");
System.out.println("result: " + output);
This will concatenate all the strings together, joined by a comma. (We’ll have a trailing comma that we could drop off the end.)
reduce
gives us an interesting look at a slightly more advanced area of streams. Consider if you wanted to count the string characters and return an integer value. How could you do that? The return value of reduce
would want to be an integer, but the accumulator
and element
args are strings. I’ll leave that for an exercise, with this Stack Overflow question as one lead, and my introduction to Java stream gatherers as another.
Reusing operations
We’ve had a pretty good look at the way it feels to use and compose some of the most important Java functional operations. Another important facet is code reuse. Say you needed to use that fancy string sorter in several places. In Java, we could create a functional interface to share that operation: