未读代码 未读代码
首页
  • Java 18 新功能介绍
  • Java 17 新功能介绍
  • Java 16 新功能介绍
  • Java 15 新功能介绍
  • Java 14 新功能介绍
  • Java 8 新特性

    • Java 8 Lambda 表达式
    • Java 8 Stream 流式操作
    • Java 8 时间处理介绍
    • Java 8 Optional 介绍
  • Java 开发工具
Java 源码分析
Spring Boot 系列
  • Arthas 问题定位
  • JMH 基准测试
GitHub (opens new window)
首页
  • Java 18 新功能介绍
  • Java 17 新功能介绍
  • Java 16 新功能介绍
  • Java 15 新功能介绍
  • Java 14 新功能介绍
  • Java 8 新特性

    • Java 8 Lambda 表达式
    • Java 8 Stream 流式操作
    • Java 8 时间处理介绍
    • Java 8 Optional 介绍
  • Java 开发工具
Java 源码分析
Spring Boot 系列
  • Arthas 问题定位
  • JMH 基准测试
GitHub (opens new window)
  • Java 新特性

  • Java8 新特性

    • Java 8 Lambda 和 Comparator 排序
    • Java 8 Optional 介绍
    • Java 8 Lambda 表达式介绍
    • Java 8 Stream 流式操作
    • Java 8 LocalDate、LocalDateTime 时间处理介绍
    • Java 8 List 转 Map
    • Java 8 Function 函数接口
    • Java 8 Supplier 函数接口
    • Java 8 Consumer 函数接口
    • Java 8 Predicate 函数接口
    • Java 8 forEach 遍历
    • Java 8 BiFunction 函数接口
      • 1. BiFunction
      • 2. BiFunction 和 Function
      • 3. 工厂模式
      • 4. 扩展玩法
      • 参考
    • Java 8 BiPredicate 函数接口
    • Java 8 UnaryOperator 函数接口
  • Java 新特性
  • Java8 新特性
程序猿阿朗
2021-07-27

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
2
3
4
5
6
7
8
9
10
11
12
13
14

# 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);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

输出结果:

16
1024.0
1
2

# 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);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

输出结果:

长度和:16
1

示例 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);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

输出结果:

长度和:16
1

示例 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);
}
1
2
3
4
5
6
7
8
9
10
11
12
13

输出结果:

和是:3
1

# 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
}
1
2
3
4
5
6
7
8
9
10
11
12
13

示例:使用 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);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

注意:Dog::new 输入两个参数,要有对应的构造函数 public Dog(String name, Integer age) 与之对应。

输出结果:

Dog{, name='牧羊犬', age=1}
Dog{, name='哈士奇', age=2}
1
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;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63

输出结果:

[2, 4, 6, 8, 10, 12]
[3, 6, 9, 12]
[4, 8, 12]
[java, node, rust]
1
2
3
4

# 参考

  • BiFunction (Java Platform SE 8 ) (opens new window)
  • Java 8 Function 函数接口
  • Java 8 Consumer 函数接口
  • Java 8 教程(LTS)

订阅

文章持续更新,订阅可以关注「 程序猿阿朗 」公众号或者未读代码博客。

文章作者: 程序猿阿朗
文章链接:https://www.wdbyte.com/java8/java8-bifunction/
版权声明:本网站当前文章采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 未读代码!
#Java8#Function Interface#Java8 BiFunction
上次更新: 2022/12/05, 08:18:32
Java 8 forEach 遍历
Java 8 BiPredicate 函数接口

← Java 8 forEach 遍历 Java 8 BiPredicate 函数接口→

最近更新
01
如何搭建一个自己的音乐服务器
12-04
02
JUnit 5 单元测试教程
11-17
03
使用 StringUtils.split 的坑
11-02
更多文章>

提示:评论前请刷新页面,否则评论的可能不是当前文章。

Theme by Vdoing | Copyright © 2018-2022 程序猿阿朗 | MIT License | 皖ICP备20000567号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式