Java 8系列之Lambda实践步骤(二)

简介: Java 8系列之Lambda实践步骤(二)

1关于实践


这里依旧我们通过学生筛选的例子,看看在实践中如何通过Lambda表达式使得代码更加灵活、简洁。现在我们需要从全体学生中,将英语成绩在95分以上的学生筛选出来。筛选代码如下:


image.png

现在的代码的确满足了我们的需求,但如果我们需要将筛选分数改成80分,并且95分的筛选方法以后还有可能需要用时该怎么办?如果在实际开发中,你可能也不会想使用策略模式(尽管还是很啰嗦),更直接的是直接写出来studentFilterByEnglish95()和studentFilterByEnglish80()两个函数来满足需求了。那现在我需要过滤75分的学生,需要过滤数学成绩,需要过滤科学成绩呢?是否会有一堆啰里啰嗦的过滤函数被写出来,看过上一节的同学一定明白,此时最好的处理思路是传递学生的判断代码,即行为参数化,重用过滤执行机制。


Step1 : 行为参数化


传递行为正是Lambda表达式的独门秘诀,我们希望结合Lambda表达式,新的学生过滤函数使用方式应该如下:


image.png

Step2 :函数式接口声明


在上一篇文章中我们说过,Lambda的使用环境上下文必须是函数式接口,很显然学生判断过滤代码只有if判断条件需要根据条件更改,所以我们现在需要一个能与 Student -> boolean匹配的函数式接口的声明,并将该接口作为studentFilter的参数,便可以实现行为的传递了,代码如下:


image.png


现在我们就可以将StudentFilter这一函数式接口作为学生过滤函数的参数,传递给它了:


image.png
Step3 :行为执行


结合StudentFilter接口,改用StudentFilter.test()用于学生的判断:


image.png


Step4 : 传递Lambda


此时,我们便可以使用studentFilter方法来传递Lambda表达式了,正如Step1中我们所期望的使用方式那样使用,只需要注意Lambda的函数签名必须与函数式接口声明的抽象方法对应。


2关于Lambda表达式的类型推断


在Java 7中,已经引入了 菱形运算符(<>),Java可以利用泛型从上下文中推断出合适的类型参数的特性。利用该特性,Java编译器同样可以在Lambda表达式中,结合函数式接口的声明,便可以推断出参数列表的参数类型,从而可以写出更加简洁的Lambda表达式,如下:

image.png


可以看到Java对于Lambda表达式支持类型推断,这些年Java的确从C#的语法特性中汲取了很多好用的特性。


3

3Lambda的变量访问


在我们目前遇到的所有示例中的Lambda主体中,都只是用了参数列表中的变量,其实Lambda是支持引用外部变量的。但是对于外部变量的引用Lambda是有限制的,如果外部变量是实例变量或静态变量可以直接使用,但如果是局部变量,那局部变量必须是final或effectively final才可以引用,如下就无法通过java编译:


image.png


为什么会有这样的限制?这要通过JMM来考虑,在JMM中局部变量与实例变量在Java内存中存储在不同的内存区域,实例变量存储在Java堆中,而局部变量存储在线程栈中。如果Lambda直接访问局部变量,而且Lambda是在一个线程中使用,则使用Lambda的线程可能会在局部变量已经被释放的情况下再去访问。而在JMM模型中,线程对于实例变量的操作都是副本操作,然后通过副本与主存之间的刷新进行同步的。final域的添加,确保了该局部变量只会有一个不变值,从而在多线程情况下的线程安全性,为什么String类型是线程安全的?就是因为它只会存在一个值。

在使用Lambda表达式之前,一定要明白自己实现的是一个什么样的函数接口,本文我们根据函数式接口的语法规则定义了StudentFilter函数式接口,从而实现了可以在filter方法中传递行为。但是在开发中,我们常常会用到类似签名接口,例如 () -> boolean, (T) -> void, ( T ) -> ( T )等等,Java 8将一些通用形式的接口进行了定义,我们将在下节来讨论这些JDK中的函数式接口。







