【函数式编程001】Java 8 中 Lambda 与 四种常见内置函数式接口的实战用法

608564A16E7D652E882914E830EE4050(1)


📚博客主页:代码探秘者

✨专栏:文章正在持续更新ing…

✅C语言/C++:C++(详细版) 数据结构) 十大排序算法

✅Java基础:JavaSE基础 面向对象大合集 JavaSE进阶 Java版数据结构JDK新特性

✅前端基础: 前端三剑客 必学前端技术栈

✅后端经典框架: 后端基础 SpringBoot Tlias项目(含SSM)

✅数据库:Mysql

✅常用中间件:redis入门+实战 Elasticsearch RabbitMQ

✅Linux: 部署篇

✅微服务:微服务

❤️感谢大家点赞👍🏻收藏⭐评论✍🏻,您的三连就是我持续更新的动力❤️

🙏作者水平有限,欢迎各位大佬指点,相互学习进步!


img


下面 详细讲解 Java 8 的 Lambda 表达式,包括其语法、原理、使用场景以及一些注意事项。

一、入门必备

🧩 本节内容gitee仓库链接:https://gitee.com/blue-national-gold/java/tree/master/java_NewFeatures/src/com/java8/Lambda

也可以点击这里快速跳转,麻烦帮忙点个Star星星

在这里插入图片描述


🔹什么是 Lambda 表达式?

Lambda 表达式是一种 匿名函数,用于简洁地表示函数式接口的实例(只有一个抽象方法的接口)。本质上它是用来实现函数式接口的一种简洁写法。


🔹基本语法

(参数列表) -> { 方法体 }

✅ 简化规则

情况示例
无参数,无返回值() -> System.out.println("Hello")
一个参数,可省略小括号x -> x * x
多个参数,多行代码(x, y) -> { int z = x + y; return z; }
只有一行代码且有返回值,可省略 return 和大括号(x, y) -> x + y

✅ 优点

优点描述
简洁减少冗余代码
易读用意明确,结构清晰
强大配合 Stream API,极大提升集合操作能力
高效编译器优化 & JVM invokedynamic 支持

🔹Lambda 示例

1. 替代匿名内部类(如 Runnable)

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

2. 用于排序(Comparator)

  • 按照字符串长度排序
@Test
public void test01(){
  List<String> fruits = Arrays.asList("cpp", "c", "java", "python");
  fruits.sort((s1,s2)->s1.length()-s2.length());  //升序
  System.out.println(fruits);
}

image-20250608151912508

  • 按照对象的多个字段属性排序
class Person {
    String name;
    int age;
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public String toString() {
        return name + " (" + age + ")";
    }
}

List<Person> people = Arrays.asList(
    new Person("Alice", 30),
    new Person("Bob", 25),
    new Person("Charlie", 30),
    new Person("David", 20)
);

// 按年龄升序;如果年龄相同,按名字字母排序
people.sort((p1, p2) -> {
    if (p1.age != p2.age) return p1.age - p2.age;
    return p1.name.compareTo(p2.name);
});

System.out.println(people);
// 输出: [David (20), Bob (25), Alice (30), Charlie (30)]

3. 与函数式接口结合使用

函数式接口就是——只定义了一个抽象方法的接口。

它的作用是:为了让你可以像传“函数”一样,传一段行为(代码)进去。

特性说明
只允许一个抽象方法这是函数式接口的定义
可以有默认方法和静态方法但只能有一个“真正要你实现”的抽象方法
用 @FunctionalInterface 标注(建议)编译器帮你检查是否符合要求
支持 Lambda 表达式创建对象是 Lambda 表达式的应用基础
@FunctionalInterface
interface MyMath {
    int operate(int a, int b);
}

public void test(MyMath m) {
    int result = m.operate(20, 10);
    System.out.println(result);
}

// 使用 Lambda 简化调用
test((a,b)->a+b);
test((a,b)->a-b);
test((a,b)->a*b);
test((a,b)->a/b);

image-20250608153313322


🔹 常用函数式接口(Java 内置)

接口名参数返回值用途
Function<T, R>TR输入 T,返回 R
Consumer<T>Tvoid对 T 执行操作
Predicate<T>Tboolean判断 T 是否满足条件
Supplier<T>T提供 T 的实例

