Java Lambda表达式多场景下使用详解

Java Lambda表达式详细使用教程

Lambda表达式是Java 8引入的一个重要特性,它允许我们以更简洁的方式表示匿名函数。本教程将详细介绍Java Lambda表达式的语法、用法和应用场景。

1. Lambda表达式基础

1.1 基本语法

Java Lambda表达式的基本语法如下:

(参数列表) -> {
    表达式或语句块 }
  • 参数列表:可以为空或包含多个参数,类型可以显式声明或由编译器推断
  • 箭头操作符-> 将参数列表与Lambda体分开
  • Lambda体:包含表达式或语句块

1.2 简化规则

Lambda表达式可以根据以下规则进行简化:

  1. 当参数只有一个且类型可推断时,可以省略参数的小括号
  2. 当Lambda体只有一条语句时,可以省略大括号
  3. 当Lambda体只有一条返回语句时,可以省略return关键字
// 标准形式
(int x, int y) -> {
    return x + y; }

// 省略参数类型
(x, y) -> {
    return x + y; }

// 省略大括号和return关键字
(x, y) -> x + y

// 单个参数时省略小括号
x -> x * x

2. 函数式接口

Lambda表达式需要与函数式接口配合使用。函数式接口是只包含一个抽象方法的接口,可以使用@FunctionalInterface注解标记。

2.1 常用函数式接口

Java 8在java.util.function包中提供了许多预定义的函数式接口:

import java.util.function.*;

public class FunctionalInterfacesDemo {
   
    public static void main(String[] args) {
   
        // Predicate<T> - 接收T类型参数,返回boolean
        Predicate<Integer> isPositive = x -> x > 0;
        System.out.println("Is 5 positive? " + isPositive.test(5)); // true
        
        // Function<T, R> - 接收T类型参数,返回R类型结果
        Function<Integer, String> intToString = x -> "Number: " + x;
        System.out.println(intToString.apply(10)); // Number: 10
        
        // Consumer<T> - 接收T类型参数,无返回值
        Consumer<String> printer = s -> System.out.println("Consuming: " + s);
        printer.accept("Hello Lambda"); // Consuming: Hello Lambda
        
        // Supplier<T> - 无参数,返回T类型结果
        Supplier<Double> randomValue = () -> Math.random();
        System.out.println("Random value: " + randomValue.get()); // 随机数
        
        // BiFunction<T, U, R> - 接收T和U类型参数,返回R类型结果
        BiFunction<Integer, Integer, Integer> add = (x, y) -> x + y;
        System.out.println("5 + 3 = " + add.apply(5, 3)); // 8
        
        // UnaryOperator<T> - Function的特例,输入和输出类型相同
        UnaryOperator<Integer> square = x -> x * x;
        System.out.println("Square of 4: " + square.apply(4)); // 16
        
        // BinaryOperator<T> - BiFunction的特例,两个输入和输出类型都相同
        BinaryOperator<Integer> multiply = (x, y) -> x * y;
        System.out.println("4 * 5 = " + multiply.apply(4, 5)); // 20
    }
}

2.2 自定义函数式接口

我们也可以创建自己的函数式接口:

@FunctionalInterface
interface MathOperation {
   
    int operate(int a, int b);
    
    // 可以包含默认方法
    default MathOperation andThen(MathOperation after) {
   
        return (a, b) -> after.operate(this.operate(a, b), 0);
    }
    
    // 可以包含静态方法
    static MathOperation addition() {
   
        return (a, b) -> a + b;
    }
}

public class CustomFunctionalInterfaceDemo {
   
    public static void main(String[] args) {
   
        // 使用Lambda表达式实现自定义函数式接口
        MathOperation addition = (a, b) -> a + b;
        MathOperation subtraction = (a, b) -> a - b;
        
        System.out.println("10 + 5 = " + addition.operate(10, 5)); // 15
        System.out.println("10 - 5 = " + subtraction.operate(10, 5)); // 5
        
        // 使用默认方法
        MathOperation addThenMultiplyBy2 = addition.andThen((a, b) -> a * 2);
        System.out.println("(10 + 5) * 2 = " + addThenMultiplyBy2.operate(10, 5)); // 30
        
        // 使用静态方法
        MathOperation add = MathOperation.addition();
        System.out.println("7 + 3 = " + add.operate(7, 3)); // 10
    }
}

3. Lambda表达式与集合操作

Lambda表达式与Stream API结合,可以大大简化集合操作。

3.1 遍历集合

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

public class CollectionTraversalDemo {
   
    public static void main(String[] args) {
   
        List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "Dave");
        
        // 传统方式
        System.out.println("传统for循环:");
        for (int i = 0; i < names.size(); i++) {
   
            System.out.println(names.get(i));
        }
        
        // 增强for循环
        System.out.println("\n增强for循环:");
        for (String name : names) {
   
            System.out.println(name);
        }
        
        // Lambda表达式 - forEach
        System.out.println("\nLambda forEach:");
        names.forEach(name -> System.out.println(name));
        
        // 方法引用 - 更简洁的Lambda
        System.out.println("\n方法引用:");
        names.forEach(System.out::println);
    }
}

3.2 过滤、映射和归约

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

public class StreamOperationsDemo {
   
    public static void main(String[] args) {
   
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        
        // 过滤 - 获取偶数
        List<Integer> evenNumbers = numbers.stream()
                                          .filter(n -> n % 2 == 0)
                                          .collect(Collectors.toList());
        System.out.println("偶数: " + evenNumbers); // [2, 4, 6, 8, 10]
        
        // 映射 - 将每个数平方
        List<Integer> squaredNumbers = numbers.stream()
                                             .map(n -> n * n)
                                             .collect(Collectors.toList());
        System.out.println("平方后: " + squaredNumbers); // [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
        
        // 归约 - 求和
        int sum = numbers.stream()
                        .reduce(0, (a, b) -> a + b);
        System.out.println("总和: " + sum); // 55
        
        // 方法引用形式的归约
        int product = numbers.stream()
                            .reduce(1, (a, b) -> a * b);
        System.out.println("乘积: " + product); // 3628800
        
        // 组合操作 - 获取偶数的平方和
        int sumOfSquaresOfEvens = numbers.stream()
                                        .filter(n -> n % 2 == 0)
                                        .map(n -> n * n)
                                        .reduce(0, Integer::sum);
        System.out.println("偶数平方和: " + sumOfSquaresOfEvens); // 220
    }
}

4. 方法引用

方法引用是Lambda表达式的一种简化形式,当Lambda表达式仅调用一个已存在的方法时,可以使用方法引用。

4.1 方法引用的类型

import java.util.Arrays;
import 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

qzw1210

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

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

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

打赏作者

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

抵扣说明:

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

余额充值