Java 8 Lambda Expression
What is a Java Functional Interface?In Java, a functional interface is basically an interface with a single abstract method. This kind of interfaces are also known as SAM (Single Abstract Method) types.
In Java, the lambda expressions are represented as objects, and so they must be bound to a particular object type known as a functional interface. This is called the target type.Since a functional interface can only have a single abstract method, the types of the lambda expression parameters must correspond to the parameters in that method, and the type of the lambda body must correspond to the return type of this method. Additionally, any exceptions thrown in the lambda body must be allowed by the throws clause of this method in the functional interface.
Javascript code can either be evaluated directly by passing javascript code as a string as shown above. Or you can pass a file reader pointing to your .js script file:
In Java, the lambda expressions are represented as objects, and so they must be bound to a particular object type known as a functional interface. This is called the target type.Since a functional interface can only have a single abstract method, the types of the lambda expression parameters must correspond to the parameters in that method, and the type of the lambda body must correspond to the return type of this method. Additionally, any exceptions thrown in the lambda body must be allowed by the throws clause of this method in the functional interface.
Simple example to demonstrate usage of lambda expressions for SAM(single abstract interface) interfaces.
Using Lamba expression for Custom Interface with default method
Implementation of interface
Traversing Collection using foreach of Iterable interface
Using Consumer Interface
Application of Predicate Interface
Java 8 Method References
If we only use a method of an object in another method, we still have to pass the full object as an argument. Wouldn't it be more practical to just pass the method as an argument?
A method reference is the shorthand syntax for a lambda expression that executes just ONE method. Here's the general syntax of a method reference:
First of all, a method reference can't be used for any method. They can only be used to replace a single-method lambda expression.
So to use a method reference, you first need a lambda expression with one method. And to use a lambda expression, you first need a functional interface, an interface with just one abstract method.
Using Lamba expression for Custom Interface with default method
Implementation of interface
Traversing Collection using foreach of Iterable interface
Using Consumer Interface
Application of Predicate Interface
Java 8 Method References
If we only use a method of an object in another method, we still have to pass the full object as an argument. Wouldn't it be more practical to just pass the method as an argument?
A method reference is the shorthand syntax for a lambda expression that executes just ONE method. Here's the general syntax of a method reference:
First of all, a method reference can't be used for any method. They can only be used to replace a single-method lambda expression.
So to use a method reference, you first need a lambda expression with one method. And to use a lambda expression, you first need a functional interface, an interface with just one abstract method.
There are four types of method references:
The Stream interface is defined in java.util.stream package. Starting from Java 8, the java collections will start having methods that return Stream. This is possible because of another cool feature of Java 8, which is default methods. Streams can be defiled as a sequence of elements from a source that supports aggregate operations.
- A method reference to a static method.
- A method reference to an instance method of an object of a particular type.
- A method reference to an instance method of an existing object.
- A method reference to a constructor.
Java8 Interface Default MethodFor creating a default method in java interface, we need to use “default” keyword with the method signature. For example,
package com.journaldev.java8.defaultmethod; public interface Interface1 { void method1(String str); default void log(String str){ System.out.println("I1 logging::"+str); } }
Note-:
- If any class in the hierarchy has a method with same signature, then default methods become irrelevant. A default method cannot override a method from java.lang.Object. The reasoning is very simple, it’s because Object is the base class for all the java classes. So even if we have Object class methods defined as default methods in interfaces, it will be useless because Object class method will always be used. That’s why to avoid confusion, we can’t have default methods that are overriding Object class methods.
- Java interface default methods are also referred to as Defender Methods or Virtual extension methods.
Java8 Interface Static MethodJava interface static method is similar to default method except that we can’t override them in the implementation classes. This feature helps us in avoiding undesired results incase of poor implementation in implementation classes. Let’s look into this with a simple example.
package com.journaldev.java8.staticmethod; public interface MyData { default void print(String str) { if (!isNull(str)) System.out.println("MyData Print::" + str); } static boolean isNull(String str) { System.out.println("Interface Null Check"); return str == null ? true : "".equals(str) ? true : false; } }
Note-:
Java8 Stream API- Java interface static method is part of interface, we can’t use it for implementation class objects.
- Java interface static method helps us in providing security by not allowing implementation classes to override them.
The Stream interface is defined in java.util.stream package. Starting from Java 8, the java collections will start having methods that return Stream. This is possible because of another cool feature of Java 8, which is default methods. Streams can be defiled as a sequence of elements from a source that supports aggregate operations.
The source here refers to a Collection, IO Operation or Arrays who provides data to a Stream. Stream keeps the order of the data as it is in the source. Just like functional programming languages, Streams support Aggregate Operations. The common aggregate operations are filter, map, reduce, find, match, sort. These operations can be executed in series or in parallel.
The Streams also support Pipelining and Internal Iterations. The Java 8 Streams are designed in such a way that most of its stream operations returns Streams only. This help us creating chain of various stream operations. This is called as pipelining. The pipelined operations looks similar to a sql query.
In Java, we traditionally use for loops or iterators to iterate through the collections. These kind of iterations are called as external iterations and they are clearly visible in the code. Java 8 Stream operations has methods like foreach, map, filter, etc. which internally iterates through the elements. The code is completely unaware of the iteration logic in the background. These kind of iterations are called as internal iterations.
There is nothing special about this code. This is a traditional Java external iterations example. Now, have a look at the below code. This line is doing exactly the same thing but we can't see any iteration logic here and hence it is called as internal iterations.
For better understanding of Java 8 Stream API:https://dzone.com/articles/understanding-java-8-streams-1
Java 8 Optional class
The Streams also support Pipelining and Internal Iterations. The Java 8 Streams are designed in such a way that most of its stream operations returns Streams only. This help us creating chain of various stream operations. This is called as pipelining. The pipelined operations looks similar to a sql query.
In Java, we traditionally use for loops or iterators to iterate through the collections. These kind of iterations are called as external iterations and they are clearly visible in the code. Java 8 Stream operations has methods like foreach, map, filter, etc. which internally iterates through the elements. The code is completely unaware of the iteration logic in the background. These kind of iterations are called as internal iterations.
For better understanding of Java 8 Stream API:https://dzone.com/articles/understanding-java-8-streams-1
Java 8 Optional class
Optional is a new type in Java 8 that wraps either a value or null, to represent the absence of a value. The main benefit is that it your code can now gracefully handle the existence of null values, as you don’t have to explicitly check for nulls anymore.
Optional is a monadic type you can map functions into, that will transform the value inside the Optional
Optional is a monadic type you can map functions into, that will transform the value inside the Optional
See-:
Java8 Nashorn engine
The Nashorn Javascript Engine is part of Java SE 8 and competes with other standalone engines like Google V8 (the engine that powers Google Chrome and Node.js). Nashorn extends Javas capabilities by running dynamic javascript code natively on the JVM.
A simple HelloWorld in java code looks like this:
ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
engine.eval("print('Hello World!');");
In order to evaluate javascript code from java, you first create a nashorn script engine by utilizing the javax.script package already known from Rhino (Javas legacy js engine from Mozilla).Javascript code can either be evaluated directly by passing javascript code as a string as shown above. Or you can pass a file reader pointing to your .js script file: