JAVA 8

Poornima Vithanage
5 min readMay 30, 2021

Java 8 is the major release for Java, which contains more features, enhancements and bug fixes to improve efficiency to develop and run Java programs. This was very much useful for developers to give adequate time for testing.

Features of Java 8

Functional Interface vs Lambda Expression

Lambda expression is the simplest way to write a method. It can avoid multiple boilerplate. In lambda expression there’s no access modifiers, no return type, no method name.

The Lambda expression is used to provide the implementation, which has functional interface. An Interface which has Single Abstract Method (SAM) is called as Functional Interface. Java provides an annotation @FuntionalInterface, which is used to declare an interface functional interface.

Java lambda expression has 3 components

1. Argument — list: It can be empty or non-empty as well.

2. Arrow — token: It is used to link arguments-list and body of expression.

3. Body: It contains expressions and statements for lambda expression.

Let’s learn how parameter syntax behaves in lambda expression!!!!

No Parameter Syntax

() -> {

//Body of no parameter lambda

}

One Parameter Syntax

(p1) -> {

//Body of single parameter lambda

}

Two Parameter Syntax

(p1,p2) -> {

//Body of multiple parameter lambda

}

Let’s first implement without lambda expression.

Using Lambda expression,

The compiler automatically returns the value if the body has a single expression to return the value. Curly braces are required to indicate that expression returns a value.

Some of useful Java8 functional interfaces are Consumer, Supplier, Function and Predicate.

Lambda expression are the way through which we can visualize functional programming in the Java object oriented world. Objects are the base of Java Programming language and we can never have a function without an object, that’s why Java language provide support for using Lambda expressions only with functional interfaces.

Since there is only one abstract function in the functional interfaces, there is no confusion in applying the lambda expression to the method. It’s syntax is (argument) -> (body).

Here are some examples of lambda expressions.

Java Stream API and Date Time API

Java Stream API provides a functional approach to processing bounded streams of objects.

What is Java Stream?

It is capable of internal iteration of its elements and it provides functionality for processing its elements during iteration.

A stream is not a data structure instead; it takes input from the collections, Arrays or I/O channels.

Streams do not change the original data structure; they only provide the pipelined methods.

Each intermediate operation is lazily executed and returns a stream as a result; hence, various intermediate operations can be pipelined. Terminal operations mark the end of the stream and return the result.

Intermediate Operations

map: The map method is used to returns a stream consisting of the results of applying the given function to the elements of this stream.

filter: The filter method is used to select elements as per the Predicate passed as argument.

sorted: The sorted method is used to sort the stream.

Terminal Operations

collect: The collect method is used to return the result of the intermediate operations performed on the stream.

forEach: The forEach method is used to iterate through every element of the stream.

reduce: The reduce method is used to reduce the elements of a stream to a single value. The reduce method takes a Binary Operator as a parameter.

Date Time API

Why?

Immutability — All the classes in the new Date Time API are immutable and good for multithreaded environments.

Separation of concerns — New API are human readable. It defines separate classes for Date, Time, DateTime, TimeStamp, TimeZone, etc;

Clarity — The methods are clearly defined and perform the same action in all the classes. For example, to get the current instance we have now() method. And also, format() and parse() method define in all these classes rather than having a separate class for them.

forEach() method in iterable interface

Java8 has introduced forEach method in java.lang.iterable interface so that while writing code we focus on business logic. The forEach method takes java.util.function.Consumer object as an argument, so it helps in having the business logic at a separate location that we can reuse. Let’s see forEach example.

Default and Static methods in Interfaces

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.

A static method is a method that is associated with the class in which it is defined rather than with any object. Every instance of the class shares its static methods.

Static method in interface are part of the interface class can not implement or override it whereas class can override the default method.

Collection API improvements

There are some new methods were introduced in collection API in Java8

1. Iterator default method forEachRemaining(Consumer action) to perform the given action for each remaining element until all elements have been processed or the action throws an exception.

2. Collection default methods removeIf(Predicate filter) to remove all the elements of this collection that satisfy the given predicate.

3. Collection spliterator() method returning Spliterator instance that can be used to traverse elements sequentially or parallel.

4. Map replaceAll(), compute(), merge() methods.

5. Performance improvement for HashMap class with Collisions.

Here I have given one example, as we know Map in order, it will give more struggle to get it sorted. Now Map Interface added default methods, which gives you comparators different styles like comparingByKey, comparingByValue.

Concurrency API improvements

Some important concurrent API enhancements are,

1. ConcurrentHashMapcompute(), forEach(), forEachEntry(), forEachKey(), forEachValue(), merge(), reduce() and sort() methods.

2. CompletableFuture that may explicitly completed (setting its value and status).

3. Executors newWorkStealingPool() method to create a work-stealing thread pool using all available processors as its target parallelism level.

Java IO improvements

Reading a file before Java8

Prior to Java 7 some of the classes available to read files included ‘BufferedReader’, ‘FileReader’ and ‘Scanner’. The disadvantage of these? You need to write a ‘while loop’ to reach each line from the file, which can be pretty time consuming.

Java 7 added the ‘java.nio.file.Files’ class which has several utility methods for performing all-kinds of File IO operations. This was a pretty handy workaround and some of the methods in the class such as ‘Files.readAllBytes’ and ‘Files.readAllLines’ can both be used for reading a file. It’s key to note that these methods don’t require a ‘while loop’ and instead help to directly read the contents of a file into a ‘byte array’ or ‘String List’ respectively.

Some important enhancements in Java IO,

1. Files.list(Path dir) that returns a lazily populated stream, the elements of which are the entries in the directory.

2. Files.lines(Path path) that read all lines from a file as stream.

3. Files.find() that returns a stream, that is lazily populated with path by searching for files in a file tree rooted at a given starting file.

4. BufferedReader.lines() that returns a stream, the elements of which are lines read from this BufferedReader.

Conclusion

Java 8 was a big release for Java, with syntax changes, new methods and types, and under-the-cover changes that will help your application even if you don’t use the new language features. Java 7 is no longer supported by Oracle, so organizations are being pushed to migrate to Java 8. The good news is that Java 8 has many benefits for your business, your existing application, and for developers looking to improve their productivity.

--

--