Java8中Lambda和Stream的详解(附代码)
本篇文章给大家带来的内容是关于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
同理,在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步的定义操作叫惰性求值,给你套路(返回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 super T, A, R> collector)
使用收集器Collector
将StrStream
转化为熟悉的集合Collection
List<String> collect = StrStream.collect(Collectors.toList());
3.2.2 Stream.map(Function super T, ? extends R> 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 super T> 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 super T, ? extends Stream extends R>> 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 super T> 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
操作实现从一组值中生成一个值,上面的max
、min
实际上都是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());
Atas ialah kandungan terperinci Java8中Lambda和Stream的详解(附代码). Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

AI Hentai Generator
Menjana ai hentai secara percuma.

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas



Dalam C++, terdapat dua cara untuk mengendalikan pengecualian menggunakan ungkapan Lambda: tangkap pengecualian menggunakan blok cuba-tangkap dan kendalikan atau buang semula pengecualian dalam blok tangkapan. Menggunakan fungsi pembalut jenis std::function, kaedah try_emplacenya boleh menangkap pengecualian dalam ungkapan Lambda.

Java8 mengira tarikh setahun yang lalu atau setahun kemudian menggunakan kaedah tolak() untuk mengira tarikh setahun yang lalu packagecom.shxt.demo02;importjava.time.LocalDate;importjava.time.temporal.ChronoUnit;publicclassDemo09{publicstaticvoidmain(String[ ]args ){LocalDatetoday=LocalDate.now();LocalDatepreviousYear=today.minus(1,ChronoUni

Dalam C++, penutupan ialah ungkapan lambda yang boleh mengakses pembolehubah luaran. Untuk membuat penutupan, tangkap pembolehubah luar dalam ungkapan lambda. Penutupan memberikan kelebihan seperti kebolehgunaan semula, penyembunyian maklumat dan penilaian malas. Ia berguna dalam situasi dunia sebenar seperti pengendali acara, di mana penutupan masih boleh mengakses pembolehubah luar walaupun ia dimusnahkan.

Kelebihan ungkapan lambda dalam pengaturcaraan berbilang benang C++ termasuk kesederhanaan, fleksibiliti, kemudahan lulus parameter dan selari. Kes praktikal: Gunakan ungkapan lambda untuk mencipta berbilang benang dan mencetak ID benang dalam urutan yang berbeza, menunjukkan kesederhanaan dan kemudahan penggunaan kaedah ini.

Ungkapan C++ Lambda menyokong penutupan, yang menyimpan pembolehubah skop fungsi dan menjadikannya boleh diakses oleh fungsi. Sintaks ialah [capture-list](parameters)->return-type{function-body}. capture-list mentakrifkan pembolehubah untuk ditangkap Anda boleh menggunakan [=] untuk menangkap semua pembolehubah tempatan mengikut nilai, [&] untuk menangkap semua pembolehubah tempatan melalui rujukan, atau [variable1, variable2,...] untuk menangkap pembolehubah tertentu. Ungkapan Lambda hanya boleh mengakses pembolehubah yang ditangkap tetapi tidak boleh mengubah suai nilai asal.

Operasi strim ialah kemuncak Java8! Walaupun java.util.stream sangat berkuasa, masih terdapat banyak pembangun yang jarang menggunakannya dalam kerja sebenar kerana aliran tidak boleh digunakan dalam DEBUG Apabila ia adalah satu baris kod, apabila sampai ke langkah seterusnya, banyak operasi sebenarnya diluluskan sekaligus, jadi sukar untuk kita menilai baris mana yang menjadi masalah. Pemalam: JavaStreamDebugger Jika versi IDEA yang anda gunakan agak baharu, pemalam ini sudah disertakan dan tidak perlu dipasang. Jika ia belum dipasang, pasangkannya secara manual dan kemudian teruskan di bawah.

Terdapat tiga cara untuk menangkap ungkapan lambda pembolehubah luaran dalam C++: Tangkap mengikut nilai: Buat salinan pembolehubah. Tangkap melalui rujukan: Dapatkan rujukan berubah-ubah. Tangkap mengikut nilai dan rujukan serentak: Membenarkan tangkapan berbilang pembolehubah, sama ada mengikut nilai atau rujukan.

Strim java8 mengambil maxpublicstaticvoidmain(String[]args){Listlist=Arrays.asList(1,2,3,4,5,6);Integermax=list.stream().max((a,b)->{if ( a>b){return1;}elsereturn-1;}).get();System.out.println(maks);}Nota: Saiz ditentukan di sini melalui nombor positif dan negatif serta 0 nilai. Daripada menulisnya terus jika(a>b){returna;}elseretur
