Top 15 new features in JAVA 8
1) Lambda Expressions
Java is a Object Oriented language and does not supports functional programming till JAVA 7. Functions are first class actors in functional programming language like JavaScript. They exists on their own and we can assign them to a variable and pass them as argument/parameter to the other functions. Lambda expressions adds that missing functional programming to Java.
Lambda expression is an anonymous function, We can say, it is a method without declaration.
A lambda expression in java written as syntax
- parameter -> expression body
- (argument) - > expression body
It will look like,
(arg1, arg2, ... ) -> {body}
(type1 arg1, type2 arg2, ...) -> {body}
As example:-
() -> System.out.println("Manoja Brahma");
(int x, int y) -> { return x+y; }
(String name) -> System.out.println(name);
These are structure of lambda expression
- A lambda expression can have none, one or more parameters.
- Multiple parameters are enclosed with parenthesis and separated by commas.
- Empty parenthesis represents empty set of parameters. as example () -> 10
- Type of parameter can be explicitly declared. (int x) is same as (x)
- A body of lambda expression can have none, one or more parameters.
- Body of lambda expression having single statement curly brackets are not mandatory
- But when there are multiple statements in body, it is enclosed with curly brackets must.
2) Functional Interface
There is an annotation introduced called @FunctionalInterface which can be used for compiler level errors saying interface you have annotated is not a valid functional interface.
Interface having exactly one abstract method is called functional interface. It is not mandatory to use annotation @FunctionalInterface to mark the interface functional but it is good practice to always use this annotation, so that we can not have accidentally more than one abstract methods defined inside.
If the interface annotated as functional and we are adding more than one methods to it, then compile time error is being thrown.
@FunctionalInterface
public interface MyFuncInterface {
public void method1();
// public void method2();// We can not have more than one method inside a functional interface
}
But we can define java.lang.Object class abstract methods and it is still functional interface.
@FunctionalInterface
public interface MyFuncInterface {
public void method1();
// public void method2();
public String toString();
public boolean equals(Object o);
}
3) forEach() method
In java 8, we have new way of loop over / iterate any collections like List, Set or Map.
forEach() method can be called following 2 ways because it is defined both Iterable Interface as well as Stream class
- By converting any collections to a Stream instance and calling forEach(). This is the preferable way of calling forEach() because streams are lazy and not loaded until operation is being called.
- Second way is calling forEach() method directly without obtaining Stream from the collection object.
Example:-
List<Integer> listOfNumbers = Arrays.asList(10, 20,50,30,40);
listOfNumbers.stream().forEach((i) -> { System.out.println(i); });
List<Integer> listOfStrings = Arrays.asList("Manoja", "Flora", "Swati");
listOfStrings .forEach((i) -> { System.out.prntln(i); });
4) default methods in Interfaces
Interface extended with 2 new concepts in JAVA 8, that is default and static methods in interface.In this section we are discussing about default methods, and followings are few point about it.
- Introducing default methods in interfaces is to enhance the Collections API in Java 8 to support lambda expressions.
- The difference between abstract methods and default methods is that abstract methods are required to be implemented where as default methods are not.
As example:-
interface DefaultMethodInterface {
default void defaultMethod() {
System.out.println("Default Implementaion");
}
}
class WithoutOverrideDefaultMethod implements DefaultMethodInterface {
}
class WithOverrideDefaultMethod implements DefaultMethodInterface {
@Override
public void defaultMethod(){
System.out.println("Overriden default method");
}
}
5) Static methods in interfaces
The static methods is just like default methods in Interface except we can not override them. Here is example which explains how exactly static method works and being called.
As example:-
interface StaticMethodInterface {
static void staticMethod() {
System.out.println("staticMethod inside interface");
}
}
public class StaticMethodMain implements StaticMethodInterface {
static void staticMethod() {
System.out.println("staticMethod inside class");
}
public static void main(String args[]){
staticMethod();
StaticMethodInterface.staticMethod();
}
}
6) Optional Class
Every Java developer must have seen NullPointerException at least once and null reference is the source of many problems. To overcome some of these problems, Java 8 introduced a new feature called Optional class which suppose to cure and handle the NullPointerException efficiently. Optional is container, which wrap a single value, if the value is present and that means value can be absent too.
java.util.Optional class has various utility methods ( like get(), orElse(), orElseThrow(), isPresent() etc.) to facilitate the code to check value is available or not available instead of checking null value.
To create an empty Optional
Optional <String> opt = Optional.empty();
To create a Optional object with non-null value, It will throw NullPointerException, if value is null
Optional <String> opt = Optional.value();
To create a Optional object that may hold null value
Optional <String> opt = Optional.ofNullable(value);
7) Java Stream API
This feature is to handle bulk data operations in collections. Developers are working more on collections and big data will love this feature most.
java.util.Stream is being added in java 8 to handle map/reduce like operations in collections. So that Collection interface has added 2 default methods stream() and parallelStream() to get Stream instance for sequential and parallel execution.
8) Java Time API
Java 8 introduced new Date and Time APIs to handle date & time operations efficiently. There are few draw backs was available in previous JDK versions described below and that has been taken cared efficiently in JAVA 8.
- Thread safe:- In previous versions of Jave Date and Time object was not Thread Safe.
- Difficult to handle :- Each developer was struggling to fix the Date and Time related issues by doing lots of coding.
- Poor design:- Lack of methods to do operations on Data and Time object hence there are few new methods are introduced to help developers.
Example:-
To get the current date and time
LocalDateTime currentTime = LocalDateTime.now();
System.out.println("Current DateTime: " + currentTime);
To get the today's date
LocalDate today = LocalDate.now();
System.out.println("Current date: " + today);
Two special classes introduced to handle the time differences
- Period − This class used to find the date based amount of time.
- Duration − This class is used to find the time based amount of time.
9) Collection API improvements
Java collection framework updated to support lambda expression and streams. There is a performance improvement in HashMap because there was lots of collision in keys. To improve performance in hash bin java 8 is using balanced trees instead of linked list for containing large number of colliding keys.
This change in jdk8 applies only to HashMap, LinkedHashMap, and ConcurrentHashMap.
Anyway we have already seen the forEach() and Stream API for collections. Here are some new methods introduced in Collection
- spliterator() :- return Spliterator instance, that can be used to traverse elements sequentially
- Map replaceAll(), compute and merge() methods
10) Concurrency API improvements
There are some concurrent API enhancement happened in JAVA 8, which is going to thrill all the java developers.
- The java.util.concurrent package added 2 new interfaces and 4 new classes
- CompletableFuture.AsynchronousCompletionTask
- CompletionStage<T>
- CompletableFuture<T>
- ConcurrentHashMap.KeySetView<K,V>
- CountedCompleter<T>
- CompletionException
- New classes in java.util.concurrent.atomic
- LongAdder
- LongAccumulator
- DoubleAccumulator
- DoubleAdder
- Few changes to existing APIs like ConcurrentHashMap introduced over 30 new methods and new methods in ForkJoinPool class
- New class java.util.concurrent.locks.StampedLock
11) NIO features and improvements
First lets have a look into java.nio.Files,
- Files.list() :- Returns lazy stream of files
- Files.walk() :- can walk through the whole file and returns lazy stream of all descendant files.
- Files.lines():- read line by line from a file
- Files.find() :- Returns stream that is lazily populated with path by searching for files.
There are several improvements to java.nio.charset.Charset class and extended version of charset implementation.
- Decrease in the size of jre/lib/charset.jar file
- New SelectorProvider implementation
12) Miscellaneous Core API improvements
There are few new stuffs got added and few got removed too in java 8.
Added
- jjs command to invoke new javascript engine (Nashorn)
- min(), max() and sum() in wrapper classes (Integer, Double and Long)
- jdeps command to analyze class files
- logicalAnd(), logicalOr() and logicalXor() methods in Boolean class.
- several utility methods in Math class
Removed
- PermGen memory space has been removed
- JDBC-ODBC has been removed
13) String Joiner
Another text utility feature introduced in jdk 8 is java.util.StringJoiner class. Even we can add suffix and prefix to the String by using the overloaded constructor of StringJoiner.
Examples:-
1)
final StringJoiner sj = new StringJoiner(",");
sj.add("Manoja");
sj.add("Flora");
sj.add("Swati");
final String names = sj.toString();
System.out.println(names); // Manoja, Flora, Swati
2)
final StringJoiner sj = new StringJoiner("/", "Prefix-", "-Postfix");
sj.add("Manoja");
sj.add("Flora");
sj.add("Swati");
final String name = sj.toString();
System.out.println(name);// Prefix-Manoja/Flora/Swati-Postfix
Note:- StringJoiner internally used by String.join()
final String names = String.join(",", "Manoja", "Flora", "Swati");
System.out.println(names); // Manoja, Flora, Swati
14) Type Annotation
On earlier versions of java we are only able to use annotations in declaration but now In JAVA 8 developer is allowed to write annotations many places like declarations, generics, type casting and constructor.
Declaration
@NotNull String name = "manoja";
Generics
List <@NotNull String> listString = ...
Type casting
String name = (@NonNull String) myObject;
Constructor
new @Interned MyObject()
Even we can use annotaitons for
- Inheritance
- Throwing exceptions
- Instanceof statement
- Nested Types and constructor
15) Nashorn: A next generation Javascript Engine in JVM
JAVA 8 introduces a new command line tool jjs to execute java script code at console for Nashorn engine.
Go to jdk1.8 home directory, then verify jjs in interactive mode.
C:\jdk1.8.0_102>jjs
jjs> print ('hello')
hello
jjs> quit()
C:\jdk1.8.0_102>
How to call javascript in java?
final ScriptEngine se = new ScriptEngineManager().getEngineByName("nashorn");
se.eval("print('Hello World');");