相关文章
|
3天前
|
存储 安全 Java
系统安全架构的深度解析与实践:Java代码实现
【11月更文挑战第1天】系统安全架构是保护信息系统免受各种威胁和攻击的关键。作为系统架构师,设计一套完善的系统安全架构不仅需要对各种安全威胁有深入理解,还需要熟练掌握各种安全技术和工具。
27 10
|
1天前
|
缓存 Java 调度
Java中的多线程编程:从基础到实践
【10月更文挑战第24天】 本文旨在为读者提供一个关于Java多线程编程的全面指南。我们将从多线程的基本概念开始,逐步深入到Java中实现多线程的方法,包括继承Thread类、实现Runnable接口以及使用Executor框架。此外,我们还将探讨多线程编程中的常见问题和最佳实践,帮助读者在实际项目中更好地应用多线程技术。
8 3
|
3天前
|
监控 安全 Java
Java多线程编程的艺术与实践
【10月更文挑战第22天】 在现代软件开发中,多线程编程是一项不可或缺的技能。本文将深入探讨Java多线程编程的核心概念、常见问题以及最佳实践,帮助开发者掌握这一强大的工具。我们将从基础概念入手,逐步深入到高级主题,包括线程的创建与管理、同步机制、线程池的使用等。通过实际案例分析,本文旨在提供一种系统化的学习方法,使读者能够在实际项目中灵活运用多线程技术。
|
1天前
|
缓存 安全 Java
Java中的多线程编程:从基础到实践
【10月更文挑战第24天】 本文将深入探讨Java中的多线程编程,包括其基本原理、实现方式以及常见问题。我们将从简单的线程创建开始,逐步深入了解线程的生命周期、同步机制、并发工具类等高级主题。通过实际案例和代码示例,帮助读者掌握多线程编程的核心概念和技术,提高程序的性能和可靠性。
6 2
|
2天前
|
Java
Java中的多线程编程:从基础到实践
本文深入探讨Java多线程编程,首先介绍多线程的基本概念和重要性,接着详细讲解如何在Java中创建和管理线程,最后通过实例演示多线程的实际应用。文章旨在帮助读者理解多线程的核心原理,掌握基本的多线程操作,并能够在实际项目中灵活运用多线程技术。
|
2天前
|
Java API 数据处理
探索Java中的Lambda表达式与Stream API
【10月更文挑战第22天】 在Java编程中,Lambda表达式和Stream API是两个强大的功能,它们极大地简化了代码的编写和提高了开发效率。本文将深入探讨这两个概念的基本用法、优势以及在实际项目中的应用案例,帮助读者更好地理解和运用这些现代Java特性。
|
6天前
|
Java API 调度
Java中的多线程编程:理解与实践
本文旨在为读者提供对Java多线程编程的深入理解,包括其基本概念、实现方式以及常见问题的解决方案。通过阅读本文,读者将能够掌握Java多线程编程的核心知识,提高自己在并发编程方面的技能。
|
5天前
|
消息中间件 监控 算法
Java性能优化:策略与实践
【10月更文挑战第21】Java性能优化:策略与实践
|
6天前
|
Java 开发者
Java中的异常处理:理解与实践
【10月更文挑战第20天】在Java编程的世界中,异常处理是一个不可忽视的重要话题。它不仅关乎代码的健壮性,更是程序设计中体现开发者预见性和解决问题能力的关键所在。本文将通过深入浅出的方式,带领读者探索Java异常处理的核心概念、实践方法以及如何优雅地应对各种异常情况,让你的代码在面对意外时也能从容不迫。
7 1
|
5天前
|
Java API
[Java]Lambda表达式
本文主要介绍了Java中的Lambda表达式,包括其优化匿名内部类的方式、使用规范、内置函数式接口及方法引用等内容。文章详细解析了Lambda的基础语法、参数列表、方法体的简化规则,以及如何利用Lambda优化代码。此外,还探讨了Lambda的作用域和引用规则,强调了对局部变量、成员变量和常量的访问限制,旨在帮助读者全面理解和掌握Lambda表达式的应用。
[Java]Lambda表达式