Sitemap
Aman Verma

Aman Verma

๐Ÿ“š#Software Engineer || Ai Technolgy || #ReadingIsLife || #techylife https://blog-project-one-silk.vercel.app/

JAVA_STREAM-API_E-5

4 min readFeb 18, 2026

--

๐Ÿ”น Method Reference (::)

โžค Introduction

  • It is a new feature introduced in JDK 1.8.
  • It is an improvement over a lambda expression.
  • While working with lambda, we need to provide the method body (implementation).
  • By using Method Reference (::), we can refer existing method at the project level or the Java API level.
  • To refer to an existing method, we use a double colon (::).
  • We can refer to any type of method:
  • Static method
  • Non-static method
  • Constructor

๐Ÿ”น Types of Method Reference

It is divided into 4 types:

  1. Instance Method Reference
    objectName::instanceMethodName
  2. Static Method Reference
    ClassName::staticMethodName
  3. Constructor Reference
    ClassName::new
  4. Arbitrary Object Method Reference
    ClassName::instanceMethodName

๐Ÿ”น 1) Program on Instance Method Reference

package com.ravi.method_ref;

@FunctionalInterface
interface Worker {
void work();
}
public class MethodReference {
public static void main(String[] args) {
// Lambda
Worker w = () -> System.out.println("Worker is working...");
w.work();
// Method Reference
Worker w1 = new Employee()::work;
w1.work();
}
}
class Employee {
public void work() {
System.out.println("Employee is working");
}
}

๐Ÿ”น 2) Static Method Reference

(ClassName::staticMethodName)

Get Aman Vermaโ€™s stories inย yourย inbox

Join Medium for free to get updates fromย thisย writer.

โšก The following program explains that the interface abstract method name and the method reference method name may be the same or different, butthe parameter list and return type must be the same.

package com.ravi.method_ref;

@FunctionalInterface
interface Worker {
void work();
}
public class MethodReference {
public static void main(String[] args) {
Worker w = Employee::salary;
w.work();
}
}
class Employee {
public static void salary() {
System.out.println("Employee is working for Salary");
}
}

๐Ÿ”น 3) Constructor Reference (ClassName::new)

package com.ravi.constructor_ref;

import java.util.function.Supplier;
class Sample {
public Sample() {
System.out.println("No Argument constructor of Sample class");
}
public void greet() {
System.out.println("Hello Everyone");
}
}
public class Demo1 {
public static void main(String[] args) {
Supplier<Sample> s1 = Sample::new;
Sample sample = s1.get();
sample.greet();
}
}

๐Ÿ”น Constructor Reference with Parameterized Constructor

package com.ravi.constructor_ref;

import java.util.function.Function;
class Student {
private String name;
public Student(String name) {
this.name = name;
}
@Override
public String toString() {
return "Student [name=" + name + "]";
}
}
public class Demo2 {
public static void main(String[] args) {
Function<String, Student> fn1 = Student::new;
Student student = fn1.apply("Ravi");
System.out.println(student);
}
}

๐Ÿ”น Parameterized Constructor (Multiple Parameters)

package com.ravi.constructor_ref;

import java.util.function.BiFunction;
class Employee {
private Integer id;
private String name;
public Employee(Integer id, String name) {
this.id = id;
this.name = name;
}
@Override
public String toString() {
return "Employee [id=" + id + ", name=" + name + "]";
}
}
public class Demo3 {
public static void main(String[] args) {
BiFunction<Integer, String, Employee> fn1 = Employee::new;
Employee obj = fn1.apply(12, "James");
System.out.println(obj);
}
}

๐Ÿ”น Creating an Array using a Constructor Reference

package com.ravi.constructor_ref;

