Understanding Function Interface in Java

Introduction

In this blog we will learn how to use Function interface in Java with examples.

As the name suggests just like functions, Function<T, R> will take a input, perform some operations on it and return a result.

Function<T, R> functional method is R apply(T t).

Function<T, R> accepts argument of type T and returns argument of type R

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

Basic example

Let us take a look at a simple example of function interface.

In the below example we take input as integer and return double of the number as output

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
package com.examples;

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

public class App {

    public static void main(String[] args) {
        Function<Integer,Integer> doubleofNumber = x -> x*2;
        System.out.println(doubleofNumber.apply(100)); // 200
    }
}

Example 2

In the below example it takes string input and returns the length of the string.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
package com.examples;

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

public class App {

    public static void main(String[] args) {
        Function<String,Integer> length = x -> x.length();
        System.out.println(length.apply("Harish Gowda")); // 2
        System.out.println(length.apply("Shanu"));  //5
    }
}

Composing functions

We can take 2 function interface and join them in a pipeline.

The output of the first function interface is input to second interface in the pipeline.

In the below example, first function interface accepts string as input and returns length of the string as output.

Length of the string is input to second interface which doubles it.

We can compose 2 interfaces using andThen method.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
package com.examples;

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

public class App {

    public static void main(String[] args) {
        Function<String,Integer> length = x -> x.length();
        Function<Integer,Integer> doubleit = x -> x * 2;

        Function<String,Integer> composed= length.andThen(doubleit);

        System.out.println(composed.apply("Harish Gowda")); // 24
        System.out.println(composed.apply("Shanu"));  // 10
    }
}

Function identity

identity method of functional interface always returns its input argument provided as it is.

1
2
3
static <T> Function<T, T> identity() {
  return t -> t;
}

In the below example, it takes input as string and returns the input argument

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
package com.examples;

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

public class App {

    public static void main(String[] args) {
        Function<String,String> identity = Function.identity();
        System.out.println(identity.apply("This is input")); //This is input

    }
}

Mapping a list with Function identity

We can create a copy of the input list using Function.identity().

In the below we take list of numbers and copy them into different list by using Function.identity() in the mapping function of the stream.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.examples;

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

public class App {

    public static void main(String[] args) {

        List<Integer> nums = Arrays.asList(10,20,30,40);

        List<Integer> result = nums.stream()
                .map(Function.identity())
                .collect(Collectors.toList());

        System.out.println(result);


    }
}

Conclusion

I hope this clarifies how to use Function<T, R> interface in Java.

Learn more functional interfaces

  1. Consumer interface
  2. Predicate interface
  3. BiPredicate interface
  4. BiFunction interface
  5. Supplier interface