加入收藏 | 设为首页 | 会员中心 | 我要投稿 大连站长网 (https://www.0411zz.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 编程要点 > 语言 > 正文

Java Lambda表达式

发布时间:2022-07-11 00:00:53 所属栏目:语言 来源:互联网
导读:Lambda 表达式(Lambda expression)是一个匿名函数,基于数学中的演算得名,也可称为闭包(Closure)。现在很多语言都支持 Lambda 表达式,如 C++、C#、Java、 Python 和 JavaScript 等。 Lambda 表达式是推动 Java 8 发布的重要新特性,它允许把函数作为
  Lambda 表达式(Lambda expression)是一个匿名函数,基于数学中的λ演算得名,也可称为闭包(Closure)。现在很多语言都支持 Lambda 表达式,如 C++、C#、Java、 Python 和 JavaScript 等。
 
  Lambda 表达式是推动 Java 8 发布的重要新特性,它允许把函数作为一个方法的参数(函数作为参数传递进方法中),下面通过例 1 来理解 Lambda 表达式的概念。
  例 1
  先定义一个计算数值的接口,代码如下。
  // 可计算接口
  public interface Calculable {
      // 计算两个int数值
      int calculateInt(int a, int b);
  }
  Calculable 接口只有一个方法 calculateInt,参数是两个 int 类型,返回值也是 int 类型。实现方法代码如下:
  public class Test{
      /**
       * 通过操作符,进行计算
       *
       * @param opr 操作符
       * @return 实现Calculable接口对象
       */
      public static Calculable calculate(char opr) {
          Calculable result;
          if (opr == '+') {
              // 匿名内部类实现Calculable接口
              result = new Calculable() {
                  // 实现加法运算
                  @Override
                  public int calculateInt(int a, int b) {
                      return a + b;
                  }
              };
          } else {
              // 匿名内部类实现Calculable接口
              result = new Calculable() {
                  // 实现减法运算
                  @Override
                  public int calculateInt(int a, int b) {
                      return a - b;
                  }
              };
          }
          return result;
      }
  }
  方法 calculate 中 opr 参数是运算符,返回值是实现 Calculable 接口对象。代码第 13 行和第 23 行都采用匿名内部类实现 Calculable 接口。代码第 16 行实现加法运算。代码第 26 行实现减法运算。
  public static void main(String[] args) {
      int n1 = 10;
      int n2 = 5;
      // 实现加法计算Calculable对象
      Calculable f1 = calculate('+');
      // 实现减法计算Calculable对象
      Calculable f2 = calculate('-');
      // 调用calculateInt方法进行加法计算
      System.out.println(n1 + "+" + n2 + "=" + f1.calculateInt(n1, n2));
      // System.out.printf("%d + %d = %d n", n1, n2, f1.calculateInt(n1, n2));
      // 调用calculateInt方法进行减法计算
      System.out.println(n1 + "-" + n2 + "=" + f1.calculateInt(n1, n2));
      // System.out.printf("%d - %d = %d n", n1, n2, f2.calculateInt(n1, n2));
  }
  代码第 5 行中 f1 是实现加法计算 Calculable 对象,代码第 7 行中 f2 是实现减法计算 Calculable 对象。代码第 9 行和第 12 行才进行方法调用。
 
  上述代码中列出了两种输出方式,下面简单介绍一下 Java 中常见的输出函数:
  printf 主要继承了C语言中 printf 的一些特性,可以进行格式化输出。
  print 就是一般的标准输出,但是不换行。
  println 和 print 基本没什么差别,就是最后会换行。
 
  输出结果如下:
  10+5=15
  10-5=15
 
  例 1 使用匿名内部类的方法 calculate 代码很臃肿,Java 8 采用 Lambda 表达式可以替代匿名内部类。修改之后的通用方法 calculate 代码如下:
  /**
  * 通过操作符,进行计算
  * @param opr 操作符
  * @return 实现Calculable接口对象
  */
  public static Calculable calculate(char opr) {
      Calculable result;
      if (opr == '+') {
          // Lambda表达式实现Calculable接口
          result = (int a, int b) -> {
              return a + b;
          };
      } else {
          // Lambda表达式实现Calculable接口
          result = (int a, int b) -> {
              return a - b;
          };
      }
      return result;
  }
  代码第 10 行和第 15 行用 Lambda 表达式替代匿名内部类,可见代码变得简洁。通过以上示例我们发现,Lambda 表达式是一个匿名函数(方法)代码块,可以作为表达式、方法参数和方法返回值。
 
  Lambda 表达式标准语法形式如下:
  (参数列表) -> {
      // Lambda表达式体
  }
 
  ->被称为箭头操作符或 Lambda 操作符,箭头操作符将 Lambda 表达式拆分成两部分:
  左侧:Lambda 表达式的参数列表。
  右侧:Lambda 表达式中所需执行的功能,用{ }包起来,即 Lambda 体。
  Java Lambda 表达式的优缺点
  优点:
  代码简洁,开发迅速
  方便函数式编程
  非常容易进行并行计算
  Java 引入 Lambda,改善了集合操作(引入 Stream API)
 
  缺点:
  代码可读性变差
  在非并行计算中,很多计算未必有传统的 for 性能要高
  不容易进行调试
  函数式接口
  Lambda 表达式实现的接口不是普通的接口,而是函数式接口。如果一个接口中,有且只有一个抽象的方法(Object 类中的方法不包括在内),那这个接口就可以被看做是函数式接口。这种接口只能有一个方法。如果接口中声明多个抽象方法,那么 Lambda 表达式会发生编译错误:
  The target type of this expression must be a functional interface
 
  这说明该接口不是函数式接口,为了防止在函数式接口中声明多个抽象方法,Java 8 提供了一个声明函数式接口注解 @FunctionalInterface,示例代码如下。
  // 可计算接口
  @FunctionalInterface
  public interface Calculable {
      // 计算两个int数值
      int calculateInt(int a, int b);
  }
  在接口之前使用 @FunctionalInterface 注解修饰,那么试图增加一个抽象方法时会发生编译错误。但可以添加默认方法和静态方法。
 
  @FunctionalInterface 注解与 @Override 注解的作用类似。Java 8 中专门为函数式接口引入了一个新的注解 @FunctionalInterface。该注解可用于一个接口的定义上,一旦使用该注解来定义接口,编译器将会强制检查该接口是否确实有且仅有一个抽象方法,否则将会报错。需要注意的是,即使不使用该注解,只要满足函数式接口的定义,这仍然是一个函数式接口,使用起来都一样。
  
 
  提示:Lambda 表达式是一个匿名方法代码,Java 中的方法必须声明在类或接口中,那么 Lambda 表达式所实现的匿名方法是在函数式接口中声明的。

(编辑:大连站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!