莫度编程网

技术文章干货、编程学习教程与开发工具分享

39. Lambda 表达式,语法形态解析

哈喽 大家好!

我是老陈,这节课一起来学习Lambda 表达式,Lambda就像 “匿名函数的速写本”,用极简语法替代冗长的匿名内部类,让代码像数学公式一样简洁! 核心思想是:将 “行为” 作为参数传递,用极简语法替代冗长代码。

39.1 Lambda 的核心特性:行为参数化与极简语法

Lambda 就像 “可传递的代码片段”,比如让线程执行一段代码时,无需定义完整的类,直接传递() -> System.out.println("Hello")这样的代码块,就像给机器人下达即时指令。

package com.lambda.demo;

import java.util.Arrays;
import java.util.Comparator;

/**
 * @author 今日头条:老陈说编程
 * Lambda表达式与匿名内部类的语法对比
 * 展示Java中传统匿名内部类和Lambda表达式在实现函数式接口时的语法差异
 */
public class LambdaBasicFeatures {
    public static void main(String[] args) {
        // 1. 匿名内部类实现Runnable接口 
        // 创建一个实现Runnable接口的匿名类实例,重写run方法 
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("匿名内部类线程");
            }
        }).start();

        // 2. Lambda表达式实现Runnable接口(无参数、无返回值) 
        // 使用Lambda表达式简化语法,省略接口名和方法名,直接实现功能逻辑 
        new Thread(() -> System.out.println("Lambda线程")).start();

        // 3. 匿名内部类实现Comparator接口 
        // 创建一个字符串数组用于排序演示 
        String[] names = {"张三", "李四", "王五"};
        // 使用匿名内部类实现Comparator接口,按字符串长度比较 
        Arrays.sort(names, new Comparator<String>() {
            @Override
            public int compare(String a, String b) {
                return a.length() - b.length(); // 升序排序 
            }
        });

        // 4. Lambda表达式实现Comparator接口(有参数、有返回值) 
        // 使用Lambda表达式进一步简化Comparator实现 
        // (a, b) -> a.length() - b.length() 等价于匿名内部类的完整实现 
        Arrays.sort(names, (a, b) -> a.length() - b.length());
        System.out.println("排序结果:" + Arrays.toString(names)); // 输出按长度排序后的数组 
    }
} 

39.2 核心语法:Lambda 表达式的五种形态

使用 Lambda 就像 “写数学表达式”—— 根据参数和返回值的不同,有五种简洁写法,从() -> {}到(a,b) -> a+b,每种形态都对应不同的业务场景。

package com.lambda.demo;

import java.util.function.*;

/**
 * @author 今日头条:老陈说编程
 * Lambda表达式五种语法形态综合演示
 * 展示了从无参数到多参数,从无返回值到有返回值的Lambda表达式写法
 */
public class LambdaSyntax {
    public static void main(String[] args) {
        // 1. 无参数无返回值的Lambda表达式
        // 实现Runnable接口,重写无参run()方法
        Runnable r1 = () -> System.out.println("无参数Lambda");

        // 2. 单参数无返回值的Lambda表达式
        // 完整写法:显式指定参数类型和括号
        Consumer<String> c1 = (String s) -> System.out.println(s.toUpperCase());
        // 简化写法:省略参数类型和括号(单参数可省略括号)
        Consumer<String> c2 = s -> System.out.println(s.toUpperCase());

        // 3. 多参数无返回值的Lambda表达式
        // 使用BiConsumer函数式接口,接收两个不同类型参数
        // 使用代码块语法,可包含多条语句
        BiConsumer<Integer, String> bc = (i, s) -> {
            System.out.println(i + ": " + s);
        };

        // 4. 单参数有返回值的Lambda表达式
        // 完整写法:显式指定参数类型为Integer
        Function<Integer, Integer> f1 = (Integer x) -> x * x;
        // 简化写法:省略参数类型、return关键字和花括号(单行表达式)
        Function<Integer, Integer> f2 = x -> x * x;

        // 5. 多参数有返回值的Lambda表达式
        // 使用BinaryOperator函数式接口,接收两个同类型参数并返回同类型结果
        // 显式指定参数类型为Double
        BinaryOperator<Double> bo = (Double a, Double b) -> {
            double result = a + b;
            return result * 0.5;
        };

        // 调用示例:演示各个Lambda表达式的执行效果
        r1.run(); // 执行无参Lambda
        c2.accept("lambda"); // 处理字符串并转换为大写
        bc.accept(1, "示例"); // 组合整数和字符串输出
        System.out.println("计算结果:" + f2.apply(5)); // 计算平方值
        System.out.println("计算结果:" + bo.apply(10.0, 20.0)); // 计算平均值
    }
} 

39.3 Lambda 与设计模式:函数式编程的架构实践

