Function

函数式接口 Function源码:jkd8所提供的函数式接口都在package java.util.function包下

package java.util.function;

import java.util.Objects;

/**
 * Represents a function that accepts one argument and produces a result.
 * 接收一个参数  生成一个结果
 * <p>This is a <a href="package-summary.html">functional interface</a>
 * whose functional method is {@link #apply(Object)}.
 *
 * @param <T> the type of the input to the function
 * @param <R> the type of the result of the function
 *
 * @since 1.8
 */
@FunctionalInterface
public interface Function<T, R> {  //T:入参   R:返回值

    /**
     * Applies this function to the given argument. 该函数应用到给定的参数上
     */
    
    R apply(T t);

    /**
     * Returns a composed function that first applies the {@code before}
     * function to its input, and then applies this function to the result.
     * If evaluation of either function throws an exception, it is relayed to
     * the caller of the composed function.
     *
     * @param <V> the type of input to the {@code before} function, and to the
     *           composed function
     * @param before the function to apply before this function is applied
     * @return a composed function that first applies the {@code before}
     * function and then applies this function
     * @throws NullPointerException if before is null
     *
     * @see #andThen(Function)
     */
    default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
        Objects.requireNonNull(before);
        return (V v) -> apply(before.apply(v));
    }

    /**
     * Returns a composed function that first applies this function to
     * its input, and then applies the {@code after} function to the result.
     * If evaluation of either function throws an exception, it is relayed to
     * the caller of the composed function.
     *
     * @param <V> the type of output of the {@code after} function, and of the
     *           composed function
     * @param after the function to apply after this function is applied
     * @return a composed function that first applies this function and then
     * applies the {@code after} function
     * @throws NullPointerException if after is null
     *
     * @see #compose(Function)
     */
    default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
        Objects.requireNonNull(after);
        return (T t) -> after.apply(apply(t));
    }

    /**
     * Returns a function that always returns its input argument.
     *
     * @param <T> the type of the input and output objects to the function
     * @return a function that always returns its input argument
     */
    static <T> Function<T, T> identity() {
        return t -> t;
    }
}

R apply(T t)

该函数应用到给定的参数上


public class Test1 {
    public static void main(String[] args) {
        List<String> list = Arrays.asList("Hello","world");

        //1.匿名内部类的方法:
        Function<String,String> fun1=new Function<String, String>() {
            public String apply(String s) {
                return "fun--"+s;
            }
        };
        System.out.println(fun1.apply("sh1")); //fun--sh1

        //2.使用lambda表达式:
        Function<String,String> fun2=(s)-> {return "fun--"+s;};
        System.out.println(fun2.apply("sh2")); //fun--sh2

        //3.方法引入:
        Test1 T=new Test1();
        Function<String,String> fun3=T::addFun;
        System.out.println(fun3.apply("sh3")); //fun--sh3
  
       
        
        //Stream 流中的map方法参数就是 函数式接口Function
        List<String> collect = list.stream().map(fun1).collect(Collectors.toList());
        System.out.println(collect); //[fun--Hello, fun--world]

    }


    public String addFun(String s){
        return "fun--"+s;
    }
}
import java.util.function.Function;

public class FunctionTest {
    public static void main(String[] args) {
        FunctionTest test=new FunctionTest();
        Function<Integer,Integer> fun=i->i*100;
        //int compute = test.compute(2, fun);
        int compute = test.compute(2, integer -> integer * 100);
        System.out.println(compute); //200
    }
   
    public int compute(int a , Function<Integer,Integer> function){
        int result =function.apply(a);
        return result;
    }
}

compose

//参数是一个function,返回值也是一个function
//即:用(V v) -> apply(before.apply(v))实现 返回的function的 apply(T t)方法
default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
        Objects.requireNonNull(before);
        return (V v) -> apply(before.apply(v));
    }

先执行传递来的 function的apply,然后将返回值作为参数执行自身的apply

andThen

 //参数是一个function,返回值也是一个function 
default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
        Objects.requireNonNull(after);
        return (T t) -> after.apply(apply(t));
    }

先执行自身的apply,将返回值作为参数,执行传进来的function 方法

栗子:

public class FunctionTest2 {

    public static void main(String[] args) {
        System.out.println(compute(1, e -> e + 1, e -> e * e));  //2
        System.out.println(compute2(1, e -> e + 1, e -> e * e)); //4

    }

    public static int compute(int a , Function<Integer,Integer> function1, Function<Integer,Integer> function2){
        int result =function1.compose(function2).apply(a);
        //先执行function2的apply,再执行function1的apply
        return result;
    }


    public static int compute2(int a , Function<Integer,Integer> function1, Function<Integer,Integer> function2){
        int result =function1.andThen(function2).apply(a);
        //先执行function1的apply,再执行function2的apply
        return result;
    }
}

BiFunction

对于function而言,只能输入一个参数,返回一个结果,BiFunction可以输入两个参数,返回一个结果:

@FunctionalInterface
public interface BiFunction<T, U, R> {

    /**
     * Applies this function to the given arguments.
     *
     * @param t the first function argument
     * @param u the second function argument
     * @return the function result
     */
    R apply(T t, U u); //输入两个参数

    /**
     * Returns a composed function that first applies this function to
     * its input, and then applies the {@code after} function to the result.
     * If evaluation of either function throws an exception, it is relayed to
     * the caller of the composed function.
     *
     * @param <V> the type of output of the {@code after} function, and of the
     *           composed function
     * @param after the function to apply after this function is applied
     * @return a composed function that first applies this function and then
     * applies the {@code after} function
     * @throws NullPointerException if after is null
     */
    
    
    // ------------
    
    //先执行BiFunction的apply,然后在执行参数Function的apply
    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));
    }
}


栗子:

public class BiFunctionTest {
    public static void main(String[] args) {
        System.out.println(compute(1,1,(a,b)->a+b)); //2
        System.out.println(compute(2,3,(a,b)->a*b,a->a+2)); //8
    }

    public static  int compute(int a,int b, BiFunction<Integer,Integer,Integer> biFunction){
        return biFunction.apply(a,b);
    }

    public static  int compute(int a, int b, BiFunction<Integer,Integer,Integer> biFunction1, Function<Integer,Integer> fun){
        return biFunction1.andThen(fun).apply(a,b);
    }
}
public class BiFunctionTest2 {
    public static void main(String[] args) {
        List<Person> persons= Arrays.asList(new Person(24,"zhangsan"),
                new Person(14,"lisi"),
                new Person(26,"wangwu"),
                new Person(34,"zhaoliu"));

        List<Person> ageThanX = getAgeThanX(20, persons); //获取年龄大于20的人
        ageThanX.forEach(System.out::println);

    }

    public static List<Person> getAgeThanX(Integer a,List<Person> people){
        BiFunction<Integer,List<Person> ,List<Person>> bfun=(age,persons)->{
            return persons.stream().filter(e->e.getAge()>age).collect(Collectors.toList());
        };

        return bfun.apply(a,people);

    }
}

@Data
@NoArgsConstructor
@AllArgsConstructor
class Person{
    Integer age;
    String name;
}

console:

Person(age=24, name=zhangsan)
Person(age=26, name=wangwu)
Person(age=34, name=zhaoliu)

Process finished with exit code 0