Double Colon Operator in Java 8
Double Colon Operator is used as a method reference by replacing lambda expression.
Syntax :
- className::methodName()
className::methodName()
Its applicable only in the place where lambda is applicable(means only for functional interface implementaions).
Let’s analyze with the below program
- package com.kb.doublecolon;
- public class RunnableEx1 {
- static void show(){
- System.out.println("show defined in separate method");
- }
- public static void main(String[] args) {
- Runnable r1 = () -> System.out.println("show defined in lambda body");
- r1.run();
- Runnable r2 = RunnableEx1::show;
- r2.run();
- }
- }
package com.kb.doublecolon; public class RunnableEx1 { static void show(){ System.out.println("show defined in separate method"); } public static void main(String[] args) { Runnable r1 = () -> System.out.println("show defined in lambda body"); r1.run(); Runnable r2 = RunnableEx1::show; r2.run(); } }
Runnable is a functional interface so it can be replaced by lambda expression as shown above with r1 declaraion
Now to replace this lambda expression , we can use one more feature of Java 8 and that is Double colon(::) operator.
So Double colon operator works well in all the places whenever we implement functional interface methods.
Steps to implement Double Colon(::) Operator
Step 1 :
Define a similar signature of functional interface method in a new class by providing body as required. Most important is signature should be same but method name can be changed.
Step 2 :
Replace lambda expression of implementing functional interface method and in that place add a method reference for a Method defined in class as specified in Step1
Using below syntax
- Classname::methodname //if method is static
Classname::methodname //if method is static
- instanceVarName :: methodname //if method is non static
instanceVarName :: methodname //if method is non static
Let’s analyze another example – sorting person class objects
Create Person.java
- package com.kb.doublecolon;
- public class Person {
- String name;
- int age;
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public int getAge() {
- return age;
- }
- public void setAge(int age) {
- this.age = age;
- }
- @Override
- public String toString() {
- return "name = "+name+" age = "+age;
- }
- }
package com.kb.doublecolon; public class Person { String name; int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "name = "+name+" age = "+age; } }
Create PersonSort.java
- package com.kb.doublecolon;
- import java.util.ArrayList;
- import java.util.Collections;
- import java.util.List;
- public class PersonSort {
- public static void main(String[] args) {
- Person p1 = new Person();
- Person p2 = new Person();
- Person p3 = new Person();
- p1.setAge(20);
- p1.setName("abc");
- p2.setAge(25);
- p2.setName("xyz");
- p3.setAge(15);
- p3.setName("def");
- List<Person> people = new ArrayList<Person>();
- people.add(p1);
- people.add(p2);
- people.add(p3);
- System.out.println("before sorting "+people);
- Collections.sort(people,(Person per1,Person per2) -> {
- return per1.getAge() - per2.getAge();
- }
- );
- System.out.println("after sorting "+people);
- }
- }
package com.kb.doublecolon; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class PersonSort { public static void main(String[] args) { Person p1 = new Person(); Person p2 = new Person(); Person p3 = new Person(); p1.setAge(20); p1.setName("abc"); p2.setAge(25); p2.setName("xyz"); p3.setAge(15); p3.setName("def"); List<Person> people = new ArrayList<Person>(); people.add(p1); people.add(p2); people.add(p3); System.out.println("before sorting "+people); Collections.sort(people,(Person per1,Person per2) -> { return per1.getAge() - per2.getAge(); } ); System.out.println("after sorting "+people); } }
Now I will add the sorting logic in one class and will call that logic in lambda body
Create PersonSortByAge.java
- package com.kb.doublecolon;
- import java.util.Comparator;
- public class PersonSortByAge {
- public int compare(Person p1,Person p2) {
- return p1.getAge() - p2.getAge();
- }
- }
package com.kb.doublecolon; import java.util.Comparator; public class PersonSortByAge { public int compare(Person p1,Person p2) { return p1.getAge() - p2.getAge(); } }
Create PersonSort.java
- package com.kb.doublecolon;
- import java.util.ArrayList;
- import java.util.Collections;
- import java.util.List;
- public class PersonSort {
- public static void main(String[] args) {
- Person p1 = new Person();
- Person p2 = new Person();
- Person p3 = new Person();
- p1.setAge(20);
- p1.setName("abc");
- p2.setAge(25);
- p2.setName("xyz");
- p3.setAge(15);
- p3.setName("def");
- List<Person> people = new ArrayList<Person>();
- people.add(p1);
- people.add(p2);
- people.add(p3);
- System.out.println("before sorting "+people);
- PersonSortByAge sortByAge = new PersonSortByAge();
- Collections.sort(people,(Person per1,Person per2) -> sortByAge.compare(per1, per2));
- System.out.println("after sorting "+people);
- }
- }
package com.kb.doublecolon; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class PersonSort { public static void main(String[] args) { Person p1 = new Person(); Person p2 = new Person(); Person p3 = new Person(); p1.setAge(20); p1.setName("abc"); p2.setAge(25); p2.setName("xyz"); p3.setAge(15); p3.setName("def"); List<Person> people = new ArrayList<Person>(); people.add(p1); people.add(p2); people.add(p3); System.out.println("before sorting "+people); PersonSortByAge sortByAge = new PersonSortByAge(); Collections.sort(people,(Person per1,Person per2) -> sortByAge.compare(per1, per2)); System.out.println("after sorting "+people); } }
Now to replace this lambda expression calling method in its body, we can use one more feature of Java 8
That is Double colon (::) operator.
See the below program
- package com.kb.doublecolon;
- import java.util.ArrayList;
- import java.util.Collections;
- import java.util.List;
- public class PersonSort {
- public static void main(String[] args) {
- Person p1 = new Person();
- Person p2 = new Person();
- Person p3 = new Person();
- p1.setAge(20);
- p1.setName("abc");
- p2.setAge(25);
- p2.setName("xyz");
- p3.setAge(15);
- p3.setName("def");
- List<Person> people = new ArrayList<Person>();
- people.add(p1);
- people.add(p2);
- people.add(p3);
- System.out.println("before sorting "+people);
- PersonSortByAge sortByAge = new PersonSortByAge();
- Collections.sort(people,sortByAge::compare);
- System.out.println("after sorting "+people);
- }
- }
package com.kb.doublecolon; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class PersonSort { public static void main(String[] args) { Person p1 = new Person(); Person p2 = new Person(); Person p3 = new Person(); p1.setAge(20); p1.setName("abc"); p2.setAge(25); p2.setName("xyz"); p3.setAge(15); p3.setName("def"); List<Person> people = new ArrayList<Person>(); people.add(p1); people.add(p2); people.add(p3); System.out.println("before sorting "+people); PersonSortByAge sortByAge = new PersonSortByAge(); Collections.sort(people,sortByAge::compare); System.out.println("after sorting "+people); } }
its very simple and useful article.
Please add stream API also.
KB
Nice blog to read
– Chethu
Thank you Chethu 🙂
Really enjoyed the simple way articles
Thank you !!
One important difference between Lambda Expressions and Method reference is lambda expressions let us define anonymous methods which can be used as an instance of functional interfaces. Method references provide a way to refer existing methods.
Read more here – http://netjs.blogspot.com/2015/06/method-reference-in-java-8.html
Hi Infoj, Thanks !!! you are right, same thing is explained in the lambda expression posts in my blog.
ultimate