Java8 Function 与BiFunction 接口

Posted SchopenhauerZhang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java8 Function 与BiFunction 接口相关的知识,希望对你有一定的参考价值。

这里写自定义目录标题

介绍

最近在研究RocketMQ源码,发现很多Function和BiFunction的用法,记录一下,平时工程编码其实用得不多。
快速掌握其实只看函数实现部分就好。
不过为了方便,使用了lambda表达式。

目标

通过本文的介绍,了解Function和BiFunction的用法。

正文

通过函数实现整数+10,对比Function和BiFunction的区别;

public class Main 

    public static class Examples 

        public int add (int a,int b) 
            return a+b;
        


    

    public static void main(String[] args) 
        System.out.println("Hello world!");
        Examples res = new Examples();

        System.out.println(res.add(10,10));

    

Lambda 表达式

作为闭包,在java8中lambda作为新特性加入java。
其实当作函数就很好理解了;
举例

public class Java8Tester 
 
   final static int b = 10;
   
   public static void main(String args[])
      AddService addService = a ->  a + b;
      addService.sum(1);
   
    
   interface AddService 
      void sum(int a);
   

相当于实现了sum函数,参数是a,函数体是a+10;

Function

注意Function的定义,Function<Integer,Integer>;

Function

简介

Function作为interface,其实就一个方法apply;

@FunctionalInterface
public interface Function<T, R> 

    /**
     * Applies this function to the given argument.
     *
     * @param t the function argument
     * @return the function result
     */
    R apply(T t);

函数实现

借助Function,实现整数+10;

import java.util.function.Function;

public class Main 

    public static class Examples 

        public int add (int a,int b) 
            return a+b;
        

        public int AddF(int a, Function<Integer,Integer> fn) 
            return fn.apply(a);
        

    

    public static void main(String[] args) 
        System.out.println("Hello world!");
        Examples res = new Examples();

        System.out.println(res.AddF(10,(a)->a+10));

    


简述

其实并不复杂,这里的fn.apply(a)可以简单理解下就是Lambda函数的执行先后问题,将a传入lambda函数,然后执行并返回结果;apply(a)可以理解为将a作为参数传入lambda的操作,并触发lambda;

   public int AddF(int a, Function<Integer,Integer> fn) 
            return fn.apply(a);
        

Function Compose

相比Function更复杂;

简介

对比Function的实现,多了一个function before;注意调用链(V v)->apply(before);

public interface Function<T, R> 
    default <V> Function<V, R> compose(Function<? super V, ? extends T> before) 
        Objects.requireNonNull(before);
        return (V v) -> apply(before.apply(v));
    

函数实现

实现整数+10,多的函数实现乘积,方便测试和对比;

import java.util.function.Function;

public class Main 

    public static class Examples 

        public int add (int a,int b) 
            return a+b;
        

        public int AddF(int a, Function<Integer,Integer> fn) 
            return fn.apply(a);
        

        public int AddFC(int a, Function<Integer,Integer> fn1,Function<Integer,Integer> fn2) 
            return fn1.compose(fn2).apply(a);
        
    

    public static void main(String[] args) 
        System.out.println("Hello world!");
        Examples res = new Examples();

        System.out.println(res.AddFC(10,(a)->a+10,(b)->b*5)); 

    


输出60;

简述

这是因为Function Compose相比Function多了Function fn2,先执行fn2中的逻辑,然后将结果传递给fn1;
如果用Function来解释就是:
50 = fn2.apply(10)
然后执行fn1.apply(50);也就是得到结果60。这里fn1与fn2的先后顺序非常重要。

Function AndThen

简介

了解了前面的内容其实可以发现,重点是多个function的执行顺序问题;来到Function AndThen也是同理;
先执行fn1,然后执行fn2;

public interface Function<T, R> 
    default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) 
        Objects.requireNonNull(after);
        return (T t) -> after.apply(apply(t));
    

函数实现

import java.util.function.Function;

public class Main 

    public static class Examples 

        public int add (int a,int b) 
            return a+b;
        

        public int AddF(int a, Function<Integer,Integer> fn) 
            return fn.apply(a);
        

        public int AddFC(int a, Function<Integer,Integer> fn1,Function<Integer,Integer> fn2) 
            return fn1.compose(fn2).apply(a);
        

        public int AddFAT(int a, Function<Integer,Integer> fn1,Function<Integer,Integer> fn2) 
            return fn1.andThen(fn2).apply(a);
        
    

    public static void main(String[] args) 
        System.out.println("Hello world!");
        Examples res = new Examples();

        System.out.println(res.AddFAT(10,(a)->a+10,(b)->b*5));

    


输出100;

简述

相较来说理解andThen就简单多了,先执行fn1.apply(10),得到结果20;然后执行fn2.apply(20);输出100。

BiFunction

理解了Function,那么理解BiFunction就简单很多;

简介

BiFunction是Function多带了一个参数;也就是说如果想向Function传入2个参数那么就需要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));
    

函数实现

借助BiFunction实现两数相加;

import java.util.function.BiFunction;
import java.util.function.Function;

public class Main 

    public static class Examples 

        public int add (int a,int b) 
            return a+b;
        

        public int AddF(int a, Function<Integer,Integer> fn) 
            return fn.apply(a);
        

        public int AddFC(int a, Function<Integer,Integer> fn1,Function<Integer,Integer> fn2) 
            return fn1.compose(fn2).apply(a);
        

        public int AddFAT(int a, Function<Integer,Integer> fn1,Function<Integer,Integer> fn2) 
            return fn1.andThen(fn2).apply(a);
        

        public int AddBiF(int a,int b, BiFunction<Integer,Integer,Integer> fn1) 
            return fn1.apply(a,b);
        

    

    public static void main(String[] args) 
        System.out.println("Hello world!");
        Examples res = new Examples();

        System.out.println(res.AddBiF(10,10,(a,b)->a+b));

    



输出20;

简述

其实就是Function多加了一个参数,理解了Function那么BiFunction就很容易理解了。

以上是关于Java8 Function 与BiFunction 接口的主要内容,如果未能解决你的问题,请参考以下文章

Java8 方法引用与构造器引用

Java8新特性及实战视频教程完整版

java8 方法引用与lambda

探索Java8:Function接口的使用

Java8之ConsumerSupplierPredicate和Function攻略

Java8Function 讲解