Functional interfaces:
It specifies only one method.
In Java JDK8 it is possible to specify the default behaviour of the method declared in interface.Then it is called default method.
The method getValue( ) is implicitly abstract and it is the only method defined by Mynumber.
Mynumber is a functional interface and its function is defined by getValue( ).
Here is an example of a functional interface:
interface MyNumber {
double getValue\(\);
}
Lambda expression is not executed on its own,it forms the implementation of the abstract method defined by its functional interface
that specifies its target type.One of the Context is created when lambda expression is assigned to a functional interface reference.
The below syntax of the
// Call getValue(), which is implemented by the previously assigned
// lambda expression.
System.out.println("myNum.getValue());
The type and number of the lambda expression’s parameters must be compatible with the method’s parameters.
The return types must be compatible and any exceptions thrown by the lambda expression must be acceptable to the method.
Block Lambda Expressions:
The body of the lambdas shown in the preceding examples consist of a single expression.
These types of lambda bodies are referred to as expression bodies and lambdas that have expression bodies are called expression lambdas.
In a lambda body the code on the right side of the lambda operator must consist of single expression.
In some case the single expression is not helpful so in that case java helps in code of right side of lambda operator that consist of
block of code which contain more than one statement.These type of lambda known as block body.
When return statement occurs within a lambda expression, it simply causes a return from the lambda.
Example: (String Function)
// A block lambda that reverses the characters in a string.
interface StringFunc {
String func(String n);
}
class BlockLambdaDemo2 {
public static void main(String args[])
{
// This block lambda reverses the characters in a string.
StringFunc reverse = (str) -> {
String result = "";
int i;
for(i = str.length()-1; i >= 0; i--)
result += str.charAt(i);
return result;
};
System.out.println("Lambda reversed is " + reverse.func("Lambda"));
System.out.println("Expression reversed is " + reverse.func("Expression"));
}
}
In this example, the functional interface StringFunc declares the func( ) method.
This method takes a parameter of type String and has a return type of String.
Thus, in the reverse lambda expression the type of str is inferred to be String.
Generic Functional Interfaces:
A lambda expression, itself, cannot specify type parameters.
The functional interface associated with a lambda expression can be generic.
Both defined a method called func( ) that took one parameter and returned a result.
Example:
// A generic functional interface.
interface SomeFunc<T> {
T func(T t);
}
class GenericFunctionalInterfaceDemo {
public static void main(String args[])
{
// Use a String-based version of SomeFunc.
SomeFunc<String> reverse = (str) -> {
String result = "";
int i;
for(i = str.length()-1; i >= 0; i--)
result += str.charAt(i);
return result;
}
System.out.println("Lambda reversed is " +
reverse.func("Lambda"));
System.out.println("Expression reversed is " +
reverse.func("Expression"));
// Now, use an Integer-based version of SomeFunc.
SomeFunc<Integer> factorial = (n) -> {
int result = 1;
for(int i=1; i <= n; i++)
result = i * result;
return result;
}
System.out.println("The factoral of 3 is " + factorial.func(3));
System.out.println("The factoral of 5 is " + factorial.func(5));
}
}
T specifies both the return type and the parameter type of func( ).
The SomeFunc interface is used to provide a reference to two different types of lambdas.
The first uses type String &The second uses type Integer.
Passing Lambda Expressions as Arguments:
It provides the expression only for target type and one of these is passed as an argument.
It provides it gives you a way to pass executable code as an argument to a method
This greatly enhances the power of java.
These program passes and block the lambda function.
Example:
outStr = stringOp((str) -> {
String result = "";
int i;
for(i = 0; i < str.length(); i++)
if(str.charAt(i) != ' ')
result += str.charAt(i);
return result;
}, inStr);
- These block lambda defines the reverse of the string which is reference to the string function(StringFunc) instances.
Lambda Expressions and Exceptions:
- Lambda exception can throw an exception.however if it throws the checked exception then that exceptions must be compatible to exception listed in the throws clause of the exception.
Example:
// Throw an exception from a lambda expression.
interface DoubleNumericArrayFunc {
double func(double[] n) throws EmptyArrayException;
}
class EmptyArrayException extends Exception {
EmptyArrayException() {
super("Array Empty");
}
}
class LambdaExceptionDemo {
public static void main(String args[]) throws EmptyArrayException
{
double[] values = { 1.0, 2.0, 3.0, 4.0 };
// This block lambda computes the average of an array of doubles.
DoubleNumericArrayFunc average = (n) -> {
double sum = 0;
if(n.length == 0)
throw new EmptyArrayException();
for(int i=0; i < n.length; i++)
sum += n[i];
return sum / n.length;
};
System.out.println("The average is " + average.func(values));
// This causes an exception to be thrown.
System.out.println("The average is " + average.func(new double[0]));
}
}
The first call to average.func( ) returns the value 2.5.
The second call, which passes a zero-length array, causes an EmptyArrayException to be thrown.
Remember,the inclusion of the throws clause in func( ) is necessary. Without it, the program willnot compile with lambda expression with func().
Lambda Expressions and Variable Capture:
- Variables defined by the enclosing scope of a lambda expression are accessible within the lambda expression.
Examples:
// An example of capturing a local variable from the enclosing scope.
interface MyFunc {
int func(int n);
}
class VarCapture {
public static void main(String args[])
{
// A local variable that can be captured.
int num = 10;
MyFunc myLambda = (n) -> {
// This use of num is OK. It does not modify num.
int v = num + n;
// However, the following is illegal because it attempts
// to modify the value of num.
// num++;
return v;
};
// The following line would also cause an error, because
// it would remove the effectively final status from num.
// num = 9;
}
}
Constructor References:
- Similar to create references to methods here create references to constructors.
General form:
classname::new
Example:
// Demonstrate a Constructor reference.
// MyFunc is a functional interface whose method returns
// a MyClass reference.
interface MyFunc {
MyClass func(int n);
}
class MyClass {
private int val;
// This constructor takes an argument.
MyClass(int v) { val = v; }
// This is the default constructor.
MyClass() { val = 0; }
// ...
int getVal() { return val; };
}
class ConstructorRefDemo {
public static void main(String args[])
{
// Create a reference to the MyClass constructor.
// Because func() in MyFunc takes an argument, new
// refers to the parameterized constructor in MyClass,
// not the default constructor.
MyFunc myClassCons = MyClass::new;
// Create an instance of MyClass via that constructor reference.
MyClass mc = myClassCons.func(100);
// Use the instance of MyClass just created.
System.out.println("val in mc is " + mc.getVal( ));
}
}
That the func( ) method of MyFunc returns a reference of type
MyClass and has an int parameter.
Notice that MyClass defines two constructors. The first specifies a parameter of type int. The second is the default,
parameterless constructor.
Now, examine the following line:
MyFunc myClassCons = MyClass::new;
The expression MyClass::new creates a constructor reference to a MyClass constructor.
In this case, because MyFunc’s func( ) method takes an int parameter, the constructor being
referred to is MyClass(int v) because it is the one that matches.Also notice that the reference to this constructor is assigned to a MyFunc reference called myClassCons.
After this statement executes, myClassCons can be used to create an instance of MyClass,
as this line shows:MyClass mc = myClassCons.func(100);
By above preceding examples the mechanics of using constructor is obtained.
Predefined Functional Interfaces:
- Upto these chapter the functional interfaces are defined by many examples so that fundamental concepts of lambda expression and functional interface are clearly illustrated.
- In some case there wont be any chance to define own interface due to Java JDK8 are introduced the new package java.util.function that provide several predefined ones.
Interface Purpose
UnaryOperator<T> Apply a unary operation to an object of type T and return the result,
which is also of type T. Its method is called apply( ).
BinaryOperator<T> Apply an operation to two objects of type T and return the result, which is also of type T.
Its method is called apply\( \).
Consumer<T> Apply an operation on an object of type T. Its method is accept( ).
Supplier<T> Return an object of type T. Its method is called get( ).
Function<T, R> Apply an operation to an object of type T and return the result as a n
object of type R.Its method is called apply( ).
- These example created its own functional interface called Numericfunc but the built-in function interfaced in it.
Example:
// Use the Function built-in functional interface.
// Import the Function interface.
import java.util.function.Function;
class UseFunctionInterfaceDemo {
public static void main(String args[])
{
// This block lambda computes the factorial of an int value.
// This time, Function is the functional interface.
Function<Integer, Integer> factorial = (n) -> {
int result = 1;
for(int i=1; i <= n; i++)
result = i * result;
return result;
};
System.out.println("The factoral of 3 is " + factorial.apply(3));
System.out.println("The factoral of 5 is " + factorial.apply(5));
}
}