Java 8 new features

In this article we are going to discuss the most important features of Java 8.  I would be discussing these features with examples.

Functional Interfaces

Functional interfaces are interfaces with exactly one method. They can have an annotation with @FunctionalInterface. A very good example of Function Interface is that of the Comparable. It has exactly one method compareTo(obj). Functional Interfaces are used extensively used with lamda expressions.

Lambda Expressions

Lambda expression is considered to be one of the most important features of Java 8. Lamda expressions have the following syntax


parameter->body

Lambda expressions don’t need the parameters to be declared with type as that can be inferred by compiler from the value of parameter. For single parameter no parenthesis are needed. For single expression body statement no curly braces are needed. Single expression doesn’t need a return.

Lambda expressions are mostly used to create the anonymous classes of functional interfaces without declaring the class and all the boilerplate code. Here is an example that  sorts a list of Person objects on firstName.

Collections.sort(list, (person1, person2) -> person1.getFirstName().compareTo(person2.getFirstName()));

Default and static methods in interfaces

Java 8 bought a major change in inheritances from interfaces. Till Java 7, interfaces only had methods signatures and no implementation of a a method was allowed. But in Java 8, it changed and now interfaces can have a method implementation. By defining a method as default, and providing an implementation the method no longer needs to be implemented by all the implementing classes. If any class in the hierarchy has a method with same definition, then the method from class take over the functionality. That is why it is not allowed to provide a default method with same signature as any method from Object. The advantage of default methods is that the existing classes don’t need to implement this method and the existing code will compile without any changes. They even don’t need to be compiled e.g; if a jar file has a class compiled with old interface the jar doesn’t need to be created again.

In the following example, we have an existing Phone interface and we added a new feature to it. But the old phones that already are in the code base don’t need to implement this new feature. And someone invokes this new feature on an old Phone class, he would get the message.

public interface Phone {
	
   default void newFeature(){
	   System.out.println("Not found here! May be this is an old phone!");
   }
}

One thing to remember is that if a class implements two interfaces and both the interfaces have a default method with same signature, then class needs to implement this default method.

Static methods are similar to static methods in classes. Static methods are implemented in interfaces and cannot be overridden. Static methods belong to the interface.

I have written a detailed article on default and static methods. You can read it here

Iterable interface has forEach() method

This is not listed as a major feature anywhere in java 8 features. But this method is probably one of the most used methods of java 8. What this feature has done is that it has made iteration of collections more cleaner and more readable. You can a write a whole foreach in one liner if you are only having one statement in the loop.  Let us look at the example below

package com.programtalk.learn.java.beginner;

import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
//programtalk.com
public class Java8ForEach {

	public static void main(String[] args) {
		List<Integer> list =Arrays.asList(1,2,3,5,6);
		
		// normal loop
		for(Integer i : list){
			System.out.println(i);
		}
		
		// same in Java 8 forEach
		Consumer<Integer> action = new IntegerConsumer();
		list.forEach(action);
		
		// use lambda expressions, see how we do it in one liner
		list.forEach(each -> System.out.println(each));
		
	}
	
	static class IntegerConsumer implements Consumer<Integer>{

		@Override
		public void accept(Integer t) {
			System.out.println(t);
		}
		
	}
}

As we saw above that we can have a consumer class that can have the business logic of handling each of the loop variables at a separate place that the loop itself. This can be helpful in making the code more clean.

 

java.util.stream package provide new Stream API

Java collections got a new package java.util.Stream. The classes in this package provide a stream API. And supports functional-style operations on streams of elements. Stream API enables bulk operations like sequential or parallel map-readuce on Collections. Here is an example that does filtering on a large collection.  In java 7 i would be doing something like below

		List<Integer> filtered = new ArrayList<>();
		for (Integer p : bigList)  {
		    if (p  > 40) {
		    	filtered.add(p);
		    } 
		}

In java 8 with streams I can do it as below.

List<Integer> filtered = bigList.stream()
		    . filter(p -> p > 40).collect(Collectors.toList());

You can see how easy and readable it is. So the stream applies some function on the data it contains and then returns the type of collection expected. So we don’t need to handle the intermediate results.

Java Date/Time API

Java Date/Time handling  was long time due for a overhaul and in Java 8  the Java Time API tries to solve the problems developers have faced for a long time with handling date. It would be hard to talk about all the improvements but let me list some of them here

  • Date/Time API in java are immutable making usage in multithreaded code very safe. Java Date, SimpleDateFormatter and Calender classes are not Thread-safe due to being mutable.
  • Date/Time  API has classes that represent different use cases of Date and Time e.g.
    • LocalDate – represents a date without time
    • LocalTime represents time without date
    • LocalDateTime - represents a combination of date and time
    • ZonedDateTime – represents time zone specific date and time
    • Period – represents a qunatity of time in days, months, years
    • Duration -represents a quantity of time in nano seconds and seconds
  • Date/Time API supports different calendaring systems.

Concurrency improvements

Some of the concurrency improvements are listed below:

Removal of PermGen

With Java 8 we have no more PermGen.  So this configuration ‑XX:MaxPermSize is also gone. And if your moving from earlier version to java 8, you will get the warning about this property.

The metadata information is not contiguous to the java heap anymore and has moved to “Metaspace”.

Other important improvements

  • Performance improvement for the java.lang.String(byte[], *) constructor and the java.lang.String.getBytes() method.
  • Parallel Array Sorting
  • The JDBC-ODBC Bridge has been removed.
  • JDK 8 includes Java Mission Control 5.3.
  • JavaFx: The new Modena theme has been implemented in this release.
Like this post? Don’t forget to share it!

Leave a Reply

Your email address will not be published. Required fields are marked *