Java BiFunction Tutorial with Examples
1. BiFunction
In Java 8, BiFunction is a functional interface which represents an operator that accepts two input values and returns one value.
Source code of BiFunction interface:
BiFunction
@FunctionalInterface
public interface BiFunction<T, U, R> {
R apply(T t, U u);
default <V> BiFunction<T, U, V> andThen(Function<? super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t, U u) -> after.apply(apply(t, u));
}
}
See also: Function is a functional interrface similar to BiFunction which accepts an input parameter and returns a value.
Example: Create a BiFunction that accepts 2 input parameters of type String and returns a String.
BiFunctionEx1.java
package org.o7planning.bifunction.ex;
import java.util.function.BiFunction;
public class BiFunctionEx1 {
public static void main(String[] args) {
// Create a BiFunction object directly.
// Accepts 2 input parameters of type String and return a String.
BiFunction<String, String, String> namer //
= (firstName, lastName) -> firstName + " " + lastName;
String fullName = namer.apply("James", "Smith");
System.out.println(fullName);
}
}
Output:
James Smith
Below is a list of methods in java.util package using BiFunction:
V | HashMap.compute(K key, BiFunction<? super K,? super V,? extends V> remappingFunction) |
V | Hashtable.compute(K key, BiFunction<? super K,? super V,? extends V> remappingFunction) |
default V | Map.compute(K key, BiFunction<? super K,? super V,? extends V> remappingFunction) |
V | TreeMap.compute(K key, BiFunction<? super K,? super V,? extends V> remappingFunction) |
V | HashMap.computeIfPresent(K key, BiFunction<? super K,? super V,? extends V> remappingFunction) |
V | Hashtable.computeIfPresent(K key, BiFunction<? super K,? super V,? extends V> remappingFunction) |
default V | Map.computeIfPresent(K key, BiFunction<? super K,? super V,? extends V> remappingFunction) |
V | TreeMap.computeIfPresent(K key, BiFunction<? super K,? super V,? extends V> remappingFunction) |
V | HashMap.merge(K key, V value, BiFunction<? super V,? super V,? extends V> remappingFunction) |
V | Hashtable.merge(K key, V value, BiFunction<? super V,? super V,? extends V> remappingFunction) |
default V | Map.merge(K key, V value, BiFunction<? super V,? super V,? extends V> remappingFunction) |
V | TreeMap.merge(K key, V value, BiFunction<? super V,? super V,? extends V> remappingFunction) |
default void | Map.replaceAll(BiFunction<? super K,? super V,? extends V> function) |
Example: A Map object contains mappings between country name and apartment renting cost in a month. We update 10% increase except Vietnam.
BiFunctionEx2.java
package org.o7planning.bifunction.ex;
import java.util.HashMap;
import java.util.Map;
import java.util.function.BiFunction;
public class BiFunctionEx2 {
public static void main(String[] args) {
// Data in 2021.
// String country --> Float price to rent an apartment per month ($).
Map<String, Float> pricingMap = new HashMap<String, Float>();
pricingMap.put("Singapore", 2147f);
pricingMap.put("Sweden", 890f);
pricingMap.put("Japan", 770f);
pricingMap.put("Mexico", 345f);
pricingMap.put("Vietnam", 305f);
pricingMap.put("India", 156f);
// Pricing Map
System.out.println(pricingMap);
System.out.println();
// (String,Float) --> Float.
BiFunction<String, Float, Float> biFunction = (country, price) -> {
if (country.equals("Vietnam")) {
return price;
}
return price * 1.1f;
};
pricingMap.replaceAll(biFunction);
// After replacement.
System.out.println("After replacement:\n");
System.out.println(pricingMap);
}
}
Output:
{Sweden=890.0, Vietnam=305.0, Singapore=2147.0, Japan=770.0, Mexico=345.0, India=156.0}
After replacement:
{Sweden=979.0, Vietnam=305.0, Singapore=2361.7, Japan=847.0, Mexico=379.5, India=171.6}
2. andThen(Function after)
andThen(after) method returns a combined BiFunction. First, BiFunction.apply is called to turn (T,U) into (R). Then after.apply is called to turn (R) into (V). If an error occurs in one of the above 2 steps, the error is passed to the caller. If an error occurs at the current BiFunction then after is ignored.
Source code of andThen(after) method can be a bit confusing:
@FunctionalInterface
public interface BiFunction<T, U, R> {
R apply(T t, U u);
default <V> BiFunction<T, U, V> andThen(Function<? super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t, U u) -> after.apply(apply(t, u));
}
}
And we can interpret the above source code in a simpler way:
BiFunction (Simpler)
@FunctionalInterface
public interface BiFunction<T, U, R> {
// (T,U) -> R
R apply(T t, U u);
// (T,U) -> V
default <V> BiFunction<T, U, V> andThen(Function<? super R, ? extends V> after) {
Objects.requireNonNull(after);
BiFunction<T, U, V> ret = (T t, U u) -> {
// (T,U) -> R
R r = this.apply(t, u);
// R -> V
V v = after.apply(r);
return v;
};
return ret;
}
}
Example:
BiFunction_andThen_ex1.java
package org.o7planning.bifunction.ex;
import java.util.function.Function;
public class BiFunction_andThen_ex1 {
public static void main(String[] args) {
// BiFunction: (char,int) --> (String)
// Example: ('0', 3) --> "000"
BiFunction<Character, Integer, String> bif = (ch, n) -> {
String s="";
for(int i=0;i< n;i++) {
s+=ch;
}
return s;
};
// Function: (String) --> (String)
// Example: "abc" --> "ABC".
Function<String,String> after = s -> s.toUpperCase();
// Test:
String result = bif.andThen(after).apply('a', 3);
System.out.println("Result: " + result);
}
}
Output:
Result: AAA
3. BiFunction + Method reference
If a method takes two parameters and returns a value then its reference can be considered as a BiFunction.
Example: Math.max(int,int) static method accepts 2 parameters and returns an Integer. So its reference is Math::max can be considered a BiFunction.
BiFunction_mRef_ex1.java
package org.o7planning.bifunction.ex;
public class BiFunction_mRef_ex1 {
public static void main(String[] args) {
// Create a BiFunction from method reference.
// (Integer,Integer) --> (Integer)
BiFunction<Integer, Integer, Integer> biFunc = Math::max;
int max = biFunc.apply(10, 20); // 20
System.out.println("Max: " + max); // 20
}
}
Output:
Max: 20
Example: BiFunction + non-static method reference:
BiFunction_mRef_ex2.java
package org.o7planning.bifunction.ex;
public class BiFunction_mRef_ex2 {
public static void main(String[] args) {
CardTemplate template = new CardTemplate("Designed by Tom");
// Create a BiFunction from method reference.
// (String,String) --> (String)
BiFunction<String, String, String> biFunc = template::getContent;
String cardContent = biFunc.apply("Eli", "Smith");
System.out.println(cardContent);
}
}
class CardTemplate {
private String someInfo;
public CardTemplate(String someInfo) {
this.someInfo = someInfo;
}
public String getContent(String firstName, String lastName) {
return "----- ~~~~~ -----\n" //
+ "First name: " + firstName + "\n" //
+ "Last name: " + lastName + "\n" //
+ this.someInfo;
}
}
Output:
----- ~~~~~ -----
First name: Eli
Last name: Smith
Designed by Tom
4. BiFunction + Constructor reference
As we all know, a constructor is a special method that returns an object. So, if a constructor has 2 parameters, its reference will be considered as a BiFunction.
BiFunction_cRef_ex1.java
package org.o7planning.bifunction.ex;
public class BiFunction_cRef_ex1 {
public static void main(String[] args) {
// Create a BiFunction from constructor reference.
// (String,Integer) --> (Staff)
BiFunction<String, Integer, Staff> biFunc = Staff::new;
Staff tom = biFunc.apply("Tom", 1000);
Staff jerry = biFunc.apply("Jerry", 2000);
tom.showInfo();
jerry.showInfo();
}
public static class Staff {
private String fullName;
private int salary;
public Staff(String fullName,int salary) {
this.fullName= fullName;
this.salary = salary;
}
public String getFullName() {
return fullName;
}
public int getSalary() {
return salary;
}
public void showInfo() {
System.out.println("Full Name: " + this.fullName +", Salary: " + this.salary);
}
}
}
Output:
Full Name: Tom, Salary: 1000
Full Name: Jerry, Salary: 2000
Java Basic
- Customize java compiler processing your Annotation (Annotation Processing Tool)
- Java Programming for team using Eclipse and SVN
- Java WeakReference Tutorial with Examples
- Java PhantomReference Tutorial with Examples
- Java Compression and Decompression Tutorial with Examples
- Configuring Eclipse to use the JDK instead of JRE
- Java String.format() and printf() methods
- Syntax and new features in Java 8
- Java Regular Expressions Tutorial with Examples
- Java Multithreading Programming Tutorial with Examples
- JDBC Driver Libraries for different types of database in Java
- Java JDBC Tutorial with Examples
- Get the values of the columns automatically increment when Insert a record using JDBC
- Java Stream Tutorial with Examples
- Java Functional Interface Tutorial with Examples
- Introduction to the Raspberry Pi
- Java Predicate Tutorial with Examples
- Abstract class and Interface in Java
- Access modifiers in Java
- Java Enums Tutorial with Examples
- Java Annotations Tutorial with Examples
- Comparing and Sorting in Java
- Java String, StringBuffer and StringBuilder Tutorial with Examples
- Java Exception Handling Tutorial with Examples
- Java Generics Tutorial with Examples
- Manipulating files and directories in Java
- Java BiPredicate Tutorial with Examples
- Java Consumer Tutorial with Examples
- Java BiConsumer Tutorial with Examples
- What is needed to get started with Java?
- History of Java and the difference between Oracle JDK and OpenJDK
- Install Java on Windows
- Install Java on Ubuntu
- Install OpenJDK on Ubuntu
- Install Eclipse
- Install Eclipse on Ubuntu
- Quick Learning Java for beginners
- History of bits and bytes in computer science
- Data Types in java
- Bitwise Operations
- if else statement in java
- Switch Statement in Java
- Loops in Java
- Arrays in Java
- JDK Javadoc in CHM format
- Inheritance and polymorphism in Java
- Java Function Tutorial with Examples
- Java BiFunction Tutorial with Examples
- Example of Java encoding and decoding using Apache Base64
- Java Reflection Tutorial with Examples
- Java remote method invocation - Java RMI Tutorial with Examples
- Java Socket Programming Tutorial with Examples
- Which Platform Should You Choose for Developing Java Desktop Applications?
- Java Commons IO Tutorial with Examples
- Java Commons Email Tutorial with Examples
- Java Commons Logging Tutorial with Examples
- Understanding Java System.identityHashCode, Object.hashCode and Object.equals
- Java SoftReference Tutorial with Examples
- Java Supplier Tutorial with Examples
- Java Aspect Oriented Programming with AspectJ (AOP)
Show More
- Java Servlet/Jsp Tutorials
- Java Collections Framework Tutorials
- Java API for HTML & XML
- Java IO Tutorials
- Java Date Time Tutorials
- Spring Boot Tutorials
- Maven Tutorials
- Gradle Tutorials
- Java Web Services Tutorials
- Java SWT Tutorials
- JavaFX Tutorials
- Java Oracle ADF Tutorials
- Struts2 Framework Tutorials
- Spring Cloud Tutorials