Javajdk8新特性中lambda 详解

Java 8 开始支持 lambda 表达式,是 Java 编程语言中对函数式编程的一种支持。Lambda 表达式也被称为闭包或匿名函数,可以让开发者轻松地写出简单而强大的代码,并带来显著的性能优势和更好的可读性。本文将详细介绍 Java Lambda 的概念、语法、使用方法以及适用场景等相关内容,帮助您充分了解并掌握该技术。

一、Lambda表达式基础知识

什么是 Lambda 表达式? Lambda 表达式实际上是一种匿名方法,它没有名称、修饰符和返回类型声明。Lambda 表达式可以传递到方法中,作为参数或返回值,或者存储在变量中。语法格式如下:

(args) -> { expression; }

或

(args) -> return statement;

为什么需要 Lambda 表达式?
Lambda 表达式可以极大地简化代码,并且可以提高代码的性能。在使用 Lambda 表达式时,可以不需要使用功能接口(Functional Interface)的实现类,从而省去了重复代码和编程工作量。同时,Lambda 表达式所带来的语法简化和代码优化也可以使代码更有可读性。

什么是 Functional Interface?
Functional Interface(函数接口)是 Java8 中定义的一种特殊概念,它描述的是一个只包含单个抽象方法的接口。Lambda 表达式被设计成只能与函数接口相关联,这意味着如果想使用 Lambda 表达式,必须有一个与之对应的函数式接口。Java 8 为我们提供了很多的预置接口,比如 Runnable 接口、Predicate 接口、Function 接口等。

二、Lambda 表达式语法

无参Lambda表达式 当Lambda表达式中没有任何参数时,小括号内留空即可,代码示例如下:
() -> System.out.println(“Hello, world!”);

有参Lambda表达式 当Lambda表达式中有一个以上的参数,多个参数之间用逗号隔开,仍需使用小括号将参数包围,代码示例如下:

(String s) -> System.out.println(s);

多行Lambda表达式 当Lambda表达式体内涉及多条语句时,使用花括号 {} 括起来,并使用分号 ; 分隔语句即可,代码示例如下:

(int x, int y) -> {
System.out.println("Input values: " + x + ", " + y);
return x + y;
}

带返回值的 Lambda 表达式 在 Lambda 表达式中使用 return 关键字来返回某个值,比如:

(String s) -> {
return "Hello, " + s;
}

当 Lambda 表达式只有一行语句时,可以省略花括号和 return。其中,该行语句既是表达式的返回值。例如:

(String s) -> "Hello, " + s;

方法引用 Lambda 表达式可转化为方法引用(Method Reference),简化了 Lambda 表达式的书写过程。举例如下:

System.out::println;

其中,System.out 对应实例对象,println 对应方法名。

三、Lambda 表达式使用方法

在 Java 集合中使用 Lambda 表达式
Java 集合提供了很多便于使用 Lambda 表达式的函数接口,比如 forEach()、map()、reduce()、filter() 等。通过使用 Lambda 表达式,可以大大简化这些接口的实现逻辑,从而更加方便地完成对集合的操作。

作为参数传递给函数或方法:
将 Lambda 表达式作为参数传递给函数或方法,能够大大减少样板代码并简化程序结构。举例,考虑一个排序程序,借助 Lambda 表达式可以让排序的逻辑更加清晰:

Arrays.sort(names, (String a, String b) -> {
return b.compareTo(a);
});

创建线程 在 Java 中,创建新线程需要实例化 Thread 类或可行性 Runnable 接口。Lambda 表达式可以使线程管理变得更加容易和便捷:

Thread t = new Thread(() -> {
System.out.println("New thread created.");
});
t.run();

四、Lambda表达式适用场景

Lambda 表达式适用于各种需要传递函数作为参数的场景,主要包括以下几个方面:

1.集合操作:Lambda 表达式可以很方便地用于对集合进行过滤、排序、转换等操作。例如,我们可以使用 Lambda 表达式来实现比较器对象,从而进行集合排序。

2.观察者模式:在需要实现简单的观察者模式时,可以使用 Lambda 表达式来代替传统的匿名内部类。这样可以使得代码更加简洁明了,并且提高了可维护性和可读性。

3.线程处理:Lambda 表达式可以通过 Java 8 中新增的函数式接口 Runnable 和 Callable 来创建新线程或者提交任务到线程池。这种方式更加简单灵活,也方便线程处理的异常处理。

4.模板方法设计模式:Lambda 表达式可以作为参数传递给通用代码中的抽象方法,从而使得代码更加灵活可扩展。

5.GUI应用程序:在使用基于事件机制的图形用户界面 GUI 开发时,可以使用 Lambda 表达式处理事件响应,避免编写复杂的匿名内部类。

总结来说,Lambda 表达式适用于需要传递函数作为参数的各种场景中,并且可以大大提高代码的简洁性、可读性和可维护性。我们可以根据具体业务需求,灵活地运用 Lambda 表达式,同时注意在性能优化方面进行相应的设计和改进。

五、Lambda表达式示例

示例1:使用 Lambda 实现 Comparator 接口

首先定义一个 Person 类:

public class Person {
    private String name;
    private int age;
    
    // 构造函数
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // getter 和 setter 略...

}

使用 Lambda 表达式实现 Comparator 接口,按照年龄对 Person 列表进行排序:

List<Person> personList = new ArrayList<>();
personList.add(new Person("Amy", 18));
personList.add(new Person("Bob", 22));
personList.add(new Person("Chris", 20));

Collections.sort(personList, (p1, p2) -> p1.getAge() - p2.getAge());

