搜索
首页Javajava教程Java8中Lambda和Stream的详解(附代码)

Java8中Lambda和Stream的详解(附代码)

Oct 16, 2018 pm 02:42 PM
java8lambdastream

本篇文章给大家带来的内容是关于Java8中Lambda和Stream的详解(附代码),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。

1. 前言

本文主要介绍Java8的2大主要新特性lambda表达式和Stream API,2者提供了更高层次的抽象,简化开发,提高生产效率。

2. Lambda表达式

2.1 初识Lambda表达式

创建一个线程,使用了一个Runnable匿名内部类

Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("Hello Aron.");
            }
        });

看着问题不大,实际上弊端挺明显:模板语法太多,真正有业务意义的的语句只有System.out.println("Hello Aron."),因为如此,也严重干扰了我们阅读代码。

引入lambda表达式后,则可以这么写

Thread thread = new Thread(() -> System.out.println("Hello Aron."));

简洁了太多,有木有?

2.2 更多Lambda表达式

 Runnable runnable = () -> System.out.println("Hello World.");
 Consumer<T> tConsumer = bean -> System.out.println("Hello World.");
 Runnable runnable1 = () -> {
         System.out.println("Hello World.");
         System.out.println("Hello World.");
     };

语法分为3段式:参数 、-> 以及语句,即(...)-> { ...}

2.3 函数接口

Java是强类型语言,方法参数都有固定的类型。那么问题了,Lambda表达式,如果当做是一堆代码片段,也会表达一种明确的意图,这个意图,姑且可以理解为函数接口。

在编程过程中,总会遇到很多函数接口,以下是JDK中一些比较最重要的函数接口

接口参数返回类型示例

接口 参数 返回类型 示例
Predicate T boolean 值等于“Hello”吗?
Consumer T void 输出一个值
Function T R 获取对象的一个属性
Supplier None T 工厂方法
UnaryOperator T T 逻辑非(!)
BinaryOperator (T, T) T 求2个数的和(+)

2.4 类型推断

先看一段熟悉的集合代码

ArrayList<Java8Test> list = new ArrayList<>();

在ArrayList中申明了存储的元素的类型,于是在ArrayList<>()这里的类型可以缺省,编译器可以根据左侧(即上文)推断出来。

同理,在lambda表达式也是一样的。

BinaryOperator<Long> addLongs = (x, y) -> x + y;

在上面的表达 式中,我们注意到 (x, y)这里是没有申明方法的参数类型的,却能执行数学运算 +

这里根据函数接口指定的泛型类为Long,即可推断方法的参数为Long,然后执行x + y

2.5 Lambda小结

Lambda表达式是一个匿名方法,简化了匿名内部类的写法,把模板语法屏蔽,突出业务语句,传达的更像一种行为。

Lambda表达式是有类型的,JDK内置了众多函数接口

Lambda的3段式结构:(...)-> { ...}

3. Stream 流

3.1 简介

流(Stream)是Java8的新特性,是一种使程序员得以站在更高的抽象层次上对集合进行操作。在思路上,类似于SQL的存储过程,有几个步骤:

  1. 先定义一些操作的集合,注意:这里只定义,不真正执行

  2. 触发执行,获取结果

  3. 对结果进一步处理,筛选、打印、使用

其中,第1步的定义操作叫惰性求值,给你套路(返回Stream),但是不会执行返回结果。

第2步的触发操作叫及早求值,这个人说干就干,立马要结果(返回结果数据)。

第3步的筛选类似SQL的where子句,对结果进一步的筛选。

3.2 Stream API

Stream 类位于java.util.stream包,是Java8核心的类之一,拥有众多方法,下面罗列了一些比较重要的方法进行讲解。更多的是抛砖引玉,任何教程都比不上自己的悟性来得爽快,先找点感觉,先掌握基本用法尝试使用起来,慢慢自然就会了。

3.2.1 Stream.of(T… t)

要使用Stream,那就必须得先创建一个String类型的Stream

Stream<String> StrStream = Stream.of("a", "b");

3.2.2 Stream.collect(Collector collector)

使用收集器CollectorStrStream转化为熟悉的集合Collection

 List<String> collect = StrStream.collect(Collectors.toList());

3.2.2 Stream.map(Function mapper)

所谓map,从字面理解就是映射。这里指的是对象关系的映射,

比如从对象集合映射到属性结合:

List<String> names = Stream.of(new Student("zhangSan"), new Student("liSi"))
                        .map(student -> student.getName())
                        .collect(toList());

从小写字母映射到大写字母:

List<String> collected = Stream.of("a", "b", "hello")
                        .map(string -> string.toUpperCase())
                        .collect(toList());

将 字符串流 根据空格分割成 字符串数组流

Stream<String> stringStream = Stream.of("Hello Aron.");
Stream<String[]> stringArrayStream = stringStream.map(word -> word.split(" "));

3.2.3 Stream.filter(Predicate predicate)

filter顾名思义,过滤筛选。这里的参数函数接口是一个条件,筛选出满足条件的元素

// 筛选年龄大于19的学生
List<Student> stu = Stream.of(new Student("zhangSan", 19), new Student("liSi"), 20)
                        .filter(student -> student.getAge() > 19)
                        .collect(toList());

3.2.4 Stream.flatMap(Function> mapper)

flatMap扁平化映射,即将数据元素为数组的Stream转化为单个元素

Stream<String> stringStream = Stream.of("Hello Aron.");
// 返回值为数组
Stream<String[]> stringArrayStream = stringStream.map(word -> word.split(" "));
// flatMap扁平化映射后,元素都合并了
Stream<String> flatResult = stringArrayStream.flatMap(arr -> Arrays.stream(arr))

