Java 8 Notes
Java 8 Notes
Lambda Expressions
Lambda Expression basically expresses an instance of the functional
interface, in other words, you can say it provides a clear and concise way to
represent a method of the functional interface using an expression. Lambda
Expressions are added in Java 8.
interface FuncInterface
{
// An abstract function
System.out.println("Hello");
class Test
fobj.abstractFun(5);
Output
10
Java
// A Java program to demonstrate simple lambda expressions
import java.util.ArrayList;
class Test {
// {1, 2, 3, 4}
arrL.add(1);
arrL.add(2);
arrL.add(3);
arrL.add(4);
// of arrL
// of arrL
arrL.forEach(n -> {
if (n % 2 == 0)
System.out.println(n);
});
Output
1
2
3
4
2
4
// above
interface FuncInter2 {
// 'FuncInter1' interface
// Expressions
System.out.println("Addition is "
+ tobj.operate(6, 3, add));
System.out.println("Multiplication is "
+ tobj.operate(6, 3, multiply));
// lambda expression for single parameter
fobj.sayMessage("Geek");
Output
Addition is 9
Multiplication is 18
Hello Geek
Note: Lambda expressions are just like functions and they accept
parameters just like functions.
Conclusion
Some Important points intake from this article is mentioned below:
The body of a lambda expression can contain zero, one, or more
statements.
When there is a single statement curly brackets are not mandatory and
the return type of the anonymous function is the same as that of the body
expression.
When there is more than one statement, then these must be enclosed in
curly brackets (a code block) and the return type of the anonymous
function is the same as the type of the value returned within the code
block, or void if nothing is returned.
FAQs in Lambda Expression
Q1. What type of lambda expression Java?
Answer:
Java Lambda Expressions are the short block of code that accepts input as
parameters and returns a resultant value.
Q2. Is it good to use lambda expressions in Java?
Answer:
Yes, using lambda expressions makes it easier to use and support other
APIs.
Q3. What are the drawbacks of Java lambda?
Answer:
Java lambda functions can be only used with functional interfaces.
Q4. Based on the syntax rules just shown, which of the following is/are
NOT valid lambda expressions?
1. () -> {}
2. () -> “geeksforgeeks”
3. () -> { return “geeksforgeeks”;)
4. (Integer i) -> return “geeksforgeeks” + i;
5. (String s) -> {“geeksforgeeks”;}
Answer:
4 and 5 are invalid lambdas, the rest are valid. Details:
1. This lambda has no parameters and returns void. It’s similar to a method
with an empty body: public void run() { }.
2. This lambda has no parameters and returns a String as an expression.
3. This lambda has no parameters and returns a String (using an explicit
return statement, within a block).
4. return is a control-flow statement. To make this lambda valid, curly braces
are required as follows: (Integer i) -> { return “geeksforgeeks” + i; }.
5. “geeks for geeks” is an expression, not a statement. To make this lambda
valid, you can remove the curly braces and semicolon as follows: (String
s) -> “geeks for geeks”. Or if you prefer, you can use an explicit return
statement as follows: (String s) -> { return “geeks for geeks”; }.
// without parameters
// functional interface
// without parameters
interface Test1 {
void print();
class GfG {
Output
Hello
Example 2: Type 2 Lambda expression with a single parameter
Java
// functional interface
interface Test2 {
class GfG {
t.print(p);
Output
10
Example 3: Type 3 Lambda expression with multi parameters
Java
interface Test3 {
class GfG {
t.print(p1, p2);
fun((p1, p2)
-> System.out.println(p1 + " " + p2),
10, 20);
Output
10 20
Example 4:Lambda expression with two parameters
Java
interface NumericTest2{
class GFG{
// The lambda expression here determines if one number is the factor of another
if(isFactor.test(10,2))
System.out.println("2 is the factor of 10");
if(!isFactor.test(10,3))
Output
2 is the factor of 10
3 is not a factor of 10
al.add(205);
al.add(102);
al.add(98);
al.add(275);
al.add(203);
}
}
import java.util.*;
TreeSet<Integer> h =
h.add(850);
h.add(235);
h.add(1080);
h.add(15);
h.add(5);
}
Sorting elements of TreeMap using Lambda Expression: Sorting will be
done on the basis of the keys and not its value.
Java
import java.util.*;
TreeMap<Integer, String> m =
m.put(1, "Apple");
m.put(4, "Mango");
m.put(5, "Orange");
m.put(2, "Banana");
m.put(3, "Grapes");
import java.util.*;
class GFG{
ts.add("A");
ts.add("B");
ts.add("C");
ts.add("D");
ts.add("E");
ts.add("F");
ts.add("G");
System.out.println(element + "");
System.out.println();
Output
G
F
E
D
C
B
A
import java.io.*;
// Interface
interface If1 {
// Abstract function
// Class
class GFG {
// Main driver method
if (isEven.fun(21))
System.out.println("21 is even");
else
// Display message to be printed
System.out.println("21 is odd");
Output
21 is odd
Implementation:
Example 1:
Java
import java.io.*;
// of a number
// Interface
interface Func {
// factorial is to be computed
// Class
// Main class
class GFG {
// Block body
int res = 1;
res = i * res;
return res;
};
Output
Factorial of 5: 120
Here in this block lambda declares a variable ‘res’, for loop and has return
statement which are legal in lambda body.
Example 2:
Java
import java.io.*;
// Interface
interface New {
// passed as an parameter
boolean test(int n);
// Class
// Main class
class GFG {
// block lambda
// Condition check
if (((year % 400 == 0)
return true;
else
return false;
};
if (leapyr.test(2020))
System.out.println("leap year");
else
Output
leap year
Example 1:
Before Java 8, we had to create anonymous inner class objects or implement
these interfaces.
Java
class Test {
}).start();
Output
New thread created
Example 2:
Java 8 onwards, we can assign lambda expression to its functional interface
object like this:
Java
// Java program to demonstrate Implementation of
class Test {
}).start();
Output
New thread created
@FunctionalInterface Annotation
@FunctionalInterface
interface Square {
class Test {
int a = 5;
Output
25
2. Predicate
In scientific logic, a function that accepts an argument and, in return,
generates a boolean value as an answer is known as a predicate. Similarly,
in the Java programming language, a predicate functional interface of Java is
a type of function that accepts a single value or argument and does some
sort of processing on it, and returns a boolean (True/ False) answer. The
implementation of the Predicate functional interface also encapsulates the
logic of filtering (a process that is used to filter stream components on the
base of a provided predicate) in Java.
Just like the Consumer functional interface, Predicate functional interface
also has some extensions. These are IntPredicate, DoublePredicate, and
LongPredicate. These types of predicate functional interfaces accept only
primitive data types or values as arguments.
Bi-Predicate – Bi-Predicate is also an extension of the Predicate functional
interface, which, instead of one, takes two arguments, does some
processing, and returns the boolean value.
Syntax of Predicate Functional Interface –
public interface Predicate<T> {
}
The predicate functional interface can also be implemented using a class.
The syntax for the implementation of predicate functional interface using a
class is given below –
public class CheckForNull implements Predicate {
@Override
public boolean test(Object o) {
return o != null;
}
}
The Java predicate functional interface can also be implemented using
Lambda expressions. An example of the implementation of the Predicate
functional interface is given below –
Predicate predicate = (value) -> value != null;
This implementation of functional interfaces in Java using Java Lambda
expressions is more manageable and effective than the one implemented
using a class as both the implementations are doing the same work, i.e.,
returning the same output.
3. Function
A function is a type of functional interface in Java that receives only a single
argument and returns a value after the required processing. There are many
versions of Function interfaces because a primitive type can’t imply a general
type argument, so we need these versions of function interfaces. Many
different versions of the function interfaces are instrumental and are
commonly used in primitive types like double, int, long. The different
sequences of these primitive types are also used in the argument.
These versions are:
Bi-Function
The Bi-Function is substantially related to a Function. Besides, it takes two
arguments, whereas Function accepts one argument.
The prototype and syntax of Bi-Function is given below –
@FunctionalInterface
public interface BiFunction<T, U, R>
{
R apply(T t, U u);
.......
}
In the above code of interface, T and U are the inputs, and there is only one
output which is R.
Unary Operator and Binary Operator
There are also two other functional interfaces which are named Unary
Operator and Binary Operator. They both extend the Function and Bi-
Function, respectively. In simple words, Unary Operator extends Function,
and Binary Operator extends Bi-Function.
4. Supplier
The Supplier functional interface is also a type of functional interface that
does not take any input or argument and yet returns a single output. This
type of functional interface is generally used in the lazy generation of values.
Supplier functional interfaces are also used for defining the logic for the
generation of any sequence. For example – The logic behind the Fibonacci
Series can be generated with the help of the Stream. generate method,
which is implemented by the Supplier functional Interface.
The different extensions of the Supplier functional interface hold many other
suppliers functions like BooleanSupplier, DoubleSupplier, LongSupplier, and
IntSupplier. The return type of all these further specializations is their
corresponding primitives only.
Syntax / Prototype of Supplier Functional Interface is –
@FunctionalInterface
public interface Supplier<T>{
// gets a result
………….
T.get();
}
Below is the implementation of the above topic:
Java
// of predicate interface
import java.util.*;
import java.util.function.Predicate;
class Test {
if (p.test(st))
System.out.println(st);
Output
Geek
GeeksQuiz
Geek2
Important Points/Observations:
Here are some significant points regarding Functional interfaces in Java:
1. In functional interfaces, there is only one abstract method supported. If
the annotation of a functional interface, i.e., @FunctionalInterface is not
implemented or written with a function interface, more than one abstract
method can be declared inside it. However, in this situation with more
than one functions, that interface will not be called a functional interface.
It is called a non-functional interface.
2. There is no such need for the @FunctionalInterface annotation as it is
voluntary only. This is written because it helps in checking the compiler
level. Besides this, it is optional.
3. An infinite number of methods (whether static or default) can be added to
the functional interface. In simple words, there is no limit to a functional
interface containing static and default methods.
4. Overriding methods from the parent class do not violate the rules of a
functional interface in Java.
5. The java.util.function package contains many built-in functional
interfaces in Java 8.