As you have learned Lambda expression feature of Java 8 which allows you to reduce code compared to anonymous class to pass behaviors to methods. In Java 8, method reference is one more new feature available which reduces code written in a lambda expression to make it more readable.

There are four kinds of method references in Java 8:

  1. Static methods
  2. Instance methods of particular objects
  3. Constructor
  4. Instance methods of an arbitrary object of a particular type

Example of Static methods

package com.javatutsworld;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Java8MethodReference {
    public static void main(String args[]) {

        List<AccountDetails> acttList = new ArrayList<>();
        acttList.add(new AccountDetails("Saaim", "00266767", 2000));
        acttList.add(new AccountDetails("Sudhir", "00266788", 30000));
        acttList.add(new AccountDetails("Gaurav", "00266798", 90000));
        acttList.add(new AccountDetails("Ram", "00266799", 50000));

        System.out.println("Before sorting : ");
        acttList.stream().forEach(acct -> System.out.println("Amount: " + acct.getAmount()));

        // Sort all records on amount, using lambda expression 

        Collections.sort(acttList, (a, b) -> AccountDetails.compareByAmount(a, b)); 
        System.out.println("After sorting on amount using lambda expression : ");
        acttList.stream().forEach(acct -> System.out.println("Amount: " + acct.getAmount()));

        // Sort all records on amount, using method reference

        Collections.sort(acttList, AccountDetails::compareByAmount); 
        System.out.println("After sorting on amount using method reference : ");
        acttList.stream().forEach(acct -> System.out.println("Amount: " + acct.getAmount()));


    }

}

AccountDetails.java

package com.javatutsworld;

interface AccountsFactory {
    public abstract AccountDetails getAccountDetails(String name, String accountNumber, Integer amount);
}

public class AccountDetails {
    private String name;
    private String accountNumber;
    private Integer amount;

    public AccountDetails() {
    }

    public AccountDetails(String name, String accountNumber, Integer amount) {
        super();
        this.name = name;
        this.accountNumber = accountNumber;
        this.amount = amount;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAccountNumber() {
        return accountNumber;
    }

    public void setAccountNumber(String accountNumber) {
        this.accountNumber = accountNumber;
    }

    public Integer getAmount() {
        return amount;
    }

    public void setAmount(Integer amount) {
        this.amount = amount;
    }

    public static int compareByAmount(AccountDetails a, AccountDetails b) {
        return a.amount - b.amount;
    }

    public int compareByName(AccountDetails a, AccountDetails b) {
        return a.name.compareTo(b.name);
    }

}

Output:

Before sorting : 
Amount: 2000
Amount: 30000
Amount: 90000
Amount: 50000
After sorting on amount using lambda expression : 
Amount: 2000
Amount: 30000
Amount: 50000
Amount: 90000
After sorting on amount using method reference : 
Amount: 2000
Amount: 30000
Amount: 50000
Amount: 90000

Example of Instance methods of particular objects

package com.javatutsworld;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Java8MethodReference {
    public static void main(String args[]) {

        List<AccountDetails> acttList = new ArrayList<>();
        acttList.add(new AccountDetails("Saaim", "00266767", 2000));
        acttList.add(new AccountDetails("Sudhir", "00266788", 30000));
        acttList.add(new AccountDetails("Gaurav", "00266798", 90000));
        acttList.add(new AccountDetails("Ram", "00266799", 50000));

        System.out.println("Before sorting : ");
        acttList.stream().forEach(acct -> System.out.println("Name: " + acct.getName()));

        // Sort all records on name, using lambda expression with Instance methods of particular objects
        System.out.println("After sorting using lambda expression with Instance methods of particular objects: "); 
        AccountDetails acctDetailsObj= new AccountDetails();
        Collections.sort(acttList, (a,b)->acctDetailsObj.compareByName(a, b));
        acttList.stream().forEach(acct -> System.out.println("Name: " + acct.getName()));

    }

}

Output:

Before sorting : 
Name: Saaim
Name: Sudhir
Name: Gaurav
Name: Ram
After sorting using lambda expression with Instance methods of particular objects: 
Name: Gaurav
Name: Ram
Name: Saaim
Name: Sudhir

Example of Constructor

package com.javatutsworld;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;



public class Java8MethodReference {
    public static void main(String args[]) {

        List<AccountDetails> acttList = new ArrayList<>();
        // prints records, using Constructor References
        AccountsFactory accountsFactory = AccountDetails::new;
        AccountDetails accountDetails1=accountsFactory.getAccountDetails("Saaim", "00266767", 2000);
        AccountDetails accountDetails2=accountsFactory.getAccountDetails("Sudhir", "00266788", 30000);
        AccountDetails accountDetails3=accountsFactory.getAccountDetails("Gaurav", "00266798", 90000);
        AccountDetails accountDetails4=accountsFactory.getAccountDetails("Ram", "00266799", 50000);

        acttList.add(accountDetails1);
        acttList.add(accountDetails2);
        acttList.add(accountDetails3);
        acttList.add(accountDetails4);

        System.out.println("prints records, using Constructor References : ");
        acttList.stream().forEach(acct -> System.out.println("Name: " + acct.getName()));

    }

}

Output:

prints records, using Constructor References : 
Name: Saaim
Name: Sudhir
Name: Gaurav
Name: Ram

Example of Instance methods of an arbitrary object of a particular type

package com.javatutsworld;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;



public class Java8MethodReference {
    public static void main(String args[]) {

        List<AccountDetails> acttList = new ArrayList<>();
        acttList.add(new AccountDetails("Saaim", "00266767", 2000));
        acttList.add(new AccountDetails("Sudhir", "00266788", 30000));
        acttList.add(new AccountDetails("Gaurav", "00266798", 90000));
        acttList.add(new AccountDetails("Ram", "00266799", 50000));

        System.out.println("Before sorting : ");
        acttList.stream().forEach(acct -> System.out.println("Amount: " + acct.getName()));

        String[] array = new String[acttList.size()];
        int index = 0;
        for (AccountDetails value : acttList) {
          array[index] = value.getName();
          index++;
        }
        // Sort all records on name, using method reference of type of Instance methods of an arbitrary object of a particular type

        Arrays.sort(array, String::compareToIgnoreCase); 
        System.out.println("After sorting on name using method reference of type of Instance methods of an arbitrary object of a particular type: ");
        for(String name: array) {
            System.out.println(name);
        }
    }

}

Output:

Before sorting : 
Amount: Saaim
Amount: Sudhir
Amount: Gaurav
Amount: Ram
After sorting on name using method reference of type of Instance methods of an arbitrary object of a particular type: 
Gaurav
Ram
Saaim
Sudhir