Over

120,000

Worldwide

Saturday - Sunday CLOSED

Mon - Fri 8.00 - 18.00

Call us

 

Java Functional Interfaces – Function & BiFunction

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?

 Function: A functional interface that represents a method that accepts one argument and returns a result.

.

@FunctionalInterface

public interface Function<T,R>

{

  R apply(T t);

}

.

 BiFunction: A functional interface that represents a method that accepts two arguments and returns a result.

.

@FunctionalInterface

public interface Function<T,U,R>

{

  R apply(T t, U u);

}

.

Function and BiFunction interface has two default methods:

.

1.compose() – returns a composed function that first applies the before function to its input, and then applies this function to the result.
2.andThen() – returns a composed function that first applies this function to its input, and then applies the after function to the result.

Why it was introduced?

.

 It was introduced to implement functional programming in Java. Functional programming allows using functions as expressions and passing functions as statements.
 This improves modularity and helps in making the code more concise.
 Functional interfaces can be used as assignment target for a lambda expression or method reference.

.

When should you use it?

.

 When we want to convert one type of object to another.
 It is used in the map operation of the Stream API.

.

.

.

.

.

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;

      }

      

}

.

.

 Function

.

1.This implementation shows usage of apply() method, taking a list of Employee objects and populating a list of (String) names of the employees, by using lambda expression and method reference.

.

.

.

.

2.This implementation shows usage of andThen() and compose() method, taking a list of Employee objects having hourly rate and converting to a list containing (Integer) daily rate of the employees.

.

.

.

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]

.

 BiFunction

.

1.This implementation takes a (String) name and (Integer) hourly rate as arguments and creates an Employee object with those values.

.

  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

.

.

2.This implementation takes a list of employees and a filter as input, and returns a list of employees passing the filter.

.

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

Your email address will not be published. Required fields are marked *

Working Hours

  • Monday 9am - 6pm
  • Tuesday 9am - 6pm
  • Wednesday 9am - 6pm
  • Thursday 9am - 6pm
  • Friday 9am - 6pm
  • Saturday Closed
  • Sunday Closed