1.示例:

@Test
public void testdemo02(){
  String str="AA,hello world";
  //差不多Lambda表达式重写了函数式接口的apply方法
  //传参返回
  Function<String,Integer> f=s->s.length();
  //传参不返回
  Consumer<String> c=s-> System.out.println(s);
  //传参,返回boolean
  Predicate<String> p=s->s.startsWith("A");
  //不传参,返回
  Supplier<Double> s=()->Math.random();


  //调用执行
  System.out.println(f.apply(str));//f.apply(str) 相当与s.length()
  c.accept(str);
  System.out.println(p.test(str));
  System.out.println(s.get());
}

image-20250608155405286

演示其中一个

2.详细解释

String str="AA,hello world";
//													对应抽象方法apply
Function<String,Integer> f=s->s.length();
Integer len = f.apply(str);     //f.apply(str) 相当与s.length()
System.out.println(len);

这表示:

  • Function<T, R> 是 Java 提供的一个函数式接口,表示:接受一个参数 T,返回一个结果 R

  • 这里你定义的是 Function<String, Integer>,也就是:

    “接收一个 String,返回一个 Integer(字符串长度)”

  • s -> s.length() 是 Lambda 表达式,对应 Function 接口的抽象方法:

R apply(T t);

即:

@Override
public Integer apply(String s) {
    return s.length();
}

3.使用方法:

int len = f.apply(str);
System.out.println(len); // 输出: 14("AA,hello world" 的长度)

4.总结:

部分含义
Function<String, Integer>接收 String,返回 Integer
s -> s.length()实现了 apply 方法,返回字符串长度
f.apply(str)执行函数,等价于 str.length()

🔹 Lambda 的底层原理

Lambda 表达式在 Java 编译器中会被转换为 匿名类对象 或使用 invokedynamic 指令生成一个对应的函数式接口实例。

(x, y) -> x + y

相当于:

new MyMath() {
    public int operate(int x, int y) {
        return x + y;
    }
}

🔹 使用场景

  • 线程创建(Runnable)
  • 排序(Comparator)
  • Stream 流操作(map, filter, reduce)
  • GUI 事件处理(如 Swing)
  • 自定义回调

⚠️ 注意事项(重要)

  1. 只能用于函数式接口(一个抽象方法)

  2. Lambda 不能直接访问非 final 的外部变量(但实际上支持“事实上的 final”)

  3. 调试困难:Lambda 出错时堆栈信息不如匿名类详细

  4. 避免滥用 Lambda,导致可读性降低

其他注意

场景写法是否合法
明确指定参数类型(int a, int b) -> a + b
多行代码(a, b) -> { ...; return ...; }
省略参数类型(a, b) -> a * b
单个参数省略括号s -> s.toUpperCase()

明确指定参数类型时

//对应接口
@FunctionalInterface
interface MyMath {
    int operate(int a, int b);
}
// 指定参数类型 int
MyMath add = (int a, int b) -> a + b;
System.out.println(add.operate(5, 3)); // 输出 8

代码多于一行,必须用花括号 {}return

MyMath max = (a, b) -> {
    System.out.println("比较两个数大小");
    return a > b ? a : b;
};
System.out.println(max.operate(5, 8)); // 输出 8

如果方法体有多行,必须加花括号,而且 需要手动写 return

根据上下文推断参数类型(省略类型)

MyMath sub = (a, b) -> a - b;
System.out.println(sub.operate(10, 4)); // 输出 6

这里 (a, b) 没有写类型,因为编译器已经知道 MyMath.operate(int, int) 要的是两个 int

参数只有一个,可以省略小括号 ()

Consumer<String> printer = s -> System.out.println(s.toUpperCase());
printer.accept("hello"); // 输出:HELLO
  • 如果参数是两个或没有,就不能省略括号

(a, b)没有写类型,因为编译器已经知道MyMath.operate(int, int)要的是两个int`。

参数只有一个,可以省略小括号 ()

Consumer<String> printer = s -> System.out.println(s.toUpperCase());
printer.accept("hello"); // 输出:HELLO
  • 如果参数是两个或没有,就不能省略括号
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

代码探秘者

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

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

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

打赏作者

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

抵扣说明:

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

余额充值