策略模式就像 "多功能计算器",不同计算策略是可更换的计算模块。Lambda 表达式则让这些模块的插拔变得像 "换电池" 一样简单!

package com.lambda.demo;

import java.util.function.Function;

/**
 * @author 今日头条:老陈说编程
 * Lambda简化策略模式(计算策略)
 * 演示传统策略模式与Lambda表达式的结合使用
 */
public class LambdaStrategyPattern {
    // 传统策略模式:定义计算策略接口
    interface Calculator {
        int calculate(int a, int b);
    }

    // 使用高阶函数的策略模式:通过Function接口实现双重参数传递
    // 参数说明:
    // - a, b:参与计算的两个整数
    // - strategy:接收第一个参数并返回另一个Function的函数,第二个Function接收第二个参数并返回计算结果
    static int compute(int a, int b, Function<Integer, Function<Integer, Integer>> strategy) {
        return strategy.apply(a).apply(b);
    }

    public static void main(String[] args) {
        // 1. 传统方式:创建匿名内部类实现策略接口
        Calculator add = new Calculator() {
            @Override
            public int calculate(int a, int b) {
                return a + b;
            }
        };
        System.out.println("传统加法:" + add.calculate(5, 3)); // 输出: 8 

        // 2. Lambda方式:直接传递计算策略
        // a -> b -> a + b 等价于:
        // Function<Integer, Function<Integer, Integer>> addStrategy = a -> {
        //     return b -> a + b;
        // };
        int sum = compute(5, 3, a -> b -> a + b);

        // Lambda乘法策略:直接传递乘法逻辑
        int product = compute(5, 3, a -> b -> a * b);
        System.out.println("Lambda加法:" + sum); // 输出: 8 
        System.out.println("Lambda乘法:" + product); // 输出: 15 

        // 3. 方法引用方式:使用Math类的subtractExact方法
        int subtract = compute(5, 3, a -> b -> Math.subtractExact(a, b));
        System.out.println("方法引用减法:" + subtract); // 输出: 2 
    }
} 

39.4 与 Stream API 结合:Lambda 的最佳拍档

Lambda 与 Stream API 的组合就像 “数据处理的流水线”—— 用 Lambda 定义处理逻辑(如过滤、映射、排序),Stream 负责高效执行,让复杂的数据处理变得像写数学公式一样简洁。

package com.lambda.demo;

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

/**
 * @author 今日头条:老陈说编程
 * Lambda与Stream API结合实现复杂数据处理
 * 演示传统集合处理方式与函数式流处理方式的对比
 */
public class LambdaStream {
    public static void main(String[] args) {
        // 初始化示例数据:包含姓名和年龄的字符串列表
        List<String> names = Arrays.asList("张三,25", "李四,30", "王五,22", "赵六,35");

        // 需求:筛选年龄>25的人,按年龄升序排列,获取姓名首字+年龄的字符串
        // 传统方式:多层循环+条件判断 
        List<String> result1 = new ArrayList<>();
        // 遍历每个元素并解析
        for (String str : names) {
            String[] arr = str.split(","); // 分割姓名和年龄
            String name = arr[0];
            int age = Integer.parseInt(arr[1]);
            // 筛选年龄>25的记录
            if (age > 25) {
                // 格式化结果:姓名首字+年龄
                result1.add(name.charAt(0) + "(" + age + ")");
            }
        }
        // 手动提取年龄进行排序
        Collections.sort(result1, (a, b) -> {
            int ageA = Integer.parseInt(a.substring(a.indexOf('(') + 1, a.indexOf(')')));
            int ageB = Integer.parseInt(b.substring(b.indexOf('(') + 1, b.indexOf(')')));
            return ageA - ageB; // 升序排列
        });
        System.out.println("传统方式:" + result1); // [李(30), 赵(35)] 

        // Lambda+Stream方式:链式调用,代码更简洁
        List<String> result2 = names.stream()
                .map(s -> s.split(",")) // 将字符串分割为数组
                .filter(arr -> Integer.parseInt(arr[1]) > 25) // 过滤年龄>25的元素
                .map(arr -> arr[0].charAt(0) + "(" + arr[1] + ")") // 映射为格式化字符串
                .sorted((a, b) -> { // 按年龄升序排序
                    int ageA = Integer.parseInt(a.substring(a.indexOf('(') + 1, a.indexOf(')')));
                    int ageB = Integer.parseInt(b.substring(b.indexOf('(') + 1, b.indexOf(')')));
                    return ageA - ageB;
                })
                .collect(Collectors.toList()); // 收集结果到列表
        System.out.println("Lambda+Stream:" + result2); // [李(30), 赵(35)] 
    }
} 




#java##程序员##计算机##编程##热搜##今日头条##热门##软件开发##ai#

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言

    Powered By Z-BlogPHP 1.7.4

    蜀ICP备2024111239号-43