第六章_面向对象进阶(6)_Lambda表达式

本文深入探讨了函数式编程思想及其在Java中的体现——Lambda表达式。通过多个案例展示了Lambda表达式的四种基本形式,包括无参数无返回值、带参数无返回值、无参数有返回值和带参数有返回值的用法。此外,还讨论了Lambda表达式的省略模式,并对比了匿名内部类与Lambda表达式的区别。内容涵盖了Lambda的基本格式、使用场景和优势。
摘要由CSDN通过智能技术生成

一、函数式编程思想

  • Lambda表达式体验
  /*
      游泳接口
   */
  interface Swimming {
      void swim();
  }

  public class TestSwimming {
      public static void main(String[] args) {
          // 通过匿名内部类实现
          goSwimming(new Swimming() {
              @Override
              public void swim() {
                  System.out.println("铁汁, 我们去游泳吧");
              }
          });

          /*  通过Lambda表达式实现
              理解: 对于Lambda表达式, 对匿名内部类进行了优化
           */
          goSwimming(() -> System.out.println("铁汁, 我们去游泳吧"));
      }

      /**
       * 使用接口的方法
       */
      public static void goSwimming(Swimming swimming) {
          swimming.swim();
      }
  }
  • 函数式编程思想
    • 在数学中,函数就是有输入量、输出量的一套计算方案,也就是“拿数据做操作”;面向对象思想强调“必须通过对象的形式来做事情”;函数式思想则尽量忽略面向对象的复杂语法:“强调做什么,而不是以什么形式去做”;而我们要学习的Lambda表达式就是函数式思想的体现

二、Lambda表达的标准格式

  • Lambda表达式的三要素:形式参数、箭头、代码块
  • Lambda表达式的格式:(形式参数) -> {代码块}
    • 形式参数:如果有多个参数,参数之间用逗号隔开;如果没有参数,留空即可
    • ->:由英文中画线和大于符号组成,固定写法。代表指向动作
    • 代码块:是我们具体要做的事情,也就是以前我们写的方法体内容
      在这里插入图片描述
  • Lambda表达的使用前提:有一个接口,接口中有且仅有一个抽象方法

案例:无参数无返回值的Lambda表达式

public class TestLambda {
        练习11. 编写一个接口(ShowHandler2. 在该接口中存在一个抽象方法(show),该方法是无参数无返回值
            3. 在测试类(ShowHandlerDemo)中存在一个方法(useShowHandler)
                        方法的的参数是ShowHandler类型的
                        在方法内部调用了ShowHandler的show方法
     */
    public static void main(String[] args) {
    	//匿名内部类实现
        useShowHandler(new ShowHandler() {
            @Override
            public void show() {
                System.out.println("我是匿名内部类中的show方法");
            }
        });
        // Lambda实现
        useShowHandler( () -> System.out.println("我是Lambda中的show方法"));
    }

    public static void useShowHandler(ShowHandler showHandler){
        showHandler.show();
    }
}

interface ShowHandler {
    void show();
}

案例:带参数无返回值的Lambda表达式

public class StringHandlerDemo {
    /*
        1.首先存在一个接口(StringHandler)
        2.在该接口中存在一个抽象方法(printMessage),该方法是有参数无返回值
        3.在测试类(StringHandlerDemo)中存在一个方法(useStringHandler)
                方法的的参数是StringHandler类型的
                在方法内部调用了StringHandler的printMessage方法
     */
    public static void main(String[] args) {
        useStringHandler(new StringHandler() {
            @Override
            public void printMessage(String msg) {
                System.out.println("我是匿名内部类" + msg);
            }
        });

        // Lambda实现
        useStringHandler( msg -> System.out.println("我是Lambda表达式" + msg));
    }

    public static void useStringHandler(StringHandler stringHandler){
        stringHandler.printMessage("itheima");
    }
}

interface StringHandler {
    void printMessage(String msg);
}

案例:无参数有返回值的Lambda表达式

public class RandomNumHandlerDemo {
    /*
        1. 首先存在一个接口(RandomNumHandler)
        2. 在该接口中存在一个抽象方法(getNumber),该方法是无参数但是有返回值
        3. 在测试类(RandomNumHandlerDemo)中存在一个方法(useRandomNumHandler)
                方法的的参数是RandomNumHandler类型的
                在方法内部调用了RandomNumHandler的getNumber方法
     */
    public static void main(String[] args) {
        useRandomNumHandler(new RandomNumHandler() {
            @Override
            public int getNumber() {
                Random r = new Random();
                int num = r.nextInt(10) + 1;
                return num;
            }
        });

        useRandomNumHandler( () -> {
                Random r = new Random();
                int num = r.nextInt(10) + 1;
                return num;
                // 注意: 如果lambda所操作的接口中的方法, 有返回值, 一定要通过return语句, 将结果返回
                // 否则会出现编译错误
        } );
    }

    public static void useRandomNumHandler(RandomNumHandler randomNumHandler){
        int result = randomNumHandler.getNumber();
        System.out.println(result);
    }
}

interface RandomNumHandler {
    int getNumber();
}

案例:带参数有返回值的Lambda表达式

public class CalculatorDemo {
    /*
        1. 首先存在一个接口(Calculator)
        2. 在该接口中存在一个抽象方法(calc),该方法是有参数也有返回值
        3. 在测试类(CalculatorDemo)中存在一个方法(useCalculator)
            方法的的参数是Calculator类型的
            在方法内部调用了Calculator的calc方法

     */
    public static void main(String[] args) {
        useCalculator(new Calculator() {
            @Override
            public int calc(int a, int b) {
                return a + b;
            }
        });

        useCalculator( ( a,  b) ->
             return a + b;
         );
    }

    public static void useCalculator(Calculator calculator){
        int result = calculator.calc(10,20);
        System.out.println(result);
    }
}

interface Calculator {
    int calc(int a, int b);
}

三、Lambda表达式的省略模式

  • 省略的规则
    • 参数类型可以省略。但是有多个参数的情况下,不能只省略一个
    • 如果参数有且仅有一个,那么小括号可以省略
    • 如果代码块的语句只有一条,可以省略大括号和分号,和return关键字
public class Test6 {
    public static void main(String[] args) {
        /*useInter( (double a, double b) -> {
            return a + b;
        });*/
        useInter((a, b) ->
                a + b
        );
    }

    public static void useInter(Inter i) {
        double result = i.method(12.3, 22.3);
        System.out.println(result);
    }
}

interface Inter {
    // 用于计算 a + b 的结果并返回
    double method(double a, double b);
}

四、匿名内部类和Lambda表达式的区别

  • 所需类型不同
    • 匿名内部类:可以是接口,也可以是抽象类,还可以是具体类
    • Lambda表达式:只能是接口
  • 使用限制不同
    • 如果接口中有且仅有一个抽象方法,可以使用Lambda表达式,也可以使用匿名内部类
    • 如果接口中多于一个抽象方法,只能使用匿名内部类,而不能使用Lambda表达式
  • 实现原理不同
    • 匿名内部类:编译之后,产生一个单独的.class字节码文件
    • Lambda表达式:编译之后,没有一个单独的.class字节码文件。对应的字节码会在运行的时候动态生成
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

无休止符

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值