函数式接口-闭包与柯里化

闭包

定义

在这里插入图片描述

示例

在这里插入图片描述

注意

这个外部变量 x 必须是effective final

  • 你可以生命他是final,你不声明也会默认他是final的,并且具有final的特性,不可变
  • 一旦x可变,他就不是final,就无法形成闭包,也无法与函数对象一起使用

这个地方存在一个取巧的行为

  • 你可以选择一个引用对象,逻辑中使用的是这个对象的某个属性,改变属性达到改变逻辑的效果,但是这个引用没有发生变化,这个对象还是这个对象,只不过属性值发生了变化。

在这里插入图片描述

闭包使用示例

  • for循环的i是变化的,无法直接作为闭包变量,可以每次生命一个新的k值来接收i
for (int i = 0; i < 10; i++) {
    // 每次循环都创建一个新的final变量k
    int k = i;
    Thread thread = new Thread(() -> {
        System.out.println("线程" + k + "执行");// 这里会报错 直接使用i会报错 因为i是final的
        
    });
    thread.start();
}

柯里化

定义

注意

柯里化是建立在闭包的基础上的

实例

使用lambda实现函数式接口

常规写法:多个参数

int a = 10;
int b = 20;

// 常规写法
MyInterface myInterface = (int x,int y) -> {
    System.out.println(x + y);
};
myInterface.method(a,b);


@FunctionalInterface
public interface MyInterface {
    void method(int a,int b);
}
  • 有点类似于递归调用
  • 每一次都返回的是一个函数,没有切实的方法体,只为了传递参数
  • 只有第一层有所有的参数,有实际的方法体
// 柯里化写法 一个函数返回一个函数 每次调用返回的函数都是一个新的函数 每个函数都有一个参数
// 这个地方其实就是隐式地使用了柯里化
MyInterface3 myInterface3 =  x ->  y -> {
    System.out.println(x + y);
};
MyInterface2 myInterface2 = myInterface3.method(a);
myInterface2.method(b);

@FunctionalInterface
public interface MyInterface2 {
    void method(int a);
}


@FunctionalInterface
public interface MyInterface3 {
    // 返回一个函数
    MyInterface2 method(int b);
}

柯里化的作用

在这里插入图片描述

练习

public class Main3 {
    public static void main(String[] args) {

        List<Integer> list = step3(step2(step1()));
        System.out.println(list);

    }



   /*
   * 函数式接口1:F1 收集第一个list 返回一个函数式接口2
   * 函数式接口2:F2 收集第二个list 返回一个函数式接口3
   * 函数式接口3:F3 收集第三个list 执行具体逻辑
   * */
    @FunctionalInterface
    interface F1  {
        // 收集第一个list 返回一个函数式接口2
        F2 method(List<Integer> list);
    }

    @FunctionalInterface
    interface F2  {
        // 收集第二个list 返回一个函数式接口3
        F3 method(List<Integer> list2);
    }

    @FunctionalInterface
    interface F3  {
        // 收集第三个list 执行具体逻辑
        List<Integer> method(List<Integer> list3);
    }


    // 第一步
    public static F2 step1 (){
        // 第一个list
        List<Integer> list1 = Arrays.asList(1, 2, 3);
        // 因为第一在最外层 所以是一个三层嵌套的函数
        // 方法体已经定义完毕 但是这个方法体并没有执行  这个方法体是在step3中执行的
        F1 step1 = a -> b -> c -> {
            List<Integer> newList = new ArrayList<>();
            newList.addAll(a);
            newList.addAll(b);
            newList.addAll(c);
            return newList;
        };
        // 执行step1的方法体 收集第一个list 返回一个函数式接口2
        return step1.method(list1);

    };

    public static F3 step2 (F2 f2){
        List<Integer> list2 = Arrays.asList(4, 5, 6);
        // 执行step2的方法体 收集第二个list 返回一个函数式接口3
        return f2.method(list2);
    };

    public static List<Integer> step3 (F3 f3){
        List<Integer> list3 = Arrays.asList(7, 8, 9);
        // 执行step3的方法体 收集第三个list 执行具体逻辑
        return f3.method(list3);
    };
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值