Java 8 New Language Features

July 6, 2019 |

Overview

This post discusses the new language features of Java 8. Java 8's release is the most awaited and is a major feature release of Java programming language.

These new features include functional interfaces, interface default method, lambda expressions, method references, Optional, and Stream API. We will also talk about some of built-in functions that implement Function Interface and the New Date and Time API.

Functional Interface

Functional Interface is an interface with single abstract method (SAM). Static or the new default method is not counted. To indicate that an interface is a Functional Interface, annotation @FunctionalInterface on class level is needed. While an interface with SAM could still function as Functional Interface (qualified as lambda expression) even if it does not have such annotation (example is AWT's ActionListener), it is recommened that it be annotated.

Some old built-in interfaces with SAM, such as Comparator and Runnable, have been annotated with @FunctionalInterface and can be used as lambda expressions

Example

We can implement above interface in two ways prior to Java 8.

  • Anonymous class
  • Concrete class

With Java 8, there is a third way to to implement an interface and that is by using Lambda Expressions

Lambda Expressions

Lambda expressions encapsulate a single unit of behavior and pass it to other code. To be able to create lambda expression, you need first a Funtional Interface. This is the reason why a Functional Interface has a single abstract method. Instead of an anonymous class, you can use lambda expression which is a concise alternative and shorthand replacement for it.

Syntax

Example

Characteristics of Lambda Expression

  1. Optional type declaration
  2. Optional parentheses

    Parentheses are required if there are multiple parameters. Parameters are separated by comma (,).

  3. Optional curly braces ({}) and optional return keyword

    Curly braces are required if body has multiple statements. return keyword is required for a function with return value if body has multiple statements. No return keyword is required if function does not return a value as in regular method.

Remember our Calculator interface? Here is how implement it using lambda expression:

Built-in Functions

Java 8 ships 43 built-in functions under java.util.function package. Thirty eight (38) of them are specialization for primitive and other functions.

The following are the basic functions:

  • Function
  • Consumer
  • Supplier
  • Predicate

Function

Function represents a function that accepts one argument and produces a result. The type parameter T represents the type of the input to the function while the second one R represents the type of result. The functonal method of this functional interface is apply(Object).

Examples

Below is an example of Function that accepts a String argument and returns a String.

This one accepts a String argument and returns an integer.

Consumer

Consumer represents an operation that accepts a single input argument and returns no result. The type parameter T represents the type of the input to the operation. The functonal method of this functional interface is accept(Object).

Examples

Both accept String input argument and returns no value.

Supplier

Supplier Represents a supplier of results. The type parameter T represents the type of results supplied by the supplier. This is a functional interface whose functional method is get().

Examples

This example returns a value of String type.

And this one returns a value of User type.

Predicate

Predicate represents a predicate (boolean-valued function) of one argument. The type parameter T represents the type of the input to the predicate. This is a functional interface whose functional method is test(Object).

Examples

To check if argument is equal to "YES" regardless of case:

To check if person is of legal age (18 and above):

Built-in Functions - Specialization

Other built-in functions are specializations for primitive types and for basic or another specialization functions.

To check all other built-in functions, please visit this Javadoc.

Existing Interface - Comparator

Comparator is an existing interface in Java since version 1.2. This interface has a single abstract method, compare(T o1, T o2), and, therefore, can be used as lambda expression similar to functions added to Java 8.

Prior to Java 8, we would use Comparator in sorting a collection the following way:

With Java 8:

Default Methods

Default methods enable you to add new functionality to the interfaces of your libraries and ensure binary compatibility with code written for older versions of those interfaces. They are interface methods that have an implementation, similar to static methods, and the default keyword at the beginning of the method signature.

Syntax

For example, default method forEach() was added to Iterable interface. This method takes a Consumer argument and performs action for each element (similar to enhanced for-each construct). List interface which extends Iterable can now be used with forEach() method:

Example

Method References

Java 8 enables you to pass references of methods or constructors via the :: keyword. Method references are compact, easy-to-read lambda expressions for methods that already have a name. They are Preferred over lambda expression if the expression does nothing but calls an existing method.

Syntax

Types of Method References

Type Example
Reference to a static method ContainingClass::staticMethodName
Reference to an instance method of a particular object containingObject::instanceMethodName
Reference to an instance method of an arbitrary object of a particular type ContainingType::methodName
Reference to a constructor ClassName::new

To be continued...