Java 8 Stream 与集合的协同使用:流式操作,让你的代码更“流畅”!
开篇语
哈喽,各位小伙伴们,你们好呀,我是喵手。运营社区:C站/掘金/腾讯云/阿里云/华为云/51CTO;欢迎大家常来逛逛
今天我要给大家分享一些自己日常学习到的一些知识点,并以文字的形式跟大家一起交流,互相学习,一个人虽可以走的更快,但一群人可以走的更远。
我是一名后端开发爱好者,工作日常接触到最多的就是Java语言啦,所以我都尽量抽业余时间把自己所学到所会的,通过文章的形式进行输出,希望以这种方式帮助到更多的初学者或者想入门的小伙伴们,同时也能对自己的技术进行沉淀,加以复盘,查缺补漏。
小伙伴们在批阅的过程中,如果觉得文章不错,欢迎点赞、收藏、关注哦。三连即是对作者我写作道路上最好的鼓励与支持!
前言
你是不是也曾经在用
for
循环处理集合时,觉得代码冗长、重复,就好像每写一行代码都在给自己加压?
直到有一天,你听说了 Java 8 Stream,仿佛是一道光照亮了前方的黑暗!
Stream API,让集合操作变得更加优雅和高效,能用更少的代码实现更强大的功能!
但你可能也有疑问,Stream到底是怎么跟 集合搭配使用的?它们的“配合”是怎么产生魔力的?
今天就让我们一起探索,Java 8 Stream 与集合的协同使用,让代码更简洁、更流畅、更有魅力!
一、Stream 的基本概念:什么是流式操作?
1. 什么是 Stream?
Stream 是 Java 8 引入的一个强大的工具,它提供了一个声明式的方式来处理集合或其他数据源(如数组、IO流等)。
Stream 不是数据结构,它只是对数据的操作流水线(也可以理解为流),提供了一些优雅的方式来对数据进行过滤、映射、排序等操作。
关键特点:
- 无存储:Stream 不会存储数据,它的操作是惰性求值的(只有在实际消费时才执行)。
- 支持顺序和并行:你可以通过流的管道操作,轻松实现并行计算。
2. 流式操作的优势:
- 可读性强:代码简洁,流程清晰,容易理解。
- 提高效率:尤其是并行流,能有效利用多核 CPU,提高性能。
- 减少错误:通过链式调用,可以减少传统循环中的错误,比如忘记条件判断等。
二、如何使用 Stream 操作集合?
1. 使用 Stream 创建流
Stream
可以通过集合对象的 stream()
或 parallelStream()
方法轻松创建:
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
// 创建顺序流
Stream<Integer> sequentialStream = list.stream();
// 创建并行流
Stream<Integer> parallelStream = list.parallelStream();
2. 流式操作的常见方法
1. 过滤(filter)
过滤掉不符合条件的元素:
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
List<Integer> evenNumbers = numbers.stream()
.filter(n -> n % 2 == 0)
.collect(Collectors.toList());
System.out.println(evenNumbers); // [2, 4, 6, 8, 10]
2. 映射(map)
对流中的每个元素应用某个函数,生成新的流:
List<String> words = Arrays.asList("Java", "Stream", "API", "is", "fun");
List<String> upperCaseWords = words.stream()
.map(String::toUpperCase)
.collect(Collectors.toList());
System.out.println(upperCaseWords); // [JAVA, STREAM, API, IS, FUN]
3. 排序(sorted)
对流中的元素进行排序:
List<Integer> numbers = Arrays.asList(4, 1, 7, 3, 9, 2);
List<Integer> sortedNumbers = numbers.stream()
.sorted()
.collect(Collectors.toList());
System.out.println(sortedNumbers); // [1, 2, 3, 4, 7, 9]
4. 限制(limit)
限制流的长度:
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
List<Integer> limitedNumbers = numbers.stream()
.limit(5)
.collect(Collectors.toList());
System.out.println(limitedNumbers); // [1, 2, 3, 4, 5]
5. 求和(reduce)
将流中的元素合并为一个结果,例如求和:
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
int sum = numbers.stream()
.reduce(0, Integer::sum);
System.out.println(sum); // 15
三、Stream 与集合的协同使用:性能、易用性与灵活性
1. 性能对比:顺序流 vs 并行流
Stream 可以通过 parallel()
或 parallelStream()
方法启用并行操作。当你的集合数据量非常大时,并行流能显著提升性能。并行流会把任务分配给多个核心,利用多核 CPU 的优势。
示例:顺序流 vs 并行流
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
// 顺序流
long startTime = System.nanoTime();
long sumSequential = numbers.stream().mapToInt(Integer::intValue).sum();
long endTime = System.nanoTime();
System.out.println("顺序流求和耗时: " + (endTime - startTime) + "ns");
// 并行流
startTime = System.nanoTime();
long sumParallel = numbers.parallelStream().mapToInt(Integer::intValue).sum();
endTime = System.nanoTime();
System.out.println("并行流求和耗时: " + (endTime - startTime) + "ns");
注意:
并行流不是在所有情况下都比顺序流更快。对于小型集合或操作成本较低的任务,顺序流反而可能更高效,因为并行化本身也有一定的开销。
2. Stream 与集合的转换
Stream
和集合类之间的转换非常简单,你可以轻松地将一个 Stream
转换回集合,反之亦然:
- Stream 转 集合:
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> result = numbers.stream()
.filter(n -> n % 2 == 0)
.collect(Collectors.toList()); // 转换为List
- 集合转 Stream:
List<Integer> list = Arrays.asList(1, 2, 3, 4);
Stream<Integer> stream = list.stream();
3. 流的中间操作与终结操作
Stream 中的操作可以分为中间操作和终结操作:
- 中间操作:如
filter
、map
、sorted
等,返回新的 Stream,可以链式调用,惰性执行。 - 终结操作:如
collect
、forEach
、reduce
等,触发流的执行,返回一个结果。
链式操作示例:
List<String> words = Arrays.asList("Java", "Stream", "is", "awesome");
List<String> result = words.stream()
.filter(w -> w.length() > 2)
.map(String::toUpperCase)
.sorted()
.collect(Collectors.toList());
System.out.println(result); // [AWESOME, IS, JAVA, STREAM]
四、Stream 与集合的最佳实践:灵活搭配,事半功倍!
1. 结合 Collection API 进行高级操作
Stream 可以与 Java 集合的其他 API 进行无缝结合,特别是 Collectors
工具类,它提供了丰富的终结操作,帮助你更高效地将流转换为集合。
示例:分组操作(Group By)
List<String> words = Arrays.asList("apple", "banana", "cherry", "apple", "banana");
Map<String, Long> wordCount = words.stream()
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
System.out.println(wordCount); // {apple=2, banana=2, cherry=1}
2. Stream 与自定义对象的协同
Stream 不仅能操作原始数据类型,还能非常好地与自定义对象结合使用。例如,假设你有一个 Person
类,需要按年龄排序:
class Person {
String name;
int age;
Person(String name, int age) {
this.name = name;
this.age = age;
}
public int getAge() {
return age;
}
@Override
public String toString() {
return name + ": " + age;
}
}
List<Person> people = Arrays.asList(
new Person("Alice", 30),
new Person("Bob", 25),
new Person("Charlie", 35)
);
List<Person> sortedPeople = people.stream()
.sorted(Comparator.comparing(Person::getAge))
.collect(Collectors.toList());
System.out.println(sortedPeople); // [Bob: 25, Alice: 30, Charlie: 35]
五、总结:Stream 的魔力,发挥你的创造力
Java 8 的 Stream API 是对集合操作的革新,让我们可以以一种更加简洁、流畅的方式进行数据处理。它通过支持函数式编程的特性,使得代码更加清晰和可读。
- Stream 让你摆脱了复杂的循环,用简洁的语法完成更复杂的操作。
- Stream 与集合的协同使用,提升了开发效率,让代码既具可读性,又能提升性能。
- 在处理大规模数据时,并行流能充分利用多核 CPU 提高性能,但要谨慎使用,并非所有场景下并行流都更优。
流畅的代码,流畅的思维,流畅的开发体验!希望你能在编程的世界里,通过 Stream 使每一行代码都更加优雅!
… …
文末
好啦,以上就是我这期的全部内容,如果有任何疑问,欢迎下方留言哦,咱们下期见。
… …
学习不分先后,知识不分多少;事无巨细,当以虚心求教;三人行,必有我师焉!!!
wished for you successed !!!
⭐️若喜欢我,就请关注我叭。
⭐️若对您有用,就请点赞叭。
⭐️若有疑问,就请评论留言告诉我叭。
版权声明:本文由作者原创,转载请注明出处,谢谢支持!
- 随机文章
- 热门文章
- 热评文章
- 深入解析LoadRunner压力测试:原理、实践与优化loadrunner压力测试500并发
- 《从Prompt工程到AI思维:开发者新技能树全解析》
- 机器学习如何让运维成本更“抠门”?——数据驱动的降本增效指南
- Java Hibernate ORM系统
- 免费测你的性格和《三叉戟》中的谁最像
- 性格测试 测你的性格像《三十而已》中的谁
- 性格测试 测你身上自带什么气
- 在线心理测试 测试你在别人眼里多优秀
- Java MVC 博客系统