# Function and BiFunction Functional Interface

In my previous blog, I’ve already talked about Predicate and BiPredicate Functional Interface. In this blog, I’ll talk about next predefined Functional Interface i.e. Function and BiFunction Functional Interface.
Function is a Functional Interface which accept single input and returns another. The functional method of Predicate is R apply(T t).

@FunctionalInterface
Public interface Function<T, R> { …}

Here is a simple source code of java.util.function.Function
package java.util.function;

import java.util.Objects;

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

Where R apply (T t) is an abstract method where T is the type of the input to the Function and will return type of R.

Example 1:

import java.util.function.Function;

public class FunctionExample {

public static void main(String[] args) {

// Calling Function Functional Interface without using Lambda Expression
FunctionExample.GetStringLength function = new FunctionExample().new GetStringLength();
System.out.println("Length of String is : " + function.apply("www.waheedtechblog.com"));

// Using Lambda Expression
Function<String, Integer> f1 = (name) -> name.length();
System.out.println("Lambda Expression, Length of String is : " + f1.apply("www.waheedtechblog.com"));
}

class GetStringLength implements Function<String, Integer> {

@Override
public Integer apply(String name) {
return name.length();
}
}
}

Example 2:
import java.util.Arrays;
import java.util.List;
import java.util.function.Function;

public class FunctionExample2 {

public static void main(String[] args) {

FunctionExample2 functionExample2 = new FunctionExample2();
Function<Student, String> f2 = student -> student.getName();

List<Student> students = functionExample2.populateStudentList();
for (Student student : students) {
System.out.println("Student Name: " + f2.apply(student));
}
}

class Student {
private String name;
private int age;

public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

public boolean equals(Object obj) {
Student student = (Student) obj;
if ((this.getName().equals(student.getName()) && this.getAge() == student.getAge())) {
return true;
} else {
return false;
}
}
}

public List<Student> populateStudentList() {
List<Student> studentList = Arrays.asList(new Student("Abdul", 31), new Student("Waheed", 29),
new Student("DummyUser", 20), new Student("Adam", 25));
return studentList;

}

}

Output:
Student Name: Abdul
Student Name: Waheed
Student Name: DummyUser

Apart from R Apply (T t) method, Function also has 2 default method and one static method.

 Modifier and Type Method and Description default  Function andThen(Function after) Returns a composed function that first applies this function to its input, and then applies the after function to the result. default  Function compose(Function before) Returns a composed function that first applies the before function to its input, and then applies this function to the result. static  Function identity() Returns a function that always returns its input argument.

1.     `andThen():` default method combines the current Function instance with another one and returns a combined Function instance which applies the two functions in sequence with the function passed as parameter to `andThen()` being invoked after the current function.

2.     `compose():` default method combines the current Function instance with another one and returns a combined Function instance which applies the two functions in sequence with the parameter function to `compose()` being invoked before the current function.

3.     `identity()`: it just returns back the parameter which it gets as input.

Let’s understand it with few more example

Example 3:

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

public class FunctioalExample3 {

public static void main(String[] args) {

FunctioalExample3 functioalExample3 = new FunctioalExample3();

// return the name of Student
Function<Student, String> f1 = student -> student.getName();
// return name in uppercase
Function<String, String> f2 = name -> name.toUpperCase();

Function<Student, Student> f3 = student -> {
String name = "Adding via Compose " + student.getName();
return new Student(name, student.getAge());
};

Function<String, String> f4 = Function.identity();

// andThen default method
System.out.println("=============================");
System.out.println("=====USING andThen Default Function======");
List<Student> students = functioalExample3.populateStudentList();
for (Student student : students) {
System.out.println("Student Name: " + f1.andThen(f2).apply(student));
}

// compose default method
System.out.println("\n");
System.out.println("=============================");
System.out.println("=====USING default COMPOSE FUNCTION======");
for (Student student : students) {
System.out.println("Student Name: " + f1.compose(f3).apply(student));
}

// Identity Static method
System.out.println("\n");
System.out.println("=============================");
System.out.println("=====Identity Static method======");
for (Student student : students) {
System.out.println("Student Name: " + f4.apply(student.getName()));
}

}

public List<Student> populateStudentList() {
List<Student> studentList = Arrays.asList(new Student("Abdul", 31), new Student("Waheed", 29),
new Student("DummyUser", 20), new Student("Adam", 25));
return studentList;

}

}

class Student {
private String name;
private int age;

public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

public boolean equals(Object obj) {
Student student = (Student) obj;
if ((this.getName().equals(student.getName()) && this.getAge() == student.getAge())) {
return true;
} else {
return false;
}
}
}

Output:

=============================
=====USING andThen Default Function======
Student Name: ABDUL
Student Name: WAHEED
Student Name: DUMMYUSER

=============================
=====USING default COMPOSE FUNCTION======
Student Name: Adding via Compose Abdul
Student Name: Adding via Compose Waheed
Student Name: Adding via Compose DummyUser

=============================
=====Identity Static method======
Student Name: Abdul
Student Name: Waheed
Student Name: DummyUser

# BiFunction

It is very similar to Function Functional Interface. The only difference is just that it will accept two input arguments instead of one and as usual will return another.

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

Let’s see another example

Example 4:

import java.util.function.BiFunction;

public class BiFunctionExample {

public static void main(String[] args) {
BiFunction<Integer, Integer, Integer> area = (a, b) -> a * b;

System.out.println("Area of Rectangle: " + area.apply(5, 10));

}

}
Output:

Area of Rectangle: 50

That’s it for Function and BiFunction Functional Interface, Will talk about other Predefined Functional Interface in my next blog.

Happy Coding…!!!