Java 8 - Part 1 Lambda, FnInterface, MethodRef
Java 8 - Part 1 Lambda, FnInterface, MethodRef
Lambda expression is a new and important feature of Java which was included in
JavaSE 8. It provides a clear and concise way to represent one method interface
using an expression. It is very useful in collection library. It helps to iterate, filter
and extract data from collection.
The Lambda expression is used to provide the implementation of an interface which has
functional interface. It saves a lot of code. In case of lambda expression, we don't need to
define the method again for providing the implementation
Java lambda expression is treated as a function, so compiler does not create .class file.
Functional Interface
Lambda expression provides implementation of functional interface. An interface
which has only one abstract method is called functional interface. Java
provides an anotation@FunctionalInterface, which is used to declare an interface
as functional interface.
Why use Lambda Expression
To provide the implementation of Functional interface.
Less coding.
interface Drawable{
public void draw();
}
public class LambdaExpressionExample {
public static void main(String[] args) {
int width=10;
Output:
Drawing 10
//with lambda
Drawable d2=()->{
System.out.println("Drawing "+width);
};
d2.draw();
}
}
Output:
Drawing 10
Output:
30
300
import java.util.*;
public class LambdaExpressionExample7{
public static void main(String[] args) {
list.forEach(
(n)->System.out.println(n)
);
}
}
Output:
ankit
mayank
irfan
jai
@FunctionalInterface
interface Sayable{
String say(String message);
}
Output:
Thread1 is running...
Thread2 is running...
Java Functional Interfaces
An Interface that contains exactly one abstract method is known as functional
interface. It can have any number of default, static methods but can contain only one
abstract method. It can also declare methods of object class.
Functional Interface is also known as Single Abstract Method Interfaces or SAM
Interfaces. It is a new feature in Java, which helps to achieve functional programming
approach.
Example 1
@FunctionalInterface
interface sayable{
void say(String msg);
}
public class FunctionalInterfaceExample implements sayable{
public void say(String msg){
System.out.println(msg);
}
public static void main(String[] args) {
FunctionalInterfaceExample fie = new FunctionalInterfaceExample();
fie.say("Hello there");
}
}
Output:
Hello there
A functional interface can have methods of object class. See in the following
example.
Example 2
@FunctionalInterface
interface sayable{
void say(String msg); // abstract method
// It can contain any number of Object class methods.
int hashCode();
String toString();
boolean equals(Object obj);
}
public class FunctionalInterfaceExample2 implements sayable{
public void say(String msg){
System.out.println(msg);
}
public static void main(String[] args) {
FunctionalInterfaceExample2 fie = new FunctionalInterfaceExample2();
fie.say("Hello there");
}
}
Test it Now
Output:
Hello there
Example 3
In the following example, a functional interface is extending to a non-functional
interface.
interface Doable{
default void doIt(){
System.out.println("Do it now");
}
}
@FunctionalInterface
interface Sayable extends Doable{
void say(String msg); // abstract method
}
public class FunctionalInterfaceExample3 implements Sayable{
public void say(String msg){
System.out.println(msg);
}
public static void main(String[] args) {
FunctionalInterfaceExample3 fie = new FunctionalInterfaceExample3();
fie.say("Hello there");
fie.doIt();
}
}
Output:
Hello there
Do it now
@FunctionalInterface
interface A
{
intadd(inta);
}
System.out.println(obj.add(1000));
}
- Predicate -Biprtedicatetest()
- Function - Bifunctionaccept()
- Consumer - Biconsumerapply()
- Supplier - Bisupplierget()
- import java.util.function.*;
static intcalculate()
{
inth=100+200;
return h;
}
public static void main(String args[])
{
Predicate<Integer>ref=(s)->(s>-10)&&(s<10);
booleanresult=ref.test(41);
System.out.println(result);
Predicate<Integer>obj=a->(a>100);
booleanresult1=obj.test(6789);
System.out.println(result1);
BiPredicate<Integer,Integer>obj1=(b,c)->(b>c);
booleanresult2=obj1.test(102,20);
System.out.println(result2);
BiPredicate<String,String>obj2=(s1,s2)->s1.equals(s2);
booleanresult3=obj2.test("appless","apple");
System.out.println(result3);
Function<String,Integer>aa= f->f.length();
System.out.println(aa.apply("i love india"));
Consumer<String>bb=s->
{
System.out.println(s.concat("goodboy"));
};
//System.out.println(bb.accept("kesaraj"));
bb.accept("kesavraj");
Supplier<Integer>ss=()->Predefinded.calculate();
System.out.println(ss.get());
}
}
Static Instance:
package Java8.Functionalinterface;
@FunctionalInterface
interface McD{
void burger();
default void ketchUp() {
System.out.println("Ketchup given");
}
static void cheese() {
System.out.println("Cheese given");
}
}
// With Lambda
public class DefaultStaticMethods// implements McD
{
Jg j=new Jg();
j.burger();
}
// Without Lambda
class Jgimplements McD{
public void burger() {
System.out.println("hi..");
ketchUp();
McD.cheese();
System.out.println("---------------------");
}
}
Output:
Hello, this is static method.
Example 2
In the following example, we are using predefined functional interface Runnable to refer
static method.
1. public class MethodReference2 {
2. public static void ThreadStatus(){
3. System.out.println("Thread is running...");
4. }
5. public static void main(String[] args) {
6. Thread t2=new Thread(MethodReference2::ThreadStatus);
7. t2.start();
8. }
9. }
Test it Now
Output:
Thread is running...
Example 3
You can also use predefined functional interface to refer methods. In the following
example, we are using BiFunction interface and using it's apply() method.
1. import java.util.function.BiFunction;
2. class Arithmetic{
3. public static int add(int a, int b){
4. return a+b;
5. }
6. }
7. public class MethodReference3 {
8. public static void main(String[] args) {
9. BiFunction<Integer, Integer, Integer>adder = Arithmetic::add;
10.int result = adder.apply(10, 20);
11.System.out.println(result);
12.}
13.}
Test it Now
Output:
30
Example 4
You can also override static methods by referring methods. In the following example, we
have defined and overloaded three add methods.
1. import java.util.function.BiFunction;
2. class Arithmetic{
3. public static int add(int a, int b){
4. return a+b;
5. }
6. public static float add(int a, float b){
7. return a+b;
8. }
9. public static float add(float a, float b){
10.return a+b;
11.}
12.}
13.public class MethodReference4 {
14.public static void main(String[] args) {
15.BiFunction<Integer, Integer, Integer>adder1 = Arithmetic::add;
16.BiFunction<Integer, Float, Float>adder2 = Arithmetic::add;
17.BiFunction<Float, Float, Float>adder3 = Arithmetic::add;
18.int result1 = adder1.apply(10, 20);
19.float result2 = adder2.apply(10, 20.0f);
20.float result3 = adder3.apply(10.0f, 20.0f);
21.System.out.println(result1);
22.System.out.println(result2);
23.System.out.println(result3);
24.}
25.}
Test it Now
Output:
30
30.0
30.0
Output:
Hello, this is non-static method.
Hello, this is non-static method.
Example 2
In the following example, we are referring instance (non-static) method. Runnable
interface contains only one abstract method. So, we can use it as functional interface.
1. public class InstanceMethodReference2 {
2. public void printnMsg(){
3. System.out.println("Hello, this is instance method");
4. }
5. public static void main(String[] args) {
6. Thread t2=new Thread(new InstanceMethodReference2()::printnMsg);
7. t2.start();
8. }
9. }
Test it Now
Output:
Hello, this is instance method
Example 3
In the following example, we are using BiFunction interface. It is a predefined interface
and contains a functional method apply(). Here, we are referring add method to apply
method.
1. import java.util.function.BiFunction;
2. class Arithmetic{
3. public int add(int a, int b){
4. return a+b;
5. }
6. }
7. public class InstanceMethodReference3 {
8. public static void main(String[] args) {
9. BiFunction<Integer, Integer, Integer>adder = new Arithmetic()::add;
10.int result = adder.apply(10, 20);
11.System.out.println(result);
12.}
13.}
Test it Now
Output:
30
3) Reference to a Constructor
You can refer a constructor by using the new keyword. Here, we are referring constructor
with the help of functional interface.
Syntax
1. ClassName::new
Example
1. interface Messageable{
2. Message getMessage(String msg);
3. }
4. class Message{
5. Message(String msg){
6. System.out.print(msg);
7. }
8. }
9. public class ConstructorReference {
10. public static void main(String[] args) {
11. Messageable hello = Message::new;
12. hello.getMessage("Hello");
13. }
14.}
Test it Now
ADVERTISEMENT
Output:
Hello
Instance method
package Java8.MethodRef;
interface A
{
void disp(inta);
//void disp1(int a);
}
InstanceMethodim=new InstanceMethod();
A ref=im::display;
ref.disp(56);
A ref1=InstanceMethod::disp;
ref1.disp(20);
}
Constructor using
Exe-1
package Java8.MethodRef;
interface A5{
void aa(); // mention the void as return type for multiple classes
}
class B1{
B1(){
System.out.println("B..");
}
}
class C1{
C1(){
System.out.println("C..");
}
}
exe-2
package Java8.MethodRef;
interface A3{
B print(); //mention the class name as return type
}
class B{
B(){
System.out.println("B..");
}
}