• Lambda表达式


    目录

    一 概述

    1.1 Lambda表达式

    1.2 函数式接口

    二 Lambda表达式语法

    2.1 无参无返回值

    2.2 无参有返回值

    2.3 有参无返回值

    2.4 有参有返回值

    2.5 对象方法引用

    2.6 类静态方法引用

    2.7 特殊方法引用


    一 概述

    1.1 Lambda表达式

    Lambda表达式是一个匿名函数,Java在JDK1.8引入Lambda表达式。

    结构:(参数列表)->{Lambda体:代码块,也就是表达式要运行的功能}

    标准写法由下面几点构成:

    • 参数列表:以,分隔,以()包裹的形参,例如(int x, int y)
    • 箭头标记:->
    • Lambda体:以{}包裹的lambda表达式,也就是代码块。

    例如:(int x, int y)->{return x + y;}

    1.2 函数式接口

    在接口上标记@FunctionalInterface说明该接口是一个函数式接口。

    无论接口声明中是否存在@FunctionalInterface注解,编译器都会将满足函数式接口定义的任何接口视为函数式接口。

    函数式接口的实例可以使用lambda表达式匿名内部类实现接口方法的类来创建。

    函数式接口需满足以下条件

    • 接口有且只能有一个抽象方法
    • 可以有default实现方法
    • 可以有static实现方法
    • 可以有Object类继承过来的方法

    如果接口声明了一个覆盖 java.lang.Object 的公共方法之一的抽象方法,这不会进入抽象方法计数,因为接口的任何实现类都具有来自 java.lang.Object 或其他地方的实现。

    1. @FunctionalInterface
    2. public interface TestInterface {
    3. //常量:编译器都会加上public final标识
    4. String name = "name";
    5. //编译器都会加上public abstract标识
    6. String get();
    7. static void staticTest(){
    8. System.out.println("staticTest");
    9. }
    10. default void defaultTest(){
    11. System.out.println("defaultTest");
    12. }
    13. boolean equals(Object o);
    14. }

    可参考:

    FunctionalInterface注解_qinghuazs的博客-CSDN博客_functionalinterface注解

    二 Lambda表达式语法

    普通用法:(int x, int y)->{return x + y;}

    精简语法:

    1、参数的类型可省略(JVM会主动识别需要实现的方法确定参数的类型)
    2、假如只有一个参数,()可以省略
    3、如果方法体只有一个语句,{}可以省略
    4、如果方法体唯一的语句是return返回语句,那么{}和return要同时省略

    5、若对象的方法或类的静态方法,和接口的方法返回值、参数列表一致,且对象的方法或类的静态方法刚好满足接口方法实现的需求,则可采用方法引用

    调用方式:对象::非静态方法

                      ::静态方法

                      ::非静态方法(适用条件参考2.7节)

    注意:在方法引用中,不能通过对象去引用静态方法,例如对象::静态方法

    2.1 无参无返回值

    1. @FunctionalInterface
    2. public interface TestInterface {
    3. void get();
    4. }
    1. @Test
    2. public void test15(){
    3. TestInterface testInterface = ()->{
    4. System.out.println("无参无返回值");
    5. };
    6. testInterface.get();
    7. //精简语法
    8. testInterface = () -> System.out.println("无参无返回值");
    9. testInterface.get();
    10. }

    2.2 无参有返回值

    1. @FunctionalInterface
    2. public interface TestInterface {
    3. String get();
    4. }
    1. @Test
    2. public void test15(){
    3. TestInterface testInterface = ()->{
    4. return "无参有返回值";
    5. };
    6. System.out.println(testInterface.get());;
    7. //精简语法
    8. testInterface = () -> "无参有返回值";
    9. System.out.println(testInterface.get());;
    10. }

    2.3 有参无返回值

    1. @FunctionalInterface
    2. public interface TestInterface {
    3. void get(String value);
    4. }
    1. @Test
    2. public void test15(){
    3. TestInterface testInterface = (value)->{
    4. System.out.println(value);
    5. };
    6. testInterface.get("有参无返回值");
    7. //精简语法
    8. testInterface = value -> System.out.println(value);
    9. testInterface.get("有参无返回值");
    10. //方法引用
    11. testInterface = System.out::println;
    12. testInterface.get("有参无返回值");
    13. }

    2.4 有参有返回值

    1. @FunctionalInterface
    2. public interface TestInterface {
    3. int get(int a, int b);
    4. }
    1. @Test
    2. public void test15(){
    3. TestInterface testInterface = (a, b)->{
    4. return a + b;
    5. };
    6. System.out.println(testInterface.get(1, 2));
    7. //精简语法
    8. testInterface = (a, b) -> a + b;
    9. System.out.println(testInterface.get(1, 2));
    10. }

    2.5 对象方法引用

    1. @FunctionalInterface
    2. public interface TestInterface {
    3. int get(int a, int b);
    4. }
    1. package com.mzp.component;
    2. public class Demo {
    3. public int getValue(int a, int b){
    4. return a + b;
    5. }
    6. }
    1. @Test
    2. public void test15(){
    3. TestInterface testInterface = (a, b)->{
    4. return a + b;
    5. };
    6. System.out.println(testInterface.get(1, 2));
    7. //精简语法
    8. testInterface = (a, b) -> a + b;
    9. System.out.println(testInterface.get(1, 2));
    10. Demo demo = new Demo();
    11. //对象::方法
    12. testInterface = demo::getValue;
    13. System.out.println(testInterface.get(1, 2));
    14. }

    2.6 类静态方法引用

    1. package com.mzp.component;
    2. public class Demo {
    3. public static int getStaticValue(int a, int b){
    4. return a + b;
    5. }
    6. }
    1. @Test
    2. public void test15(){
    3. TestInterface testInterface = (a, b)->{
    4. return a + b;
    5. };
    6. System.out.println(testInterface.get(1, 2));
    7. //精简语法
    8. testInterface = (a, b) -> a + b;
    9. System.out.println(testInterface.get(1, 2));
    10. //类::静态方法
    11. testInterface = Demo::getStaticValue;
    12. System.out.println(testInterface.get(1, 2));
    13. }

    2.7 特殊方法引用

    如果Lambda表达式的方法体刚好是排在第一的参数对象调用对象自身的方法(排除静态方法),且对象的方法参数和Lambda参数列表从第二位参数开始一一对应(参数类型个数),

    则可使用::非静态方法

    例如

    1. package com.mzp.component.functional;
    2. import com.mzp.component.Demo;
    3. @FunctionalInterface
    4. public interface TestInterface {
    5. int get(Demo a, String b, int c);
    6. }
    1. package com.mzp.component;
    2. public class Demo {
    3. private String name = "original";
    4. public Demo(){
    5. }
    6. public Demo(String name){
    7. this.name = name;
    8. }
    9. public int add(String a, int b){
    10. System.out.println(name);
    11. return b;
    12. }
    13. }
    1. @Test
    2. public void test15(){
    3. Demo demo = new Demo("update");
    4. TestInterface testInterface = (a, b, c)->{
    5. return a.add(b, c);
    6. };
    7. System.out.println(testInterface.get(demo,"1", 2));
    8. //精简语法
    9. testInterface = (a, b, c) -> a.add(b, c);
    10. System.out.println(testInterface.get(demo,"1", 2));
    11. //类::非静态方法
    12. testInterface = Demo::add;
    13. System.out.println(testInterface.get(demo,"1", 2));
    14. }

    注意:若是Demo类中刚好有名称相同的静态方法和非静态方法,且函数式接口的第一个参数类型为Demo,通过lambda表达式创建函数式接口实例,

    静态方法通过方法引用(::静态方法)匹配到,

    非静态方法也通过特殊方法引用(::方法)匹配到,编译器则会报错,匹配到多个实现方法。

    例如

    函数式接口方法如图

    1. @FunctionalInterface
    2. public interface MyFunctionalInterface {
    3. int add(Demo a, int b);
    4. }

    Demo类如图

    1. public class Demo {
    2. public static int add(Demo demo, int b){
    3. return b;
    4. }
    5. public int add(int b){
    6. return b;
    7. }
    8. }

     通过lambda表达式创建函数式接口实例报错

  • 相关阅读:
    express-generator快速构建node后端项目
    【概率论与数理统计(研究生课程)】知识点总结2(一维随机变量及其分布)
    【C语言】冒泡排序算法详解
    JAVA知识点笔记
    设计模式-代理模式(Proxy)
    【计算机网络】HTTP 重定向
    建造者模式和模板设计模式应该怎么使用
    Endnote 中批量导出PDF
    分布式系统架构理论与组件
    FPGA project : uart232_ram_vga
  • 原文地址:https://blog.csdn.net/weixin_37607613/article/details/126346443