Programming & Development / March 27, 2025

Supplier vs Function in Java 8 with Examples

java 8 supplier vs function java functional interfaces java supplier example java function example lazy initialization java java 8 lambda java util function

Learn the differences between Supplier and Function in Java 8, including their purpose, method signatures, use cases, and practical examples to help you write cleaner and more efficient functional code.

🔍 Introduction

Java 8 introduced several functional interfaces under the java.util.function package to support functional programming. Two commonly used interfaces are:

  • Supplier<T>: for providing values without input.
  • Function<T, R>: for transforming input into output.

Although both are single-method interfaces, they serve different purposes. Let's break them down.

1️⃣ What is a Supplier?

📌 Purpose:

Represents a supplier of results. It takes no arguments and returns a result.

📌 Method:

java

T get();

📌 Signature:

java

@FunctionalInterface
public interface Supplier<T> {
    T get();
}

✅ Example:

java

import java.util.function.Supplier;

public class SupplierExample {
    public static void main(String[] args) {
        // Lambda
        Supplier<String> lambdaSupplier = () -> "Hello, Supplier!";
        
        // Method Reference
        Supplier<String> methodRefSupplier = SupplierExample::getMessage;

        System.out.println(lambdaSupplier.get());      // Output: Hello, Supplier!
        System.out.println(methodRefSupplier.get());   // Output: Hello, Method Reference!
    }

    public static String getMessage() {
        return "Hello, Method Reference!";
    }
}

2️⃣ What is a Function?

📌 Purpose:

Represents a function that takes one argument and produces a result.

📌 Method:

java

R apply(T t);

📌 Signature:

java

@FunctionalInterface
public interface Function<T, R> {
    R apply(T t);
}

✅ Example:

java

import java.util.function.Function;

public class FunctionExample {
    public static void main(String[] args) {
        // Lambda
        Function<String, Integer> lambdaFunction = s -> s.length();

        // Method Reference
        Function<String, Integer> methodRefFunction = String::length;

        System.out.println(lambdaFunction.apply("Hello, Function!"));       // Output: 16
        System.out.println(methodRefFunction.apply("Hello, Method Reference!")); // Output: 23
    }
}

🔄 Key Differences: Supplier vs Function

FeatureSupplierFunctionTakes Input?❌ No✅ Yes (one input of type T)Returns Output?✅ Yes (type T)✅ Yes (type R)Method Nameget()apply(T t)Common Use CasesLazy initialization, cachingData transformation, mapping

🛠️ Real-World Examples

✅ Supplier Example: Lazy Initialization

java

import java.util.function.Supplier;

public class LazyInitialization {
    private static Supplier<ExpensiveObject> expensiveObjectSupplier = ExpensiveObject::new;

    public static void main(String[] args) {
        // Object is created only when get() is called
        ExpensiveObject obj = expensiveObjectSupplier.get();
        obj.performAction();
    }
}

class ExpensiveObject {
    ExpensiveObject() {
        System.out.println("ExpensiveObject created!");
    }

    void performAction() {
        System.out.println("Action performed!");
    }
}

🧠 Use Case: Delay creating heavy objects until actually needed.

✅ Function Example: Mapping List of Strings to Lengths

java

import java.util.Arrays;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

public class FunctionExample {
    public static void main(String[] args) {
        List<String> fruits = Arrays.asList("apple", "banana", "cherry");

        Function<String, Integer> stringLengthFunction = s -> s.length();

        List<Integer> lengths = fruits.stream()
                                      .map(stringLengthFunction)
                                      .collect(Collectors.toList());

        System.out.println(lengths);  // Output: [5, 6, 6]
    }
}

🧠 Use Case: Convert input data (strings) into something else (lengths).

✅ Summary

  • Use Supplier<T> when you don't need any input but want to generate or retrieve a value.
  • Use Function<T, R> when you need to transform an input of type T into a result of type R.

Choosing the right interface helps write cleaner, more expressive, and modular Java 8 code.


Comments

No comments yet

Add a new Comment

NUHMAN.COM

Information Technology website for Programming & Development, Web Design & UX/UI, Startups & Innovation, Gadgets & Consumer Tech, Cloud Computing & Enterprise Tech, Cybersecurity, Artificial Intelligence (AI) & Machine Learning (ML), Gaming Technology, Mobile Development, Tech News & Trends, Open Source & Linux, Data Science & Analytics

Categories

Tags

©{" "} Nuhmans.com . All Rights Reserved. Designed by{" "} HTML Codex