import java.util.function.Function;
record Customer(Integer id, String name) {}
public class Demo4 {
public static void main(String[] args) {
Function<Integer, Customer[]> fn = Customer[]::new;
int size = 3;
Customer[] customers = fn.apply(size);
customers[0] = new Customer(1, "Ravi");
customers[1] = new Customer(2, "Rahul");
customers[2] = new Customer(3, "Raj");
System.out.println("Printing the Customer Data:");
for (Customer customer : customers) {
System.out.println(customer);
}
}
}

๐Ÿ”น 4) Arbitrary Method Reference

(ClassName::instanceMethodName)

โœ” Arbitrary means any type of object.
โœ” By using this technique, we can directly call a non-static method with the class name.
โœ” Internally, the JVM passes the object automatically.

Example:

Lambda Expression Method References

  • s -> s.length() String::length
  • (i1, i2) -> i1.compareTo( i2) Integer::compareTo
  • s -> s.toUpperCase() String::toUpperCase

๐Ÿ”น Program Example 1

package com.ravi.arbit_ref_type;

import java.util.function.Function;
public class ArbitraryRefDemo1 {
public static void main(String[] args) {
Function<String, String> fn1 = String::toUpperCase;
System.out.println(fn1.apply("java"));
System.out.println(fn1.apply("stream"));
}
}

๐Ÿ”น Program Example 2

package com.ravi.arbit_ref_type;

import java.util.TreeSet;
public class ArbitraryRefDemo2 {
public static void main(String[] args) {
TreeSet<String> ts = new TreeSet<>(String::compareTo);
ts.add("C");
ts.add("D");
ts.add("A");
System.out.println(ts);
TreeSet<String> ts1 =
new TreeSet<>((s1, s2) -> s2.compareTo(s1));
ts1.add("C");
ts1.add("D");
ts1.add("A");
System.out.println(ts1);
}
}

๐Ÿ”น Limitation of Method Reference

  • We need to executethe already existing method.
  • We cannot modify the method body.
  • If customization is required, we should use a Lambda Expression.

๐Ÿ”น Sorting Example (Lambda vs Method Reference)

package com.ravi.arbit_ref_type;

import java.util.*;
public class ArbitraryRefDemo3 {
public static void main(String[] args) {
List<Integer> listOfNumbers =
Arrays.asList(9, 5, 6, 2, 4, 1);
// By using Lambda
Collections.sort(listOfNumbers,
(i1, i2) -> i2.compareTo(i1));
listOfNumbers.forEach(System.out::println);
System.out.println("------------------");
// By using Method Reference
Collections.sort(listOfNumbers,
Integer::compareTo);
listOfNumbers.forEach(System.out::println);
// Sorting Strings
String[] players =
{"Virat", "Rohit", "Zaheer", "Rishab", "Abhishek"};
Arrays.sort(players,
String::compareTo);
System.out.println(Arrays.toString(players));
}
}

๐Ÿ”น Internal Working of Arbitrary Method Reference

package com.ravi.arbit_ref_type;

@FunctionalInterface
interface MyFunction<T, U, V, R> {
R myApply(T t, U u, V v);
}
public class ArbitraryReferenceDemo4 {
public static void main(String[] args) {
// Lambda
MyFunction<Addition, String, String, Integer> myLambda =
(add, str1, str2) -> add.doSum(str1, str2);
System.out.println(
myLambda.myApply(new Addition(), "100", "200"));
// Method Reference
MyFunction<Addition, String, String, Integer> myRef =
Addition::doSum;
System.out.println(
myRef.myApply(new Addition(), "500", "400"));
}
}
class Addition {
public Integer doSum(String n1, String n2) {
return Integer.parseInt(n1)
+ Integer.parseInt(n2);
}
}

โœ… Final Conclusion

โœ” Method Reference is cleaner and shorter than Lambda.
โœ” Used when implementation already exists.
โœ” Introduced in Java 8.
โœ” Works only with Functional Interfaces.

--

--

Aman Verma
Aman Verma

Written by Aman Verma

๐Ÿ“š#Software Engineer || Ai Technolgy || #ReadingIsLife || #techylife https://blog-project-one-silk.vercel.app/