Alphalearningschool
        

<<< Prev

Next >>>

Up
Java 8 Features

Lambda Expression:

Lambda expression provide concise implementation of one method interface(Functional interface). In this case we don’t need to write method again. We can also provide implementation of abstract method of an interface  using anonymous class. Lambda expression provides implementation of a single abstract method of interface in better and concise form. Lambda expression is an important feature which is introduced in java 8. 

Functional Interface is an interface which has only one abstract method. We can use @FunctionalInterface annotation to define functional interface. @FunctionalInterface is an optional annotation. Functional interface can have any no of default, static method but it can contain only one abstract method.

Test1.java
package com.qualde;
public class Test1 {
         public static void main(String[] args) {
	//using anonymous class
	MyInterface m=new MyInterface() {
		public void show() {
			System.out.println("welcome to show() method");
		}		
	};
	m.show();
		
	//using lambda expression
	MyInterface m1=()->{System.out.println("hello this is lambda expression");};	
	m1.show();
        }
}

@FunctionalInterface
interface MyInterface{
	void show();	
}

Output:welcome to show() method
hello this is lambda expression

 

Different form to implement lambda Expression:

Test2.java
package com.qualde;
public class Test2 {
	public static void main(String[] args) {		
		
		//using lambda expression
		Interface11 m1=(int x, int y)->(x+y);	
		Interface11 m2=(x,y)->{return(x+y);};	
		Interface11 m3=(x,y)->(x+y);	
		System.out.println(m1.sum(25,76));
		System.out.println(m2.sum(25,76));
		System.out.println(m3.sum(25,76));
		
	}
}

interface Interface11{
	int sum(int a, int b);		
}

Output:
101
101
101

 

Use of Lambda Expression to iterate collection elements:

Test3.java
package com.qualde;
import java.util.*;
public class Test3 {
	public static void main(String[] args) {		
		List<Integer> list=new ArrayList<>();
		list.add(500);
		list.add(10);
		list.add(3000);
		list.add(450);		
		list.forEach(num->System.out.println(num));		
	}
}

Output:
500
10
3000
450

Use of Lambda Expression to create thread using Runnable interface:

Test4.java
package com.qualde;
public class Test4 {
        public static void main(String[] args) {		
	Runnable r=new Runnable() {	
		public void run() {
			System.out.println("------ run method() -----");
			for(int i=0;i<5;i++)
			      System.out.println(i+" ="+Thread.currentThread().getName());
			}
		};
		Thread th=new Thread(r);
	
		Runnable r1=()->{
		              System.out.println("----- this is lambda expression--------");
		         for(int i=0;i<5;i++)
			System.out.println(i+" ="+Thread.currentThread().getName());
		};
		Thread th1=new Thread(r1);
		th1.start();
		th.start();
	}
}

Output:
------ run method() -----
----- this is lambda expression--------
0 =Thread-0
0 =Thread-1
1 =Thread-0
1 =Thread-1
2 =Thread-0
2 =Thread-1
3 =Thread-0
3 =Thread-1
4 =Thread-0
4 =Thread-1

Use of Lambda Expression to sort the element of collection:

Test5.java
package com.qualde;
import java.util.*;
public class Test5 {
       public static void main(String[] args) {		
	List<Student> students=new ArrayList<>();
	students.add(new Student(101,"Sachin", 65));
	students.add(new Student(102,"Arjun", 82));
	students.add(new Student(103,"Rohan", 87));
	students.add(new Student(104,"Sohan", 35));
	students.add(new Student(105,"Rakesh", 70));
	students.add(new Student(106,"Sachin", 19));
	System.out.println(students);
		
	System.out.println("----  sorting according to marks using lambda expression ----");
	Collections.sort(students,(s1,s2)->{return s1.getMarks()-s2.getMarks();});
	System.out.println(students);
	}
}

class Student{
	private int sid;
	private String sname;
	private int marks;
	public Student(int sid, String sname, int marks) {
		super();
		this.sid = sid;
		this.sname = sname;
		this.marks = marks;
	}
		
	public int getSid() {
		return sid;
	}

	public void setSid(int sid) {
		this.sid = sid;
	}

