The IBM Streams’ Java Application API (introduction) supports processing of streams using functional transformations. A functional transformation, when applied to a stream, creates a new stream by performing a function on each tuple in the original stream. With Java 8, it becomes simpler to implement such transformations.

Functions using Anonymous classes (Java 7)

With Java 7, one typically uses an anonymous class, for example, filtering a stream of String objects to remove short strings is coded like this:

1   TStream<String> strings = ...;
2   strings = strings.filter(new Predicate() {
3       private static final long serialVersionUID = 1L;
4       @Override
5       public boolean test(String tuple) {
6          return tuple.length() > 20;
7   }});

The actual logic (tuple.length() > 20) is hidden on line 6, surrounded by four and a half lines of boiler plate code.
While an IDE like Eclipse, through code completion, helps with creating the boiler plate code, the resulting source is not that readable.

Functions using Lambda Expressions (Java 8)

IBM Streams 4.0.1 and later support Java 8 which then allows lambda expressions to be used for functional programming. This greatly simplifies our filter example to:

1    TStream<String> strings = ...;
2    strings = strings.filter(tuple -> tuple.length() > 20);

Much simpler, all the boiler plate code has gone, leaving the focus on the actual application logic.

Functions using Method References (Java 8)

In addition to lambda expressions, Java 8 introduces method references, so that a method reference can be used as a function (functional interface in Java 8 terms).
Changing the example, we now are transforming a stream of BigDecimal values to their engineering representation in stream of strings , using lambda expressions this would be:

1    TStream<BigDecimal> decimals = ...
2    strings = decimals.transform(decimals.transform(tuple -> tuple.toEngineeringString(), String.class);

With a method reference the method’s receiver is implied, so that the example becomes

1    TStream<BigDecimal> decimals = ...
2    strings = decimals.transform(decimals.transform(BigDecimal::toEngineeringString(), String.class);

This works well with filters where the object’s class has some boolean method that one can filter on, for example a telco application might have a Call object that has a wasDropped() method, and can use Call::wasDropped to create a stream of just dropped calls for real-time failure analysis.

Join The Discussion