Java进阶-Java Stream API的使用
一、Java Stream API介绍
1. Java Stream API简述
Java Stream API 是Java 8中引入的一项功能,它允许程序员以声明式方式处理数据集合。通过Stream API,可以对数据执行复杂的查询操作,而不必编写冗余的代码。Stream 不是数据结构,它更像是一个高级版本的Iterator。单次使用,数据只能遍历一次,遍历过程中你可以对数据进行过滤、排序、聚合等操作。
2. Java Stream API支持的功能
功能 | 描述 |
---|---|
filter |
过滤流中的元素,根据条件只留下满足条件的元素 |
map |
将流中的每个元素映射成其他形式,结果是一个包含映射后结果的新流 |
sorted |
确保流中的元素在消费时的顺序按照自然顺序或自定义Comparator排序 |
collect |
将流转换为其他形式,如List、Set或Map,或者是自定义的收集器 |
forEach |
遍历流中的每个元素并执行给定的操作 |
reduce |
通过重复处理其元素来将流减少到单个汇总结果 |
anyMatch |
检查流中的元素是否有一个满足给定的条件 |
allMatch |
检查流中的元素是否全部满足给定条件 |
noneMatch |
检查流中的元素是否没有满足给定条件的 |
findFirst |
返回流中的第一个元素,如果流为空,则返回空的Optional |
limit |
截断流,使其最大长度不超过给定数量 |
skip |
跳过流中的前n个元素,返回包含余下元素的新流 |
3. 使用Java Stream API的优势
功能 | Java Stream API | 传统集合操作 |
---|---|---|
数据处理模式 | 声明式,支持函数式编程 | 命令式,代码较为复杂 |
内存效率 | 更高,因为它是在流上直接操作 | 低,需要复制到新的数据结构 |
并发处理 | 内建支持并发处理 | 手动处理并发 |
可读性 | 高,流操作可链式调用 | 低,循环和条件判断多 |
使用场景 | 数据集合操作,大数据处理 | 小数据量操作 |
二、常用的Java Stream API功能
下面是针对每个Java Stream API函数的示例代码:
1. filter
过滤流中的元素,根据条件只留下满足条件的元素。
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6);
List<Integer> evenNumbers = numbers.stream()
.filter(n -> n % 2 == 0)
.collect(Collectors.toList());
System.out.println(evenNumbers); // 输出 [2, 4, 6]
2. map
将流中的每个元素映射成其他形式,结果是一个包含映射后结果的新流。
List<String> words = Arrays.asList("hello", "world", "java", "stream");
List<Integer> wordLengths = words.stream()
.map(String::length)
.collect(Collectors.toList());
System.out.println(wordLengths); // 输出 [5, 5, 4, 6]
3. sorted
确保流中的元素在消费时的顺序按照自然顺序或自定义Comparator排序。
List<Integer> numbers = Arrays.asList(4, 3, 6, 1, 5, 2);
List<Integer> sortedNumbers = numbers.stream()
.sorted()
.collect(Collectors.toList());
System.out.println(sortedNumbers); // 输出 [1, 2, 3, 4, 5, 6]
4. collect
将流转换为其他形式,如List、Set或Map,或者是自定义的收集器。
List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");
Set<String> nameSet = names.stream()
.collect(Collectors.toSet());
System.out.println(nameSet); // 输出 [Alice, Bob, Charlie, David]
5. forEach
遍历流中的每个元素并执行给定的操作。
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
names.stream()
.forEach(System.out::println); // 依次输出 1、2、3、4、5
6. reduce
通过重复处理其元素来将流减少到单个汇总结果。
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
int sum = numbers.stream()
.reduce(0, Integer::sum);
System.out.println("Sum: " + sum); // 输出 Sum: 15
7. anyMatch
检查流中的元素是否有一个满足给定的条件。
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
boolean hasEven = numbers.stream()
.anyMatch(n -> n % 2 == 0);
System.out.println("Has even numbers: " + hasEven); // 输出 Has even numbers: true
8. allMatch
检查流中的元素是否全部满足给定条件。
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
boolean allEven = numbers.stream()
.allMatch(n -> n % 2 == 0);
System.out.println("All are even: " + allEven); // 输出 All are even: false
9. noneMatch
检查流中的元素是否没有满足给定条件的。
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
boolean noneMultipleOfTen = numbers.stream()
.noneMatch(n -> n % 10 == 0);
System.out.println("None are multiples of ten: " + noneMultipleOfTen); // 输出 None are multiples of ten: true
10. findFirst
返回流中的第一个元素,如果流为空,则返回空的Optional。
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
Optional<Integer> first = numbers.stream()
.findFirst();
System.out.println("First number: " + first.orElse(-1)); // 输出 First number: 1
11. limit
截断流,使其最大长度不超过给定数量。
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> limited = numbers.stream()
.limit(3)
.collect(Collectors.toList());
System.out.println(limited); // 输出 [1, 2, 3]
12. skip
跳过流中的前n个元素,返回包含余下元素的新流。
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> skipped = numbers.stream()
.skip(3)
.collect(Collectors.toList());
System.out.println(skipped); // 输出 [4, 5]
这些示例展示了Java Stream API的多样化和强大功能,使得处理集合数据更加灵活和
三、Java Stream API和类似包比较的优势
Java Stream API 作为Java 8及以后版本的核心特性,对集合和数据流的处理提供了强大的支持。除了Java自带的Stream API,还有一些其他的库或框架也提供了类似的功能,用于处理集合或者数据流。
1. 常见的Java集合处理库
- Java Stream API - 内置于Java 8及以上版本,提供了一种高级的处理集合的方法,支持函数式编程。
- Apache Commons Collections - 提供了丰富的集合操作工具,但主要是针对Java集合框架之前的版本设计。
- Google Guava - 提供了许多核心Java库没有的集合类型和工具,包括对集合的操作和新的集合类型。
- Vavr(之前称为Javaslang)- 提供了不可变的集合类型和其他函数式编程的工具,以提高代码的健壮性。
- Eclipse Collections(之前称为GS Collections)- 提供了一套丰富的集合库,以及各种性能优化和内存优化的集合类型。
2. 集合处理库之间的比较
特性 / 库 | Java Stream API | Apache Commons Collections | Google Guava | Vavr | Eclipse Collections |
---|---|---|---|---|---|
主要优势 | 内置支持,无需额外依赖 | 丰富的集合操作工具 | 强大的集合工具和新集合类型 | 不可变集合和函数式编程支持 | 高性能、丰富的集合类型 |
集合不可变性 | 不提供 | 不提供 | 提供部分不可变集合 | 所有集合默认不可变 | 提供不可变和可变集合 |
函数式编程 | 支持 | 有限支持 | 有限支持 | 完全支持 | 有限支持 |
并发支持 | 并发流处理 | 不专门针对并发优化 | 提供并发集合 | 不提供 | 提供优化的并发集合 |
类型安全和检查 | 类型安全 | 类型安全 | 类型安全 | 类型安全 | 类型安全 |
学习曲线 | 中等 | 低 | 中等 | 高 | 中等 |
与Java版本兼容性 | Java 8+ | Java 1.2+ | Java 1.6+ | Java 8+ | Java 5+ |
扩展集合类型 | 无 | 提供额外集合操作 | 提供新的集合类型 | 提供函数式集合类型 | 提供丰富的集合类型 |
每个库都有其独特的优点和用途。Java Stream API是Java开发中的标准选项,无需额外依赖且与现代Java应用高度兼容。对于需要在老版本Java上工作的开发者,Apache Commons Collections提供了后向兼容。Google Guava和Eclipse Collections提供了高性能的集合操作,而Vavr则为喜欢函数式编程的开发者提供了很好的支持。选择哪个库取决于具体的项目需求、团队的熟悉度以及对库特性的需求。
四、Java Stream API使用总结
Java Stream API 是一个功能强大的工具,适用于处理集合和数据流。它提供了一种简洁而高效的方法来操作数据,尤其是在处理大量数据时。这个API优化了数据处理逻辑,使开发者能够以更少的代码执行复杂的数据转换和聚合操作。利用Java Stream API,可以轻松实现数据过滤、排序、转换及汇总,极大地提升了代码的可读性和可维护性。同时,Stream API 的函数式编程特性有助于减少错误和侧效应,使得并发程序的编写更为安全。通过使用Java Stream API,开发者可以写出更简洁、更高效、更易于维护的代码,同时享受到函数式编程带来的好处。
- 点赞
- 收藏
- 关注作者
评论(0)