	public String getSname() {
		return sname;
	}

	public void setSname(String sname) {
		this.sname = sname;
	}

	public int getMarks() {
		return marks;
	}

	public void setMarks(int marks) {
		this.marks = marks;
	}

	@Override
	public String toString() {
		return "\n Student [sid=" + sid + ", sname=" + sname + ", marks=" + marks + "]";
	}	
	
}

Output:
[
Student [sid=101, sname=Sachin, marks=65], 
Student [sid=102, sname=Arjun, marks=82], 
Student [sid=103, sname=Rohan, marks=87], 
Student [sid=104, sname=Sohan, marks=35], 
Student [sid=105, sname=Rakesh, marks=70], 
Student [sid=106, sname=Sachin, marks=19]]
----  sorting according to marks using lambda expression ----
[
Student [sid=106, sname=Sachin, marks=19], 
Student [sid=104, sname=Sohan, marks=35], 
Student [sid=101, sname=Sachin, marks=65], 
Student [sid=105, sname=Rakesh, marks=70], 
Student [sid=102, sname=Arjun, marks=82], 
Student [sid=103, sname=Rohan, marks=87]]

Filter Collection Data using Lambda Expression:

Test6.java
package com.qualde;
import java.util.*;
import java.util.stream.Stream;
public class Test6 {
         public static void main(String[] args) {		
	List<Student> students=new ArrayList<>();
	students.add(new Student(101,"Sachin", 65));
	students.add(new Student(102,"Arjun", 82));
	students.add(new Student(103,"Rohan", 87));
	students.add(new Student(104,"Sohan", 35));
	students.add(new Student(105,"Rakesh", 70));
	students.add(new Student(106,"Sachin", 19));

	System.out.println(students);
		
	System.out.println("----filter students according to marks using lambda expression ---");
Stream<Student> filteredStudent=students.stream().filter(s->s.getMarks()>30                        && s.getMarks()<80);
	filteredStudent.forEach(student->System.out.println(student));	
	
}
}


class Student{
	private int sid;
	private String sname;
	private int marks;
	public Student(int sid, String sname, int marks) {
		super();
		this.sid = sid;
		this.sname = sname;
		this.marks = marks;
	}
		
	public int getSid() {
		return sid;
	}

	public void setSid(int sid) {
		this.sid = sid;
	}

	public String getSname() {
		return sname;
	}

	public void setSname(String sname) {
		this.sname = sname;
	}

	public int getMarks() {
		return marks;
	}

	public void setMarks(int marks) {
		this.marks = marks;
	}

	public String toString() {
	return "\nStudent [sid=" + sid + ", sname=" + sname + ", marks=" + marks + "]";
	}	
	
}

Output:
[
Student [sid=101, sname=Sachin, marks=65], 
Student [sid=102, sname=Arjun, marks=82], 
Student [sid=103, sname=Rohan, marks=87], 
Student [sid=104, sname=Sohan, marks=35], 
Student [sid=105, sname=Rakesh, marks=70], 
Student [sid=106, sname=Sachin, marks=19]]
----  filter students according to marks using lambda expression ----

Student [sid=101, sname=Sachin, marks=65]

Student [sid=104, sname=Sohan, marks=35]

Student [sid=105, sname=Rakesh, marks=70]

Interface Improvement in Java 8:

Now we can write static and default method inside the interface with body.

1)Static non abstract methods inside interface:

Test7.java
package com.qualde;
public class Test7 {
	public static void main(String[] args) {		
		Interface1.show();
		Interface1.hello("Welcome");
	}
}

interface Interface1{
	static void show() {
		System.out.println("this is static show() method inside interface");	
	}
	
	static void hello(String str) {
		System.out.println("-- static hello() method inside interface -->> "+str);	
	}
}

Output:
this is static show() method inside interface
-- static hello() method inside interface -->> Welcome

 

Java Default methods inside interface:

In java 8, we can implement non abstract method inside interface using default keyword. We can access that method by using object of subclass.

