JAVA -- 函数式接口

函数式接口是只有一个抽象方法的接口,但是可以有多个静态方法和默认方法。
静态方法不能被子类继承,默认方法可以被子类继承重写。
@FunctionalInterface 注解是非必需的,但是该注解会对函数式接口的方法进行校验,存在多个抽象方法时会编译错误,当接口继承的父接口中存在多个未实现的抽象类时,也会编译错误,因此建议写上。

实现一个函数式接口

创建接口

@FunctionalInterface
interface Interface1{
    
    

    String test(int i);

    default int add(int x,int y){
    
    
        return x+y;
    }
}

@FunctionalInterface
interface Interface2{
    
    
    String test(int i);

    default int add(int x,int y){
    
    
        return x+y+1;
    }
}
//两个父接口的抽象方法必须一样,否则会编译错误
@FunctionalInterface
interface Interface3 extends Interface1,Interface2{
    
    

    @Override
    default int add(int x, int y) {
    
    
        return Interface1.super.add(x,y);
    }

    default void print(String test) {
    
    
        System.out.println(test);
    }

    default int get() {
    
    
        return 0;
    }
}

实现接口并调用

Interface3 i3 = new Interface3() {
    
    
    @Override
    public String test(int i) {
    
    
        return String.valueOf(i*2);
    }
};
//上面的实现可以用lambda简化为
//Interface3 i3 = i->String.valueOf(i*2);
System.out.println(i3.test(12));
System.out.println(i3.add(1,2));
System.out.println(i3.get());
i3.print("测试一下");

结果:
24
3
0
测试一下

java.util.function 提供的函数式接口

Function<T,R> 功能型函数

** 接受类型 T 的参数,返回类型 R 的参数**

Function<Integer,String> function = i-> "这个数字是:"+i;
System.out.println(function.apply(6));

结果:
这个数字是:6

java.util.function还提供了已经定义好类型的函数式接口。例如:

  • IntFunction 接收一个 int 类型的参数,返回 R 类型的参数
    IntFunction<String> function = i-> "这个数字是:"+i;
    System.out.println(function.apply(6));
    
    结果:
    这个数字是:6
    
  • ToDoubleFunction 接收一个 T 类型的参数,返回 Double 类型的参数
    ToDoubleFunction<String> function = i-> Double.valueOf(i);
    System.out.println(function.applyAsDouble("6"));
    
    结果:
    6.0
    
  • IntToDoubleFunction 接收一个 int 类型的参数,返回 Double 类型的参数
    IntToDoubleFunction function = i-> Double.valueOf(i);
    System.out.println(function.applyAsDouble(6));
    
    结果:
    6.0
    

其他类型的函数式接口也有与之类似的接口。

Predicate<T> 断言函数

** 接收 T 类型,返回boolean**

Predicate<Integer> intPredicate = i->i>0;
System.out.println(intPredicate.test(6));

结果:
true

Consumer<T> 消费者函数

** 消费者顾名思义只消费,不生产,接收 T 类型不返回结果**

Consumer<Integer> intComsumer = i-> System.out.println("结果是:"+i);
intComsumer.accept(1);

结果:
结果是:1

Supplier<R>提供者函数

** 与消费者函数相反,他不接收参数,返回 R 类型结果**

Supplier<Integer> supplier = ()-> 0;
System.out.println(supplier .get());

结果:
0

BiFunction<T, U, R>

接受两个参数 类型 T ,U 返回 类型 R 结果

BiFunction<Integer,Integer,String> supplier = (x,y)-> String.valueOf(x+y);
System.out.println(supplier .apply(1,1));

结果:
2

UnaryOperator<T> 一元运算函数

其实就是继承自 Function<T,T> ,输入输出类型一致

@FunctionalInterface
public interface UnaryOperator<T> extends Function<T, T> {
    
    

    /**
     * Returns a unary operator that always returns its input argument.
     *
     * @param <T> the type of the input and output of the operator
     * @return a unary operator that always returns its input argument
     */
    static <T> UnaryOperator<T> identity() {
    
    
        return t -> t;
    }
}

方法引用

创建Dog实例

class Good{
    
    

    private String name = "小浣熊干脆面";
    private static int allNum = 100;
    public Good(String name){
    
    
        this.name = name;
    }

    //售罄
    public static void saleout(Good good){
    
    
        System.out.println(good + "卖光了");
    }

    //出售
    public int sale(int num ){
    
    
        System.out.println(name+"卖出了"+num+"袋");
        this.allNum-=num;
        return this.allNum;
    }

    @Override
    public String toString() {
    
    
        return this.name;
    }
}

静态方法的方法引用

Consumer<Good> consumer = Good::saleout;
consumer.accept(new Good("小浣熊"));

结果:
小浣熊卖光了

非静态方法实例化引用

IntUnaryOperator consumer2 = new Good("小浣熊")::sale;
System.out.println(consumer2.applyAsInt(9));

结果:
小浣熊卖出了991

非静态方法通过类引用

BiFunction<Good,Integer,Integer> consumer3 = Good::sale;
System.out.println(consumer3.apply(new Good("小浣熊"),9));

结果:
小浣熊卖出了991

猜你喜欢

转载自blog.csdn.net/qq_40096897/article/details/121329085