Java 8 BiFunction 函数接口
这篇文章属于 Java 8 教程(LTS)系列教程,点击阅读更多相关文章。
在 Java 8 中,BiFunction
是一个函数式接口,它和 Function
函数接口十分相似,它可以接受两个不同类型的参数(泛型 T 类型和 泛型 U 类型),然后返回一个其他类型的值(泛型 R 类型)。
相关阅读:Java 8 Function 函数接口
BiFunction
在 Java 8 中的源码。
package java.util.function;
import java.util.Objects;
@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));
}
}
1. BiFunction
示例:接收两个字符串,返回字符串的长度和;接收两个数字,返回 x 的 y 次方。
package com.wdbyte;
import java.util.function.BiFunction;
public class Java8BiFunction {
public static void main(String[] args) {
// 两个字符串长度和
BiFunction<String, String, Integer> lengthBiFun = (s1, s2) -> s1.length() + s2.length();
Integer length = lengthBiFun.apply("java", "www.byte.com");
System.out.println(length);
// x 的 y 次方
BiFunction<Integer, Integer, Double> powBiFun = (i1, i2) -> Math.pow(i1, i2);
Double pow = powBiFun.apply(2, 10);
System.out.println(pow);
}
}
输出结果:
16
1024.0
2. BiFunction 和 Function
BiFunction
中的 andThen
方法可以接受一个 Function
参数,使用 andThen
时的运算逻辑,是把 BiFunction
的结果传入 Function
运算。
示例1:使用 BiFunction
,输入两个字符串,返回两个字符串的长度和;长度和输入到 Function
,拼接上字符串 ”长度和:“ 返回,然后输出这个结果。
package com.wdbyte;
import java.util.function.BiFunction;
import java.util.function.Function;
public class Java8BiFunctionAndThen {
public static void main(String[] args) {
// 两个字符串长度和
BiFunction<String, String, Integer> lengthBiFun = (s1, s2) -> s1.length() + s2.length();
Function<Integer, String> function = s -> "长度和:" + s;
String result = lengthBiFun.andThen(function).apply("java", "www.byte.com");
System.out.println(result);
}
}
输出结果:
长度和:16
示例 2:这里两个函数式接口还可以进一步抽象,抽象成更通用的转换方法。
package com.wdbyte;
import java.util.function.BiFunction;
import java.util.function.Function;
public class Java8BiFunctionAndThen2 {
public static void main(String[] args) {
String result = convert("java",
"www.wdbyte.com",
(a1, a2) -> a1.length() + a2.length(),
r1 -> "长度和:" + r1);
System.out.println(result);
}
public static <T1, T2, R1, R2> R2 convert( T1 t1,
T2 t2,
BiFunction<T1, T2, R1> biFunction,
Function<R1, R2> function) {
return biFunction.andThen(function).apply(t1, t2);
}
}
输出结果:
长度和:16
示例 3:上面的例子已经十分通用了,可以传入任意类型组合操作,比如求两个数字的和。
public static void main(String[] args) {
String convert = convert(1, 2,
(a1, a2) -> a1 + a2,
r1 -> "和是:" + r1);
System.out.println(convert);
}
public static <T1, T2, R1, R2> R2 convert( T1 t1,
T2 t2,
BiFunction<T1, T2, R1> biFunction,
Function<R1, R2> function) {
return biFunction.andThen(function).apply(t1, t2);
}
输出结果:
和是:3
3. 工厂模式
准备要创建的对象类。
package com.wdbyte;
public class Dog {
private String name;
private Integer age;
public Dog() {
}
public Dog(String name, Integer age) {
this.name = name;
this.age = age;
}
// 省略 get set toString
}
示例:使用 BiFunction
构建工厂模式创建狗类对象。
package com.wdbyte;
import java.util.function.BiFunction;
public class JavaBiFunctionFactory {
public static void main(String[] args) {
System.out.println(dogFactory("牧羊犬", 1, Dog::new));
System.out.println(dogFactory("哈士奇", 2, Dog::new));
}
public static <R extends Dog> Dog dogFactory(String name, Integer age, BiFunction<String, Integer, R> biFunction) {
return biFunction.apply(name, age);
}
}
注意:Dog::new
输入两个参数,要有对应的构造函数 public Dog(String name, Integer age)
与之对应。
输出结果:
Dog{, name='牧羊犬', age=1}
Dog{, name='哈士奇', age=2}
4. 扩展玩法
彻底掌握 BiFunction
的使用,随心构建一个使用 BiFunction
完成的集合过滤函数。
示例:构建一个可以过滤指定集合条件的 filter
方法。
package com.wdbyte;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.BiFunction;
public class Java8BiFunctionFilter {
public static void main(String[] args) {
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12);
// 筛选 2 的倍数
List<Integer> result1 = filter(list, 2, Java8BiFunctionFilter::divisible);
System.out.println(result1);
// 筛选 3 的倍数
List<Integer> result2 = filter(list, 3, Java8BiFunctionFilter::divisible);
System.out.println(result2);
// 筛选 4 的倍数
List<Integer> result3 = filter(list, 4, Java8BiFunctionFilter::divisible);
System.out.println(result3);
// 筛选长度为 4 的字符串
List<String> stringList = Arrays.asList("java", "node", "c++", "rust", "www.wdbyte.com");
List<String> stringList1 = filter(stringList, 4, (s, n) -> s.length() == 4 ? true : null);
System.out.println(stringList1);
}
/**
* n1 / n2 是否可以除尽
*
* @param n1
* @param n2
* @return
*/
private static Boolean divisible(Integer n1, Integer n2) {
if (n1 % n2 == 0) {
return true;
}
return null;
}
/**
* 过滤集合 List 中,符合 BiFunction<T, U, R> biFunction 的元素
*
* @param list
* @param u
* @param biFunction
* @param <T>
* @param <U>
* @param <R>
* @return
*/
private static <T, U, R> List<T> filter(List<T> list,
U u,
BiFunction<T, U, R> biFunction) {
List<T> resultList = new ArrayList<>();
for (T t : list) {
if (biFunction.apply(t, u) != null) {
resultList.add(t);
}
}
return resultList;
}
}
输出结果:
[2, 4, 6, 8, 10, 12]
[3, 6, 9, 12]
[4, 8, 12]
[java, node, rust]