Test8.java
package com.qualde;
public class Test8 implements Interface2 {
	public static void main(String[] args) {		
		Test8 t=new Test8();
		t.hello("Hi");;
	}
}
interface Interface2{
	default void hello(String str) {
		System.out.println("-- interface2 -->> "+str);	
	}
}

Output:
-- interface2 -->> Hi

 

If we implement multiple inheritance in java 8 and both interface have default method with same signature(same method name and arguments)  then we have to override that method inside the subclass.

Test9.java
package com.qualde;
public class Test9 implements Interface3,Interface4 {
	
	public void hello(String str) {
		System.out.println("--- Test8 hello() method "+str);
	}
	public static void main(String[] args) {		
		Test9 t=new Test9();
		t.hello("Hi");
		t.display();
	}
}

interface Interface3{
	default void hello(String str) {
		System.out.println("-- interface3 hello() method -->> "+str);		
	}
	default void display() {
		System.out.println("-- interface3 display() method-->> ");		
	}	
}

interface Interface4{		
	default void hello(String str) {
		System.out.println("-- interface3 hello() method-->> "+str);	
	}
}

Output:
--- Test8 hello() method Hi
-- interface3 display() method-->>

 

If a class Test10 extend a class A and implement an interface Interface5 and both class and interface have same method then subclass object will call method of class A because class has more preference than interface.

Test10.java
package com.qualde;
public class Test10 extends A implements Interface5{
	public static void main(String[] args) {		
		Test10 t=new Test10();
		t.hello("Hi");		
	}
}

class A{	
	public  void hello(String str) {
		System.out.println("-- A hello() method -->> "+str);			
	}
}

interface Interface5{
	default void hello(String str) {
		System.out.println("-- interface5 hello() method -->> "+str);		
	}	
}

Output:
-- A hello() method -->> Hi

 

Method Reference in Java 8:

Method reference is used to refer method implementation of a functional interface.                       

Refer a static method to user defined functional interface

Test11.java
package com.qualde;
public class Test11{
	public static void main(String[] args) {		
		In1 in1=Hi::sayHello;
		in1.hello();
		
		In2 in2=Hi::sayBye;
		in2.bye("Bye");		
	}
}
class Hi{
	public static void sayHello() {
		System.out.println("sayHello() method");
	}
	public static void sayBye(String str) {
		System.out.println("sayBye() method"+str);
	}
}
interface In1{	
	void hello();
}
interface In2{
	void bye(String str);	
}

Output:
sayHello() method
sayBye() methodBye

 

Refer a static method to predefined functional interface:

Test.java
package com.qualde;
public class Test12{
	public static void main(String[] args) {	
		System.out.println("main method() started");
		
		Runnable r=Hello::sayHello;
		Thread th=new Thread(r);
		th.start();
		
	System.out.println("main method() end");
	}
}

class Hello{
	public static void sayHello() {
		System.out.println("sayHello() method");
	}
	public static void sayBye(String str) {
		System.out.println("sayBye() method"+str);
	}
}

Output:
main method() started
main method() end
sayHello() method

Refer a instance method to a functional interface:

Test13.java
package com.qualde;
public class Test13{
	public static void main(String[] args) throws InterruptedException {	
		System.out.println("main method() started");
		Demo d=new Demo();
		Runnable r=d::say;
		Thread th=new Thread(r);
		th.start();
		Thread.sleep(1);	
	System.out.println("main method() end");
	}
}

class Demo{
	public void say() {
		for(int i=0;i<6;i++)
		System.out.println("sayHello() method "+i);
	}
}

Output:
main method() started
sayHello() method 0
sayHello() method 1
main method() end
sayHello() method 2
sayHello() method 3
sayHello() method 4
sayHello() method 5

 

 Refer a constructor to a functional interface:

Test14.java
package com.qualde;
public class Test14{
	public static void main(String[] args) throws InterruptedException {	
		System.out.println("main method() started");
		
		ExampleInterface ei=Example::new;
		ei.something();
		
	System.out.println("main method() end");
	}
}

class Example{
	public Example() {
		System.out.println("--->> this is Example() constructor");		
	}
}

interface ExampleInterface{	
	public void something();
}
	
Output:
main method() started
--->> this is Example() constructor
main method() end