Java Lambda 表达式

前言

1、Lambda 表达式

  • 匿名类概念相比较,Lambda 表达式 其实就是匿名方法,这是一种把方法作为参数进行传递的编程思想。Java 会在背后,悄悄的,把这些都还原成匿名类方式。

    1
    2
    // 参数 -> 表达式主体
    h -> h.hp > 100 && h.damage < 50
  • 一般语法

    1
    (Parameters) -> { Body }
    • -> 分隔参数和 Lambda 表达式主体。
    • 参数括在括号中,与方法相同,而 Lambda 表达式主体 是用大括号括起来的代码块。
    • Lambda 表达式主体可以有局部变量,语句。
    • 可以在 Lambda 表达式主体中使用 break,continue 和 return。
    • 甚至可以从 Lambda 表达式主体中抛出异常。
  • 分类

    • 隐式 Lambda 表达式:未声明其参数类型的 Lambda 表达式,编译器将推断其参数类型。
    • 显式 Lambda 表达式:声明其参数的类型的 Lambda 表达式。
  • 引入 Lambda 表达式,会使得代码更加紧凑,而不是各种接口和匿名类到处飞。

  • Lambda 表达式虽然带来了代码的简洁,但是也有其局限性。

    • 可读性差,与啰嗦的但是清晰的匿名类代码结构比较起来,Lambda 表达式一旦变得比较长,就难以理解。
    • 不便于调试,很难在 Lambda 表达式中增加调试信息,比如日志。
    • 版本支持,Lambda 表达式在 JDK8 版本中才开始支持,如果系统使用的是以前的版本,考虑系统的稳定性等原因,而不愿意升级,那么就无法使用。
    • Lambda 表达式没有名称,因为它表示匿名内部类。
    • Lambda 表达式的返回类型由编译器推断。
    • Lambda 表达式不能像方法一样有 throws 子句。
    • Lambda 表达式不能是泛型,而泛型在函数接口中定义。
  • Lambda 比较适合用在简短的业务代码中,并不适合用在复杂的系统中,会加大维护成本。

2、方法引用

  • 方法引用的一般语法是

    1
    2
    // 限定符 :: 方法名
    Qualifier::MethodName
  • 只需要指定方法名,无需指定方法的参数类型和返回类型。方法引用的目标类型是功能接口。它确定方法的签名并在必要时解析重载的方法。

    • 两个连续的冒号充当分隔符。
    • MethodName 是方法的名称。
    • 限定符告诉在哪里找到方法引用。
  • 有六种类型的方法引用。

    • TypeName::staticMethod - 引用类的静态方法,接口或枚举
    • objectRef::instanceMethod - 引用实例方法
    • ClassName::instanceMethod - 从类中引用实例方法
    • TypeName.super::instanceMethod - 从对象的父类型引用实例方法
    • ClassName::new - 引用一个类的构造函数
    • ArrayTypeName::new - 对指定数组类型的构造函数的引用
  • 引用静态方法

    1
    2
    3
    filter(heros, h -> TestLambda.testHero(h));        // 在 Lambda 表达式中使用静态方法

    filter(heros, TestLambda::testHero); // 直接引用静态方法
  • 引用对象方法:与引用静态方法很类似,只是传递方法的时候,需要一个对象的存在。

    1
    2
    3
    filter(heros, h -> testLambda.testHero(h));

    filter(heros, testLambda::testHero);
  • 引用容器中的对象的方法

    1
    2
    3
    filter(heros, h -> h.matched());                   // Lambda 表达式中调用容器中的对象的 matched 方法

    filter(heros, Hero::matched); // 引用容器中对象的方法
  • 引用构造器

    1
    List list3 = getList(ArrayList::new);

3、聚合操作

  • 聚合操作

    1
    2
    3
    4
    heros
    .stream()
    .filter(h -> h.hp > 100 && h.damage < 50) // 过滤,获取 hp > 100 并且 damage < 50 的对象
    .forEach(h -> System.out.println(h.name)); // 遍历,输出 name
文章目录
  1. 1. 前言
  2. 2. 1、Lambda 表达式
  3. 3. 2、方法引用
  4. 4. 3、聚合操作
隐藏目录