JavaSE -- Lambda表达式

Lambda表达式

Lambda 表达式,也可称为闭包,它是 Java 8 发布的最重要新特性。Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中),允许用表达式代替功能性接口。使用 Lambda 表达式可以使代码变的更加简洁紧凑,但是随之而来的是代码可读性变差。

语法

java 复制代码
(parameters) -> expression
或
(parameters) ->{ statements; }
  • parameters 是参数列表,

  • expression{ statements; } 是Lambda 表达式的主体。

案例

在匿名内部类上面使用 Lambda,效果更加明显

java 复制代码
// 传统的匿名内部类
Runnable runnable1 = new Runnable() {
    @Override
    public void run() {
        System.out.println("Hello World!");
    }
};

// 使用 Lambda 表达式
Runnable runnable2 = () -> System.out.println("Hello World!");

函数式接口介绍

一个接口只有一个抽象方法的接口叫做函数式接口

基本使用

  • 如果只有一个参数,可以省略括号;
  • 如果没有参数,也需要空括号
  • 只有一行语句,可以省略大括号
  • 无参,无返回值,只有一行语句(多行语句时大括号不能省略)
java 复制代码
public class Main {
    public static void main(String[] args) {
        Inter inter = () -> System.out.println("Hello");
        inter.test();
    }
}
interface Inter {
    void test();
}
  • 有一个参数,无返回值,只有一行语句(多行语句时大括号不能省略)
java 复制代码
public class Main {
   public static void main(String[] args) {
       //参数类型可以不用写,会自动推测
       Inter inter = str -> System.out.println(str);
       inter.test("Hello");
   }
}
interface Inter {
   void test(String str);
}
  • 有一个参数,有返回值,只有一行语句(多行语句时大括号不能省略)
java 复制代码
public class Main {
    public static void main(String[] args) {
        //参数类型可以不用写,会自动推测
        Inter inter = str -> str;
        inter.test("Hello");
    }
}
interface Inter {
    String test(String str);
} 	 

内置的函数式接口

上面我们介绍的 Lambda 的基本使用, 我们每次要使用某种类型的函数式接口都要自己先创建一个函数式接口,比较繁琐,所以在 JDK8 之后,就内置了 4 个核心的函数式接口供我们使用。

简单介绍
核心函数式接口
接口 特点 抽象方法
Consumer< T > 有参,无返回值 accept(T t)
Supplier< T > 无参,有返回值 get()
Function< T, R > 有参,有返回值 apply(T t)
Predicate< T > 有参有返回值,返回 Boolean 类型 test(T t)
其他函数式接口

对于这些函数式接口,其实就是对核心的函数式接口做了扩展,不如参数数量增加等等

接口 特点 抽象方法
BiConsumer< T, U > 接收两个不同类型的参数,无返回值 accept(T t, U u)
BiFunction< T, U ,R > 接收两个不同类型的参数,返回一个结果 R apply(T t, U u)
UnaryOperator< T > 输入和输出类型相同 T apply(T t)
BinaryOperator 对两个同类型操作数进行运算,返回同类型结果 T apply(T t,T t)
详细介绍(核心函数式接口)
Consumer<T>:消费型接口
  • 抽象方法void accept(T t)
  • 用途:接收一个参数并执行操作,无返回值
基本使用
java 复制代码
public static void main(String[] args) {
    // 使用 lambda 表达式实现 Consumer
    Consumer<String> printer = (str) -> System.out.println(str);

    // 调用 accept 方法
    printer.accept("Hello");
}
遍历集合
java 复制代码
public static void main(String[] args) {
    List<String> names = Arrays.asList("Alice", "Bob", "Charlie");

    // 使用 Consumer 遍历集合,forEach 的参数就是一个 Consumer 接口
    names.forEach(name -> System.out.println("Hello, " + name));
}
Supplier<T>:供给型接口
  • 抽象方法T get()
  • 用途:不接收参数,返回一个值
基本使用
java 复制代码
public static void main(String[] args) {
     // 使用 lambda 表达式实现 Supplier
    Supplier<Double> randomSupplier = () -> Math.random();

    // 调用 get 方法获取值
    System.out.println(randomSupplier.get());
}
Function<T,R>:函数型接口
  • 抽象方法R apply(T t)
  • 用途:接收一个参数,返回一个结果
基本使用
java 复制代码
public static void main(String[] args) {
    // 将字符串转换为整数
    // 使用 lambda 表达式实现 Function
    Function<String, Integer> stringToInt = str -> Integer.parseInt(str);

    // 调用 apply 方法
    Integer result = stringToInt.apply("123");
}
Predicate<T>:断言型接口
  • 抽象方法boolean test(T t)
  • 用途:接收一个参数,返回布尔值
基本使用
java 复制代码
public static void main(String[] args) {
    // 判断字符串长度是否大于 5
    Predicate<String> lengthChecker = str -> str.length() > 5;

    // 调用 test 方法
    System.out.println(lengthChecker.test("HelloWorld")); // 输出: true
    System.out.println(lengthChecker.test("Hi"));        // 输出: false
}

方法引用

介绍

在Java中,方法引用是一种强大的功能,它允许您在Lambda表达式中引用方法,而不是在表达式中直接定义这些方法。方法引用使代码更加简洁和可读,尤其在函数式编程中非常有用。

使用前提

如果 Lambda 表达式体中的方法已经被实现过了,就可以使用方法引用,Lambda 表达式引用的方法的参数列表和返回值要和函数式接口的中定义的抽象方法参数列表和返回值一致

语法格式
  • 静态方法引用:类名::静态方法名
  • 实例方法引用:实例对象名::实例方法名
  • 特殊方法引用:类名::实例方法名
  • 构造方法引用:类名::new
静态方法引用
没使用静态方法引用
java 复制代码
public class Main {
    public static void main(String[] args) {
        Consumer<String> consumer = s -> Test.test(s);
        consumer.accept("Hello");
    }
}
class Test {
    public static void test(String str) {
        System.out.println(str);
    }
}
使用静态方法引用
java 复制代码
public class Main {
    public static void main(String[] args) {
        Consumer<String> consumer = Test::test;
        consumer.accept("Hello");
    }
}
class Test {
    //静态方法
    public static void test(String str) {
        System.out.println(str);
    }
}
实例方法引用
  • 引用前
  • 引用后
  • 对于集合遍历也可以使用到该方式
特殊方法引用

当我们函数有参数的时候,且第一个参数调用方法,则可以使用特殊方法引用

  • 使用前
  • 使用后
构造方法引用
  • 使用前

  • 使用后

数组构造引用
super 和 this 引用

主要用于在一个方法中的函数接口调用了,父类的某个方法或者本类的某个方法

相关推荐
景彡先生3 分钟前
C++17 并行算法:std::execution::par
开发语言·c++
JiaJZhong14 分钟前
力扣.最长回文子串(c++)
java·c++·leetcode
Xy91023 分钟前
开发者视角:App Trace 一键拉起(Deep Linking)技术详解
java·前端·后端
nextera-void37 分钟前
仓颉编程语言:从入门到精通
开发语言
一个混子程序员39 分钟前
Mockito不常用的方法
java
oioihoii41 分钟前
C++随机打乱函数:简化源码与原理深度剖析
开发语言·c++·算法
敏叔V5871 小时前
SpringBoot实现MCP
java·spring boot·后端
小袁拒绝摆烂1 小时前
SpringCache整合SpringBoot使用
java·spring boot·后端
水果里面有苹果1 小时前
19-C#静态方法与静态类
java·开发语言·c#
minji...1 小时前
数据结构 算法复杂度(1)
c语言·开发语言·数据结构·算法