Java’s Function<T, R> interface with practical use cases.

What is Function<T, R>?

  • Part of java.util.function (Java 8+)
  • Represents a function that:
  • Takes one argument of type T
  • Returns a result of type R
  • one abstract method:
R apply(T t);
  • Often used with lambda expressions and method references.

Example 1 – Basic Transformation

import java.util.function.Function;

public class FunctionExample1 {
  public static void main(String[] args) {
    // Function to convert String to Integer (length of string)
    Function<String, Integer> stringLength = str -> {
      if (str == null) return 0; // null safety
      return str.length();
    };

    System.out.println(stringLength.apply("Hello")); // 5
    System.out.println(stringLength.apply(""));   // 0
  }
}

Use case: Simple data transformation.

Example 2 – Chaining with andThen and compose

import java.util.function.Function;

public class FunctionExample2 {
    public static void main(String[] args) {
        Function<Integer, Integer> multiplyBy2 = x -> x * 2;
        Function<Integer, Integer> add10 = x -> x + 10;

        // First multiply, then add
        Function<Integer, Integer> multiplyThenAdd = multiplyBy2.andThen(add10);
        System.out.println(multiplyThenAdd.apply(5)); // (5*2)+10 = 20

        // First add, then multiply
        Function<Integer, Integer> addThenMultiply = multiplyBy2.compose(add10);
        System.out.println(addThenMultiply.apply(5)); // (5+10)*2 = 30
    }
}

Use case: Building function pipelines.

Example 3 – Using with Streams

import java.util.Arrays;

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

public class FunctionExample3 {
    public static void main(String[] args) {
        List<String> names = Arrays.asList("Alice", "Bob", "Charlie");

        // Function to convert name to uppercase
        Function<String, String> toUpper = String::toUpperCase;

        List<String> upperNames = names.stream()
                                       .map(toUpper)
                                       .collect(Collectors.toList());

        System.out.println(upperNames); // [ALICE, BOB, CHARLIE]
    }
}

Use case: Transforming collections in Stream API.

Example 4 – Mapping Complex Objects

Java

コードをコピー
import java.util.Arrays;
import java.util.List;
import java.util.function.Function;

class User {
    String name;
    int age;
    User(String name, int age) { this.name = name; this.age = age; }
}

public class FunctionExample4 {
    public static void main(String[] args) {
        List<User> users = Arrays.asList(
            new User("Alice", 25),
            new User("Bob", 30)
        );

        // Extract user names
        Function<User, String> getName = user -> user.name;

        users.stream()
             .map(getName)
             .forEach(System.out::println);
    }
}

Use case: Extracting fields from objects.

βœ… Key Points:

  • Function<T, R> is stateless unless you capture external variables.
  • Use andThen and compose for function composition.
  • Works seamlessly with Streams and method references.
  • For primitive types, use specialized versions like IntFunctionLongFunction, etc., to avoid boxing.


← Back to Learning Journey