Java中Lambda表达式的简单介绍

目录

一、简介

二、组成部分

三、使用场景

四、优点与注意事项

五、函数式接口

六、方法引用

七、使用示例

一、简介

Lambda表达式是 Java 8 引入的新特性,提供了一种简洁明了的方式来表示匿名函数(没有声明的方法)。它使得函数式编程在Java中成为可能,大大简化了代码,提高了可读性和可维护性。

基本语法

(参数列表) -> 表达式
或
(参数列表) -> { 代码块 }
  • 参数列表:可以为空(())或包含一个或多个参数。
  • 箭头操作符->,将参数列表与方法体分隔开。
  • 方法体:可以是一个表达式或一段代码块。

二、组成部分

Lambda表达式由以下三个部分组成:

  1. 参数列表

    • 表示输入参数,可以有0个、1个或多个。
    • 如果有多个参数,用逗号分隔。
    • 类型声明可选:参数类型可以明确声明,也可以省略,由编译器根据上下文推断。
    • 如果只有一个参数,圆括号可以省略。

    示例:

    (int x, int y) -> x + y   // 类型声明
    (x, y) -> x + y           // 类型推断
    x -> x * x                // 单个参数,省略括号
    () -> System.out.println("Hello") // 无参数
    
  2. 箭头操作符 (->)

    • 将参数列表与方法体分隔开。
    • ->是Lambda表达式的核心语法符号。
  3. 方法体

    • 定义Lambda表达式要执行的功能,可以是:
      • 单个表达式(无需大括号,值会自动作为返回值)。
      • 代码块(用大括号包裹,需要显式使用return返回值)。
    • 方法体的形式决定大括号和返回关键字的使用规则:
      • 单表达式:省略大括号和return
      • 代码块:必须加大括号,返回值需显式return

    示例:

    (x, y) -> x + y           // 单表达式,返回x + y的值
    (x, y) -> { return x + y; } // 代码块,显式返回x + y的值
    () -> System.out.println("Hello World") // 无返回值
    

三、使用场景

1. 函数式接口

函数式接口是只包含一个抽象方法的接口,通常会在接口上使用@FunctionalInterface注解。Lambda表达式最常见的用途就是替代匿名内部类来实现函数式接口。

示例

@FunctionalInterface
interface MathOperation {
    int operation(int a, int b);
}

// 使用Lambda表达式
MathOperation addition = (a, b) -> a + b;
int result = addition.operation(5, 3); // 输出8

2. 结合集合框架

Lambda表达式与Java集合框架的Stream API紧密结合,方便进行集合数据的过滤、映射、归约等操作。

示例

List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");

// 过滤出以字母'C'开头的名字并打印
names.stream()
     .filter(name -> name.startsWith("C"))
     .forEach(System.out::println); // 输出 "Charlie"

四、优点与注意事项

优点:

  1. 代码简洁:消除了匿名内部类的冗长代码,使代码更加精炼。
  2. 可读性高:代码结构清晰,逻辑一目了然。
  3. 提高效率:支持并行流处理,充分利用多核CPU的优势。
  4. 灵活性强:与函数式接口、方法引用等特性结合,增强了代码的灵活性。

注意事项:

  1. 只能用于函数式接口:Lambda表达式需要一个目标类型,该类型必须是函数式接口。
  2. 变量作用域:Lambda表达式中使用的局部变量必须是final有效的final(即其值在初始化后未被修改)。
  3. 检查异常:Lambda表达式中如果抛出受检异常,必须在接口的抽象方法中声明该异常。
  4. 调试困难:Lambda表达式的堆栈信息可能不如传统代码直观,调试时需要注意。

五、函数式接口

Java 8在java.util.function包中提供了一系列通用的函数式接口,如:

  • Predicate<T>:接收一个参数,返回boolean值。

    Predicate<String> isEmpty = s -> s.isEmpty();
    System.out.println(isEmpty.test("")); // true
    System.out.println(isEmpty.test("Hello")); // false
    
  • Function<T, R>:接收一个参数,返回一个结果。

    Function<Integer, String> intToString = num -> "Number: " + num;
    System.out.println(intToString.apply(10)); // 输出 "Number: 10"
    
  • Consumer<T>:接收一个参数,无返回值。

    Consumer<String> printer = s -> System.out.println(s);
    printer.accept("Hello World!"); // 输出 "Hello World!"
    
  • Supplier<T>:不接收参数,返回一个结果。

    Supplier<Double> randomSupplier = () -> Math.random();
    System.out.println(randomSupplier.get()); // 输出一个随机数
    
  • BinaryOperator<T>:接收两个相同类型的参数,返回一个相同类型的结果。

    BinaryOperator<Integer> adder = (a, b) -> a + b;
    System.out.println(adder.apply(10, 20)); // 输出 30
    

六、方法引用

如果Lambda表达式仅调用一个已存在的方法,可以使用方法引用来替代,语法更加简洁。

语法

  • 对象的实例方法引用:instance::method
  • 类的静态方法引用:Class::staticMethod
  • 类的实例方法引用:Class::instanceMethod

示例

public class LambdaClassSuper {
    LambdaInterface sf(){
        return null;
    }
}

public class LambdaClass extends LambdaClassSuper {
    public static LambdaInterface staticF() {
        return null;
    }

    public LambdaInterface f() {
        return null;
    }

    void show() {
        //1.调用静态函数,返回类型必须是functional-interface
        LambdaInterface t = LambdaClass::staticF;

        //2.实例方法调用
        LambdaClass lambdaClass = new LambdaClass();
        LambdaInterface lambdaInterface = lambdaClass::f;

        //3.超类上的方法调用
        LambdaInterface superf = super::sf;

        //4. 构造方法调用
        LambdaInterface tt = LambdaClassSuper::new;
    }
}

七、使用示例

实现线程:

// 传统方式
new Thread(new Runnable() {
    @Override
    public void run() {
        System.out.println("Thread is running");
    }
}).start();

// 使用Lambda表达式
new Thread(() -> System.out.println("Thread is running")).start();

列表排序:

List<Integer> strings = Arrays.asList(1, 2, 3);
//传统方式
Collections.sort(strings, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
    return o1 - o2;}
});

//Lambda
Collections.sort(strings, (Integer o1, Integer o2) -> o1 - o2);
//分解开
Comparator<Integer> comparator = (Integer o1, Integer o2) -> o1 - o2;
Collections.sort(strings, comparator);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值