• JDK8函数式编程


    JDK8函数式编程

    1、概述

    为什么需要学?

    ​ 因为Java的发展在进步,就比如说可以简化代码,一些for循环里面你还有套娃,写出来的代码就显得非常厚重,其次就是ES(ElasticSearch)、reactive(响应式)等等,都用到了函数式编程,所以有什么理由不学呢?


    2、lambda表达式

    2.1 概述

    百度百科:Lambda 表达式(lambda expression)是一个匿名函数,Lambda表达式基于数学中的λ演算得名,直接对应于其中的lambda抽象(lambda abstraction),是一个匿名函数,即没有函数名的函数。Lambda表达式可以表示闭包(注意和数学传统意义上的不同)。

    Java 8的一个大亮点是引入Lambda表达式,使用它设计的代码会更加简洁。当开发者在编写Lambda表达式时,也会随之被编译成一个函数式接口。下面这个例子就是使用Lambda语法来代替匿名的内部类,代码不仅简洁,而且还可读。

    2.2 基本格式

    (参数列表)-> {代码}
    
    • 1

    举栗子:

    例一:

    我们在创建线程的重写run方法并调用是这样的:

    // 当想看方法或者对象里面的参数可以 ctrl + p
    new Thread(new Runnable() {
        public void run() {
            System.out.println(Thread.currentThread().getName()+"线程调用");
        }
    },"A").start();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    当我们使用lambda表达式后:

    new Thread(()->{
        System.out.println(Thread.currentThread().getName()+"线程调用");
    },"A").start();
    
    • 1
    • 2
    • 3
    例二:

    有一个方法,参数是一个接口:

    public static int calculateNum(IntBinaryOperator operator) {
        int a = 10;
        int b = 20;
        return operator.applyAsInt(a, b);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    我们进行调用,先用匿名内部类进行调用:

    // 将鼠标放到接口按 alt+enter 可以来回切换匿名内部类和lambda表达式
    calculateNum(new IntBinaryOperator() {
        @Override
        public int applyAsInt(int left, int right) {
            return 0;
        }
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    转为lambda表达式:

    calculateNum((int left, int right) -> {
        return left + right;
    });
    
    • 1
    • 2
    • 3
    例三:
    public static void printNum(IntPredicate predicate){
        int[] arr = {1,2,3,4,5,6,7,8,9,10};
        for (int i : arr) {
            if (predicate.test(i)){
                System.out.print(i+" ");
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    使用匿名内部类进行调用

    printNum(new IntPredicate() {
        @Override
        public boolean test(int value) {
            return value%2 == 0;
        }
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    使用lambda表达式:

    printNum((int value)->{
        return value%2 ==0;
    });
    
    • 1
    • 2
    • 3
    例四:

    这里有一个方法,参数是函数式接口

    public static <R>R typeCover(Function<String,R> function){
        String str = "1235";
        R result = function.apply(str);
        return result;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    新手写这种方法一定要先写匿名内部类,便于理解

    Integer i = typeCover(new Function<String, Integer>() {
        @Override
        public Integer apply(String s) {
            return Integer.parseInt(s);
        }
    });
    
    String str = typeCover(new Function<String, String>() {
        @Override
        public String apply(String s) {
            return s+"ywj";
        }
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    转为lambda表达式:

    typeCover((String s)->{
    	return Integer.parseInt(s);
    });
    
    str = typeCover((String s)->{
        return s+"yjw";
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    例五:
    public static void foreachArr(IntConsumer consumer){
        int[] arr = {1,2,3,4,5,6,7,8,9,10};
        for (int i : arr) {
            consumer.accept(i);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    匿名内部类:

    foreachArr(new IntConsumer() {
        @Override
        public void accept(int value) {
            System.out.println(value);
        }
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    lambda表达式:

    foreachArr((int value)->{
        System.out.println(value);
    });
    
    • 1
    • 2
    • 3

    2.3省略规则:

    • 参数类型可以省略
    • 方法体只有一句话时大括号return和唯一一句代码的分号可以省略
    • 方法只有一个参数时小括号可以省略

    2.4总结

    • 在使用lambda表达式之前尽量先使用匿名内部类的方式,这样可以更好地理解
    • lambda表达式,无非就是去掉接口名,方法名,我们只需要关心参数列表和方法体
    • 简化代码,有一些没必要写的就可以去掉,比如:数据类型、括号等等
    • 最终技巧:懒人技巧,先使用匿名内部类创建,然后选中参数中的接口名,直接使用idea快捷键 alt+enter 自动创建lambda表达式
  • 相关阅读:
    【JVM】优化参数+优化工具+优化实例
    MySQL 索引的使用和设计
    Android-Intent与Bundle在传值上的区别
    【毕业设计】深度学习人脸表情识别系统 - python
    [Java]订单超时自动取消——RocketMQ实现+SpringBoot项目
    广播实现强制下线功能
    Node.js学习上(67th)
    独立站内容营销策略,加入情景营销提升转化率
    智慧公厕:科技赋予公共卫生新生命,提升城市管理品质
    LeetCode315 周赛
  • 原文地址:https://blog.csdn.net/weixin_46073538/article/details/126843355