- Interface Advantages / Java 8 Default Methods
- Code as Data in Java 8: Lambda Expressions / Installing Java 8
Code as Data in Java 8: Lambda Expressions
Earlier, we saw the use of Java interfaces and the corresponding implementation class code. In one sense, the combination of interfaces and classes can be a bit too heavyweight, particularly when a given interface consists of just one abstract method.
In general, an interface consisting of just one method is a functional interface. In Java 8, this can be implemented as a lambda expression. To make this more concrete, consider the Listing 11 example, which is based on those at the Java Tutorials.
Listing 11: Lambda expressions in action
public class Calculator { interface IntegerMath { int operation(int a, int b); } interface RealMath { double operation(double a, double b); } public int operateBinary(int a, int b, IntegerMath op) { return op.operation(a, b); } public double operateBinary(int a, int b, RealMath op) { return op.operation(a, b); } public static void main(String... args) { Calculator myApp = new Calculator(); IntegerMath addition = (a, b) -> a + b; IntegerMath subtraction = (a, b) -> a - b; RealMath division = (a, b) -> a / b; System.out.println("137 / 12 = " + myApp.operateBinary(137, 2, division)); System.out.println("40 + 2 = " + myApp.operateBinary(40, 2, addition)); System.out.println("20 - 10 = " + myApp.operateBinary(20, 10, subtraction)); } }
Listing 11 defines two interfaces: IntegerMath and RealMath. Each interface contains a single method called operation. The implementation of operation is itself specified by an instance of the associated interface; this is done by using a lambda expression.
The use of lambda expressions obviates the need for a class definition or an anonymous class instance. The lambda is illustrated as the right side of the following statement:
IntegerMath addition = (a, b) -> a + b;
The addition instance is then passed as a parameter into the invocation of the operateBinary method:
myApp.operateBinary(40, 2, addition)
In effect, the above line is an example of passing code as data. This is powerful and more lightweight than passing an object reference or an anonymous class instance. It's also extensible: If you need real number arithmetic, you just define another interface:
interface RealMath
The implementation of the above interface is supplied using a lambda expression:
RealMath division = (a, b) -> a / b;
Again, the division is invoked as follows:
myApp.operateBinary(137, 2, division)
This is similar to the use of lambda functions in Python, which in turn is similar to the functional programming use case for lambda functions. All of which makes me think that the mainstream languages are increasingly beginning to cross-fertilize each other with allied concepts.
Installing Java 8
Getting up and running with Java 8 is easy. If you're running Ubuntu, just run the following commands:
sudo apt-get purge openjdk* sudo apt-get install python-software-properties sudo add-apt-repository ppa:webupd8team/java sudo apt-get update sudo apt-get install oracle-java8-installer java -version
The java -version command should produce output similar to the following:
java version "1.8.0" Java(TM) SE Runtime Environment (build 1.8.0-b132) Java HotSpot(TM) 64-Bit Server VM (build 25.0-b70, mixed mode)
If you see this output, you're good to go with Java 8.
Conclusion
Java 8 provides many convenient new features. Extensible default-method interfaces help to reduce code bloat when adding to legacy interfaces. This use of default interface code is a useful implementation of information hiding at the code level; in other words, not all interface implementations will necessarily need the new methods. The new default code in the interface is used on an as-needed basis only.
Functional programming is used extensively in the financial services industry because this style of programming has less reliance on state propagation than might be the case in the telecommunications industry. Java 8 now provides lambda expressions as a means of implementing lightweight class-free interfaces. In effect, this allows for code to be passed around as data. Lambda expressions also allow for more concise code.
It's likely that future versions of Java will include other, similar features.