Java Functional Interfaces – Function & BiFunction
This section describes the functional interfaces Function and BiFunction defined in java.util.Function package in Java 8.
What is it?
@FunctionalInterface
public interface Function<T,R>
{
R apply(T t);
}
@FunctionalInterface
public interface Function<T,U,R>
{
R apply(T t, U u);
}
Function and BiFunction interface has two default methods:
Why it was introduced?
When should you use it?
Examples
The examples illustrated below use the following Employee POJO class:
package org.examples;
public class Employee { private String name; private Integer hourRate; public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getHourRate() { return hourRate; } public void setHourRate(Integer hourRate) { this.hourRate = hourRate; } public Employee(String name, Integer hourRate) { super(); this.name = name; this.hourRate = hourRate; }
} |
package org.examples;
import java.util.ArrayList; import java.util.List; import java.util.function.Function;
public class FunctionExample1 { public static void main(String[] args) { List<Employee> employees = new ArrayList<>(); employees.add(new Employee(“Jack”,10)); employees.add(new Employee(“Robert”,50)); employees.add(new Employee(“David”,30)); employees.add(new Employee(“Abhi”,20));
//Lambda Function<Employee, String> nameFunc = emp -> emp.getName(); List<String> namesList1 = getNamesFromEmployeeList(employees, nameFunc); System.out.println(namesList1);
//Method reference FunctionExample1 obj = new FunctionExample1(); List<String> namesList2 = getNamesFromEmployeeList(employees, obj::getEmployeeName); System.out.println(namesList2); }
public static List<String> getNamesFromEmployeeList (List<Employee> employeeList, Function<Employee,String> func) { List<String> employeeNames = new ArrayList<>(); for(Employee emp : employeeList) { String name = func.apply(emp); employeeNames.add(name); } return employeeNames; }
public String getEmployeeName(Employee employee) { return employee.getName(); } }
|
Output: [Jack, Robert, David, Abhi] [Jack, Robert, David, Abhi] |
package org.examples;
import java.util.ArrayList; import java.util.List; import java.util.function.Function;
public class FunctionExample2 { public static void main(String[] args) { List<Employee> employees = new ArrayList<>(); employees.add(new Employee(“Jack”,10)); employees.add(new Employee(“Robert”,50)); employees.add(new Employee(“David”,30)); employees.add(new Employee(“Abhi”,20));
Function<Employee, Integer> hourRate = emp -> emp.getHourRate();
Function<Integer, Integer> dailyRate = hourly -> hourly * 8;
//andThen List<Integer> rateList1 = getDailyRateList(employees, hourRate.andThen(dailyRate)); System.out.println(rateList1);
//compose List<Integer> rateList2 = getDailyRateList(employees, dailyRate.compose(hourRate)); System.out.println(rateList2); }
public static List<Integer> getDailyRateList(List<Employee> employeeList, Function<Employee,Integer> func) { List<Integer> rateList = new ArrayList<>(); for(Employee emp : employeeList) { Integer dailyRate = func.apply(emp); rateList.add(dailyRate); } return rateList; }
public String getEmployeeName(Employee employee) { return employee.getName(); } } |
Output: [80, 400, 240, 160] [80, 400, 240, 160]
|
package org.examples;
import java.util.function.BiFunction;
public class FunctionExample3 { public static void main(String[] args) { BiFunction<String,Integer,Employee> employeeCreator = (name,rate) -> { return new Employee(name,rate); }; Employee newEmployee = employeeCreator.apply(“Ankit”, 100); System.out.println(“New Employee: “+newEmployee.getName());
} } |
Output: New Employee: Ankit |
package org.examples;
import java.util.ArrayList; import java.util.List; import java.util.function.BiFunction;
public class FunctionExample4 { public static void main(String[] args) {
List<Employee> employees = new ArrayList<>(); employees.add(new Employee(“Jack”,10)); employees.add(new Employee(“Robert”,50)); employees.add(new Employee(“David”,30)); employees.add(new Employee(“Abhi”,20)); employees.add(new Employee(“Ankit”,70));
//find employees having name starting with a prefix BiFunction<Employee,String,Employee> nameStartsWithFunc = (employee,namePrefix) -> {
if(employee.getName().startsWith(namePrefix)) { return employee; } return null; };
String prefix = “A”; List<Employee> result1 = filterByName(employees, prefix, nameStartsWithFunc); System.out.println(“Employees having name starting with “+prefix); result1.forEach(emp -> System.out.println(emp.getName()));
//find employees having rate greater than input BiFunction<Employee,Integer,Employee> rateGreaterThanFunc = (employee,rate) -> { if(employee.getHourRate() > rate) { return employee; } return null; };
Integer minRate = 30; List<Employee> result2 = filterByRate(employees, minRate, rateGreaterThanFunc); System.out.println(“Employees having rate greater than “+minRate); result2.forEach(emp -> System.out.println(emp.getName())); }
public static List<Employee> filterByName (List<Employee> employeeList, String str, BiFunction<Employee,String,Employee> func) { List<Employee> employees = new ArrayList<>(); for(Employee emp : employeeList) { Employee result = func.apply(emp, str); if(result!=null) { employees.add(result); } } return employees; }
public static List<Employee> filterByRate (List<Employee> employeeList, Integer rate, BiFunction<Employee,Integer,Employee> func) { List<Employee> employees = new ArrayList<>(); for(Employee emp : employeeList) { Employee result = func.apply(emp, rate); if(result!=null) { employees.add(result); } } return employees; } }
|
Output: Employees having name starting with A Abhi Ankit Employees having rate greater than 30 Robert Ankit |
Leave a Reply