Руководство Java BiFunction
1. BiFunction
В Java 8, BiFunction ялвяетсяfunctional interface, представляющим оператор, который принимает два входных значения и возвращает одно значение.
Исходный код интерфейса BiFunction:
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));
}
}
См.Также: Function является functional interrface, подобным BiFunction, но он принимает входной параметр и возвращает значение.
Например: Создание BiFunction, которая принимает 2 входных параметра типа String и возвращает 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
Ниже приведен список методов в package java.util, использующих 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) |
Например: Объект Map содержит сопоставления между названием страны и стоимостью аренды квартиры в месяц. Мы повысим цены на 10%, за исключением Вьетнама.
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) возвращает комбинированную BiFunction. В начале, BiFunction.apply вызывается для преобразования (T,U) в (R), затем after.apply вызывается для преобразования (R) в (V). Если на одном из вышеперечисленных 2 шагов возникает ошибка, она передается вызывающему абоненту (caller). Если в текущей BiFunction возникает ошибка, то after игнорируется.
Исходный код метода andThen(after) может быть немного запутанным:
@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));
}
}
И мы можем интерпретировать приведенный выше исходный код более простым способом:
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;
}
}
Например:
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
Если метод принимает два параметра и возвращает значение, то его ссылку можно рассматривать как BiFunction.
Например: Статический метод Math.max(int,int) принимает 2 параметра и возвращает целое число Integer. Таким образом, его ссылку - Math::max можно считать 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
Например: 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
Как мы все знаем, constructor - это специальный метод, который возвращает объект. Таким образом, если constructor имеет 2 параметра, его ссылка будет рассматриваться как 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
- Настройте java compiler для обработки вашего Annotation (Annotation Processing Tool)
- Программирование на Java для группы с помощью Eclipse и SVN
- Руководство Java WeakReference
- Руководство Java PhantomReference
- Сжатие и декомпрессия в Java
- Настройка Eclipse для использования JDK вместо JRE
- Методы String.format() и printf() в Java
- Синтаксис и новые функции в Java 8
- Регулярные выражения Java
- Руководство Java Multithreading Programming
- Библиотеки Java JDBC Driver для различных типов баз данных
- Руководство Java JDBC
- Получить значения столбцов, автоматически возрастающих при вставлении (Insert) записи, используя JDBC
- Руководство Java Stream
- Руководство Java Functional Interface
- Введение в Raspberry Pi
- Руководство Java Predicate
- Абстрактный класс и Interface в Java
- Модификатор доступа (Access modifiers) в Java
- Руководство Java Enum
- Руководство Java Annotation
- Сравнение и Сортировка в Java
- Руководство Java String, StringBuffer и StringBuilder
- Обработка исключений Java - Java Exception Handling
- Руководство Java Generics
- Манипулирование файлами и каталогами в Java
- Руководство Java BiPredicate
- Руководство Java Consumer
- Руководство Java BiConsumer
- Что мне нужно для начала работы с Java?
- История Java и разница между Oracle JDK и OpenJDK
- Установить Java в Windows
- Установите Java в Ubuntu
- Установите OpenJDK в Ubuntu
- Установить Eclipse
- Установите Eclipse в Ubuntu
- Быстрое изучение Java для начинающих
- История бит и байтов в информатике
- Типы данных в java
- Битовые операции
- Команда if else в Java
- команды switch в Java
- Циклы в Java
- Массивы (Array) в Java
- JDK Javadoc в формате CHM
- Наследование и полиморфизм в Java
- Руководство Java Function
- Руководство Java BiFunction
- Пример Java encoding и decoding с использованием Apache Base64
- Руководство Java Reflection
- Java Удаленный вызов методов - Java RMI
- Руководство Программирование Java Socket
- Какую платформу я должен выбрать для разработки приложений Java Desktop?
- Руководство Java Commons IO
- Руководство Java Commons Email
- Руководство Java Commons Logging
- Понимание Java System.identityHashCode, Object.hashCode и Object.equals
- Руководство Java SoftReference
- Руководство Java Supplier
- Аспектно-ориентированное программирование Java с помощью AspectJ (AOP)
Show More
- Руководства Java Servlet/JSP
- Руководства Java Collections Framework
- Java API для HTML, XML
- Руководства Java IO
- Руководства Java Date Time
- Руководства Spring Boot
- Руководства Maven
- Руководства Gradle
- Руководства Java Web Services
- Руководства Java SWT
- Руководства JavaFX
- Руководства Oracle Java ADF
- Руководства Struts2 Framework
- Руководства Spring Cloud