for (Person person : personList) {
    System.out.println(person.getName() + ": " + person.getAge());
}

输出结果为:

Amy: 18
Chris: 20
Bob: 22

示例2:使用 Lambda 实现 Runnable 接口

实现 Runnable 接口是 Java 中创建线程的一种方式,在 Java 8 中可以通过 Lambda 表达式来实现这一接口。

Thread thread = new Thread(() -> {
    for (int i = 0; i < 10; i++) {
        System.out.println("Thread run " + i);
    }
});
thread.start();

输出结果为:

Thread run 0
Thread run 1
Thread run 2
Thread run 3
Thread run 4
Thread run 5
Thread run 6
Thread run 7
Thread run 8
Thread run 9

示例3:使用 Lambda 实现 forEach 方法

Iterable 接口中的 forEach 方法可以很方便地实现对集合或者数组中每个元素的遍历操作。在 Java 8 中,我们可以直接传入 Lambda 表达式来实现这一功能。

List<String> list = Arrays.asList("Java", "Python", "C++");
list.forEach(str -> System.out.println(str));

输出结果为:

Java
Python
C++

示例4:使用 Lambda 实现并行流处理

并行流是一个在 Java 8 中新增的特性,可以让我们方便地利用 CPU 的多核心来加速数据处理任务。在使用 Lambda 表达式时,只需要将 sequential() 方法替换成 parallel() 方法即可开启并行处理。

下面以求平均数为例,展示如何使用 Lambda 实现并行流处理:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

double average = numbers.parallelStream()
                        .mapToInt(i -> i)
                        .average()
                        .getAsDouble();

System.out.println(average);

输出结果为:

5.5

示例5:使用 Lambda 实现 Stream 的 filter 和 map 方法

Stream 类中的 filter 和 map 方法可以实现对流中元素的筛选和转换操作。在 Java 8 中,我们可以利用 Lambda 表达式来完成这一功能。

下面以将字符串全部变成大写为例,展示如何使用 Lambda 实现 filter 和 map 方法:

List<String> stringList = Arrays.asList("Java", "Python", "C++");

List<String> upperCaseList = stringList.stream()
                                    .filter(str -> str.length() > 3)
                                    .map(str -> str.toUpperCase())
                                    .collect(Collectors.toList());

System.out.println(upperCaseList);

输出结果为:

[JAVA, PYTHON]

六、Lambda表达式优缺点

优点:

1.更简洁的代码:Lambda 表达式能够代替传统的匿名内部类,可以大大减少代码行数,并且让代码更加清晰明了。

2.函数式风格:Lambda 表达式支持函数式风格编程,即将方法作为参数进行传递,从而实现更加灵活的编程方式。

3.可重用性:Lambda 表达式可以非常方便地在各种集合、数组等容器中使用,也可以在多个地方重用同一个 Lambda 表达式,提高代码的复用性。

4.并发能力:通过使用 Stream API 和并行流处理,Lambda 表达式可以帮助我们更加轻松地并行化处理计算任务,提高程序的运行效率。

缺点:

1.学习难度增加:Lambda 表达式需要理解更加抽象的函数式编程思想,初学者可能需要一定时间来掌握这项新特性。

2.语法繁琐:Lambda 表达式虽然可以减少代码行数,但有些场景下也需要繁琐的语法结构来实现。

3.性能问题:Lambda 表达式在确保代码简洁的同时,可能会对程序的性能造成一定的损失,例如遍历过程中进行过多的装箱和拆箱操作。

4.缺少可读性:Lambda 表达式虽然可以使得代码更加简洁,但在一些复杂的情况下,Lambda 表达式会让代码变得难以阅读和理解。

七、Lambda表达式的性能

Lambda 表达式的性能与传统的匿名内部类相比,可能会稍微降低一些性能。主要原因包括以下几点:

1.对象创建:在使用 Lambda 表达式时,需要创建一个函数式接口的实例对象,这个过程需要进行对象的创建和初始化,而在传统的匿名内部类中,由于不需要额外的函数式接口,所以不需要进行对象的创建和初始化。

2.捕获上下文:Lambda 表达式可以访问父类作用域的变量,这需要将这些变量捕获到 Lambda 表达式中,并在每次调用时传递给 Lambda 表达式,这个过程也会对性能造成一定影响。

3.代码生成:在编译时,Lambda 表达式会被转换为一个方法,并生成一个动态类的实例,在运行时通过反射的方式进行调用。而在传统的匿名内部类中,由于它们是单独的类,所以不存在这个问题。

虽然 Lambda 表达式相对于传统的匿名内部类会带来一定程度的性能损失,但这种损失往往只是微不足道的,在新版本的 Java 中也会进行优化,并尝试将性能优化至与传统的匿名内部类相当甚至更好。因此,我们无需过度担心 Lambda 表达式的性能问题,而应该侧重于在代码的可读性、可维护性和可重复使用性等方面进行考虑和优化。同时,在涉及到大量计算的场景时,可以采用其他方式,如并行处理等,来进一步优化 Lambda 表达式的性能。

八、结语

本文主要介绍了 Java 8 引入 Lambda 表达式的概念、语法和应用场景以及如何充分利用 Lambda 表达式来提高代码的效率和可读性。同时,我们也揭示了 Java 8 的新特性带来的性能提升。Lambda 表达式已经成为 Java 开发中不可或缺的技术特性之一。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

日霄科技

感谢各位大佬,您鼓励是我的动力

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

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

打赏作者

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

抵扣说明:

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

余额充值