Java Lambda 表达式详解

文章目录

  • 1、Lambda 表达式的基本语法回顾
  • 2、 常用函数式接口及案例
  • 3、更多方法和案例
  • 4、自定义函数接口
  • 5、Lambda 表达式的优势和注意事项

Java Lambda表达式Java 8 引入的一项重大特性,它彻底改变了 Java语言的编程方式,尤其是在处理集合、线程以及事件监听等方面。

Lambda 表达式不仅简化了代码,还提高了代码的可读性和灵活性,使得开发者能够以更声明式的方式表达他们的意图。

1、Lambda 表达式的基本语法回顾

Lambda表达式的基本语法为:

(parameter1, parameter2, ..., parameterN) -> { // Lambda body }

参数列表:可以包含零个或多个参数,参数类型可以省略,因为 JVM 会通过上下文进行类型推断。
箭头符号:-> 将参数列表与 Lambda 主体分隔开。
Lambda 主体:可以是一个表达式或一组语句。如果是一个表达式,其值会被自动返回;如果是一组语句,则需要用大括号括起来,并可能需要显式返回值。

2、 常用函数式接口及案例

Java 8提供了一系列内置的函数式接口,这些接口位于 java.util.function 包中,包括但不限于 Predicate, Consumer, Function, Supplier等。

Predicate 接口
用于判断条件是否满足,返回 boolean 值

import java.util.Arrays;
import java.util.List;

public class PredicateExample {
    public static void main(String[] args) {
        List<String> languages = Arrays.asList("Java", "Python", "JavaScript");
        languages.removeIf(language -> language.startsWith("Java")); // 使用 Lambda 表达式
        System.out.println(languages); // 输出: [Python]
    }
}

Consumer 接口
用于消费数据,不返回任何值。

import java.util.Arrays;
import java.util.List;

public class ConsumerExample {
    public static void main(String[] args) {
        List<String> languages = Arrays.asList("Java", "Python", "JavaScript");
        languages.forEach(language -> System.out.println(language.toUpperCase())); // 使用 Lambda 表达式
    }
}

Function 接口
用于将输入转换为输出,接受一个输入参数,返回一个结果。

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class FunctionExample {
    public static void main(String[] args) {
        List<String> fruits = Arrays.asList("apple", "banana", "orange");
        List<Integer> lengths = fruits.stream().map(fruit -> fruit.length()).collect(Collectors.toList()); // 使用 Lambda 表达式
        System.out.println(lengths); // 输出: [5, 6, 6]
    }
}

3、更多方法和案例

filter() 方法:过滤集合中的元素。

List<String> filteredFruits = fruits.stream().filter(fruit -> fruit.startsWith("a")).collect(Collectors.toList());
System.out.println(filteredFruits); // 输出: [apple]

sorted() 方法:对集合进行排序。

List<String> sortedFruits = fruits.stream().sorted((fruit1, fruit2) -> fruit1.compareTo(fruit2)).collect(Collectors.toList());
System.out.println(sortedFruits); // 输出: [apple, banana, orange]

thenApply() 方法:处理 CompletableFuture 的结果。

CompletableFuture.supplyAsync(() -> 42).thenApply(result -> result * 2).thenAccept(System.out::println); // 输出: 84

Runnable 和 Callable 接口:创建线程和异步任务。

Runnable runnable = () -> System.out.println("Hello from Runnable!");
new Thread(runnable).start();

// Callable
Callable<Integer> callable = () -> {
    TimeUnit.SECONDS.sleep(1);
    return 42;
};
ExecutorService executor = Executors.newCachedThreadPool();
Future<Integer> future = executor.submit(callable);
Integer result = future.get();
System.out.println(result); // 输出: 42
executor.shutdown();

4、自定义函数接口

除了使用内置的函数式接口外,我们还可以自定义自己的函数接口,并通过 Lambda 表达式来实现它们。

@FunctionalInterface
interface Calculator {
    int calculate(int a, int b);
}

public class CustomLambdaExample {
    public static void main(String[] args) {
        // 使用 Lambda 表达式实现 Calculator 接口
        Calculator add = (a, b) -> a + b;
        int sum = add.calculate(10, 5);
        System.out.println("10 + 5 = " + sum); // 输出: 10 + 5 = 15

        // 另一个 Lambda 表达式实现,用于减法
        Calculator subtract = (a, b) -> a - b;
        int difference = subtract.calculate(10, 5);
        System.out.println("10 - 5 = " + difference); // 输出: 10 - 5 = 5
    }
}

5、Lambda 表达式的优势和注意事项

  • 优势:
    • 简化代码:Lambda 表达式使得匿名内部类的语法更加简洁。
    • 提高可读性:使得代码更加直观,易于理解。
    • 函数式编程风格:促进了一种更声明式的编程风格。
  • 注意事项:
    • 性能:在某些情况下,Lambda 表达式可能比传统的匿名内部类稍慢,因为 JVM需要进行额外的类型推断和调用动态绑定。
    • 调试:Lambda 表达式的调试可能比较困难,因为它们没有名称和行号信息。
    • 过度使用:不要滥用 Lambda 表达式,尤其是在复杂的业务逻辑中,应该权衡代码的可读性和维护性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

bjzhang75

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

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

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

打赏作者

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

抵扣说明:

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

余额充值