The Function Functional interface takes a single input and returns any value. The function interface is located in java.util.function package. It has a Single Abstract Method (SAM) apply(), which accepts the generic object type T and returns object type R.
Java Function Example
Whenever we create a Lambda Expression, which takes a single input and can return any value, then the Function can be used as a target for the lambda expression. The Function interface is similar to Predicate functional interface; the only change is the return type.
Methods in Function Interface
- R apply(T t) – This method takes a single generic argument T and returns an object of type R
- default <V> Function<T,V> andThen(Function<? super R,? extends V> after) – This is a default method, returns a composed function. The input function will be executed and on the result after function will be executed.
- default <V> Function<V,R> compose(Function<? super V,? extends T> before) – This is a default method, returns a composed function. The before function will be executed first and on the result input function will be executed.
- static <T> Function<T,T> identity() – This static method returns its input argument.
1. Java Function apply() method example
The apply() method of the Function interface can take any object type as an argument and can return any object type.
Let’s build a Function that returns the capitalizes of the String passed to it.
package com.javainterviewpoint; import java.util.function.Function; public class ToUpperFunction { public static void main(String[] args) { Function<String, String> capitalize = val -> val.toUpperCase(); System.out.println(capitalize.apply("WeLcoMe")); System.out.println(capitalize.apply("JaVaInTeRvIeWpOiNt")); } }
Output:
WELCOME JAVAINTERVIEWPOINT
In the above code, we have created a Function that capitalizes the string passed to it.
Function<String, String> capitalize = val -> val.toUpperCase();
We can invoke the capitalize function by passing a string argument to the apply() method.
We have passed a string as input and got a string as output. There are no rules that the return type has to be the same as the input type.
Let’s create a new Function, which takes in a string input and returns the length of the string, which will be an integer output.
package com.javainterviewpoint; import java.util.function.Function; public class LengthOfString { public static void main(String[] args) { Function<String, Integer> length = val -> val.length(); System.out.println("Length of \"Hello\" is: " + length.apply("Hello")); System.out.println("Length of \"Welcome\" is: " + length.apply("Welcome")); } }
Output:
Length of "Hello" is: 5 Length of "Welcome" is: 7
The Function interface can also be used in the Streams; the map() method of the stream takes the Function as its argument.
Let’s create a Function which squares the number passed to it.
package com.javainterviewpoint; import java.util.Arrays; import java.util.List; import java.util.function.Function; public class SquareFunction { public static void main(String[] args) { Function<Integer, Integer> squareFunction = num -> num * num; List numberList = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9); numberList.stream().map(num -> (squareFunction.apply(num))) .forEach(System.out::println); } }
Output:
1 4 9 16 25 36 49 64 81
The Function can be used on custom objects as well. Let’s create a function that adds an internal mark of 20 to each student.
Student.java
package com.javainterviewpoint; public class Student { private int id; private int mark; private String name; public Student() { super(); } public Student(int id, int mark, String name) { super(); this.id = id; this.mark = mark; this.name = name; } public int getId() { return id; } public void setId(int id) { this.id = id; } public int getMark() { return mark; } public void setMark(int mark) { this.mark = mark; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
StudentPredicate.java
package com.javainterviewpoint; import java.util.ArrayList; import java.util.List; import java.util.function.Function; public class StudentFunction { public static void main(String[] args) { List<Student> studentList = new ArrayList(); studentList.add(new Student(1, 45, "Alice")); studentList.add(new Student(2, 65, "Bob")); studentList.add(new Student(3, 80, "Clair")); studentList.add(new Student(4, 20, "Dom")); Function<Integer, Integer> markIncrement = mark -> mark + 20; System.out.println("** Student marks after adding internal marks **"); studentList.stream() .map(student -> markIncrement.apply(student.getMark())) .forEach(System.out::println); } }
In the above, we have created a simple function which adds 20 marks to each student.
Output:
** Student marks after adding internal marks ** 65 85 100 40
2. Java Function andThen() method example
The andThen() method of the Function interface, the input function will be executed first, and on the result the second function (andThen) will be executed.
We will be performing same operation which we did in the above code, but this time we will use the two functions and andThen method.
package com.javainterviewpoint; import java.util.ArrayList; import java.util.List; import java.util.function.Function; public class StudentFunction { public static void main(String[] args) { List<Student> studentList = new ArrayList(); studentList.add(new Student(1, 25, "Adam")); studentList.add(new Student(2, 35, "Bob")); studentList.add(new Student(3, 45, "Danny")); studentList.add(new Student(4, 55, "Will")); Function<Student, Integer> getMark = student -> student.getMark(); Function<Integer, Integer> markIncrement = mark -> mark + 20; System.out.println("** Student marks after adding internal marks **"); studentList.stream().map(student -> getMark.andThen(markIncrement).apply(student)).forEach(System.out::println); } }
In the above, we have the first function, getMark takes the Student object as input and returns the student’s marks. The second function, markIncrement, add 20 marks to each student.
Since we have used getMark.andThen(markIncrement), the getMark function will be executed first, and on top of it, the markIncrement get executed.
Output:
** Student marks after adding internal marks ** 45 55 65 75
3. compose() method example
The compose() method is just the reverse of the andThen() method. The second functional interface will be executed first and followed by the first functional interface.
package com.javainterviewpoint; import java.util.ArrayList; import java.util.List; import java.util.function.Function; public class StudentFunction { public static void main(String[] args) { List studentList = new ArrayList(); studentList.add(new Student(1, 25, "Adam")); studentList.add(new Student(2, 35, "Bob")); studentList.add(new Student(3, 45, "Danny")); studentList.add(new Student(4, 55, "Will")); Function<Student, String> getName = student -> student.getName(); Function<String, String> addCountry = name -> name + " US"; System.out.println("** Student after adding Country **"); studentList.stream().map(student -> addCountry.compose(getName).apply(student)).forEach(System.out::println); } }
We have the second function getName will be executed first and followed by addCountry function.
** Student after adding Country ** Adam US Bob US Danny US Will US
Leave a Reply