3.2.5 Stream.max(Comparator comparator)

max即最大,类似SQL中的函数max(),从数据中根据一定的条件筛选出最值

// 筛选年龄最大/小的学生
Stream<Student> studentStream = Stream.of(new Student("zhangSam", 19), new Student("liSi", 20));
Optional<Student> max = studentStream.max(Comparator.comparing(student -> student.getAge()));
// Optional<Student> max = studentStream.min(Comparator.comparing(student -> student.getAge()));
// 年龄最大/小的学生
Student student = max.get();

3.2.7 Sream.reduce(T identity, BinaryOperator binaryOperator)

reduce操作实现从一组值中生成一个值,上面的maxmin实际上都是reduce操作。

参数Identity 表示初始值,

参数binaryOperator是一个函数接口,表示二元操作,可用于数学运算

// 使用reduce() 求和 (不推荐生产环境使用)
int count = Stream.of(1, 2, 3).reduce(0, (acc, element) -> acc + element);

上面代码,展开reduce() 操作

BinaryOperator<Integer> accumulator = (acc, element) -> acc + element;
int count = accumulator.apply( accumulator.apply(accumulator.apply(0, 1),2), 3);

3.2.8 综合操作

// 查找所有姓张的同学并按字典顺序排序,存储到list
List<Student> newList = studentList.Stream()
            .filter(student -> student.getName().startsWith("张"))
            .sorted(Comparator.comparing(student -> student.getName())
            .collect(toList());

以上是Java8中Lambda和Stream的详解(附代码)的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文转载于:segmentfault思否。如有侵权,请联系admin@php.cn删除
JVM中的类加载程序子系统如何促进平台独立性?JVM中的类加载程序子系统如何促进平台独立性?Apr 23, 2025 am 12:14 AM

类加载器通过统一的类文件格式、动态加载、双亲委派模型和平台无关的字节码,确保Java程序在不同平台上的一致性和兼容性,实现平台独立性。

Java编译器会产生特定于平台的代码吗?解释。Java编译器会产生特定于平台的代码吗?解释。Apr 23, 2025 am 12:09 AM

Java编译器生成的代码是平台无关的,但最终执行的代码是平台特定的。1.Java源代码编译成平台无关的字节码。2.JVM将字节码转换为特定平台的机器码,确保跨平台运行但性能可能不同。

JVM如何处理不同操作系统的多线程?JVM如何处理不同操作系统的多线程?Apr 23, 2025 am 12:07 AM

多线程在现代编程中重要,因为它能提高程序的响应性和资源利用率,并处理复杂的并发任务。JVM通过线程映射、调度机制和同步锁机制,在不同操作系统上确保多线程的一致性和高效性。

在Java的背景下,'平台独立性”意味着什么?在Java的背景下,'平台独立性”意味着什么?Apr 23, 2025 am 12:05 AM

Java的平台独立性是指编写的代码可以在任何安装了JVM的平台上运行,无需修改。1)Java源代码编译成字节码,2)字节码由JVM解释执行,3)JVM提供内存管理和垃圾回收功能,确保程序在不同操作系统上运行。

Java应用程序仍然可以遇到平台特定的错误或问题吗?Java应用程序仍然可以遇到平台特定的错误或问题吗?Apr 23, 2025 am 12:03 AM

Javaapplicationscanindeedencounterplatform-specificissuesdespitetheJVM'sabstraction.Reasonsinclude:1)Nativecodeandlibraries,2)Operatingsystemdifferences,3)JVMimplementationvariations,and4)Hardwaredependencies.Tomitigatethese,developersshould:1)Conduc

云计算如何影响Java平台独立性的重要性?云计算如何影响Java平台独立性的重要性?Apr 22, 2025 pm 07:05 PM

云计算显着提升了Java的平台独立性。 1)Java代码编译为字节码,由JVM在不同操作系统上执行,确保跨平台运行。 2)使用Docker和Kubernetes部署Java应用,提高可移植性和可扩展性。

Java的平台独立性在广泛采用中扮演着什么角色?Java的平台独立性在广泛采用中扮演着什么角色?Apr 22, 2025 pm 06:53 PM

Java'splatformindependenceallowsdeveloperstowritecodeonceandrunitonanydeviceorOSwithaJVM.Thisisachievedthroughcompilingtobytecode,whichtheJVMinterpretsorcompilesatruntime.ThisfeaturehassignificantlyboostedJava'sadoptionduetocross-platformdeployment,s

容器化技术(例如Docker)如何影响Java平台独立性的重要性?容器化技术(例如Docker)如何影响Java平台独立性的重要性?Apr 22, 2025 pm 06:49 PM

容器化技术如Docker增强而非替代Java的平台独立性。1)确保跨环境的一致性,2)管理依赖性,包括特定JVM版本,3)简化部署过程,使Java应用更具适应性和易管理性。

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

功能强大的PHP集成开发环境

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

将Eclipse与SAP NetWeaver应用服务器集成。

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一个PHP/MySQL的Web应用程序,非常容易受到攻击。它的主要目标是成为安全专业人员在合法环境中测试自己的技能和工具的辅助工具,帮助Web开发人员更好地理解保护Web应用程序的过程,并帮助教师/学生在课堂环境中教授/学习Web应用程序安全。DVWA的目标是通过简单直接的界面练习一些最常见的Web漏洞,难度各不相同。请注意,该软件中

VSCode Windows 64位 下载

VSCode Windows 64位 下载

微软推出的免费、功能强大的一款IDE编辑器

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)