网站首页 > java教程 正文
Java 8 Stream API 详解
一、概述
在 Java 8 中,Stream API 是一个重要的新特性。它为处理集合(如 List、Set 等)中的元素提供了一种高效且富有表现力的方式。Stream API 允许开发者以声明式的方式处理数据,将数据处理逻辑与数据存储结构分离,使得代码更加简洁、易读和可维护。同时,Stream API 支持并行处理,能够充分利用多核处理器的性能。
二、Stream 的概念
2.1 什么是 Stream
Stream 不是一种数据结构,它是对数据源(如集合、数组等)的元素进行一系列操作的抽象。可以将 Stream 看作是一个高级迭代器,它允许我们以一种更灵活的方式遍历和处理集合中的元素。
2.2 Stream 的特点
- 不存储数据:Stream 只是对数据源中的元素进行操作,不存储元素本身。
- 函数式编程:使用 Lambda 表达式来定义操作,代码简洁且易于理解。
- 延迟执行:Stream 的中间操作不会立即执行,只有在调用终止操作时才会触发执行。
- 可并行操作:Stream 可以并行处理元素,提高处理效率。
三、创建 Stream
3.1 从集合创建 Stream
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
public class StreamCreationFromCollection {
public static void main(String[] args) {
List<String> fruits = new ArrayList<>();
fruits.add("apple");
fruits.add("banana");
fruits.add("cherry");
// 创建顺序流
Stream<String> sequentialStream = fruits.stream();
// 创建并行流
Stream<String> parallelStream = fruits.parallelStream();
}
}
3.2 从数组创建 Stream
import java.util.stream.Stream;
public class StreamCreationFromArray {
public static void main(String[] args) {
String[] colors = {"red", "green", "blue"};
Stream<String> colorStream = Stream.of(colors);
}
}
3.3 使用 Stream.generate() 和 Stream.iterate() 创建无限流
import java.util.stream.Stream;
public class InfiniteStreamCreation {
public static void main(String[] args) {
// 使用 generate 创建无限流,生成随机数
Stream<Double> randomStream = Stream.generate(Math::random);
randomStream.limit(5).forEach(System.out::println);
// 使用 iterate 创建无限流,从 0 开始,每次递增 2
Stream<Integer> evenStream = Stream.iterate(0, n -> n + 2);
evenStream.limit(5).forEach(System.out::println);
}
}
四、Stream 的操作
4.1 中间操作
中间操作会返回一个新的 Stream,并且不会立即执行,常见的中间操作有:
4.1.1 过滤(filter)
import java.util.Arrays;
import java.util.List;
public class FilterOperation {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6);
numbers.stream()
.filter(n -> n % 2 == 0)
.forEach(System.out::println);
}
}
4.1.2 映射(map)
import java.util.Arrays;
import java.util.List;
public class MapOperation {
public static void main(String[] args) {
List<String> words = Arrays.asList("hello", "world");
words.stream()
.map(String::toUpperCase)
.forEach(System.out::println);
}
}
4.1.3 扁平化映射(flatMap)
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
public class FlatMapOperation {
public static void main(String[] args) {
List<List<Integer>> nestedList = Arrays.asList(
Arrays.asList(1, 2),
Arrays.asList(3, 4),
Arrays.asList(5, 6)
);
Stream<Integer> flatStream = nestedList.stream()
.flatMap(List::stream);
flatStream.forEach(System.out::println);
}
}
4.1.4 排序(sorted)
import java.util.Arrays;
import java.util.List;
public class SortedOperation {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(3, 1, 4, 1, 5, 9);
numbers.stream()
.sorted()
.forEach(System.out::println);
// 自定义排序
numbers.stream()
.sorted((a, b) -> b - a)
.forEach(System.out::println);
}
}
4.1.5 去重(distinct)
import java.util.Arrays;
import java.util.List;
public class DistinctOperation {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 2, 3, 3, 3);
numbers.stream()
.distinct()
.forEach(System.out::println);
}
}
4.1.6 截断(limit)和跳过(skip)
import java.util.Arrays;
import java.util.List;
public class LimitAndSkipOperation {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6);
// 取前 3 个元素
numbers.stream()
.limit(3)
.forEach(System.out::println);
// 跳过前 2 个元素
numbers.stream()
.skip(2)
.forEach(System.out::println);
}
}
4.2 终止操作
终止操作会触发中间操作的执行,并产生一个最终结果,常见的终止操作有:
4.2.1 遍历(forEach)
import java.util.Arrays;
import java.util.List;
public class ForEachOperation {
public static void main(String[] args) {
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
names.stream()
.forEach(System.out::println);
}
}
4.2.2 收集(collect)
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
class Person {
String name;
int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
public class CollectOperation {
public static void main(String[] args) {
List<Person> people = Arrays.asList(
new Person("Alice", 25),
new Person("Bob", 30),
new Person("Charlie", 25)
);
// 收集到 List
List<String> names = people.stream()
.map(Person::getName)
.collect(Collectors.toList());
// 按年龄分组
Map<Integer, List<Person>> groupedByAge = people.stream()
.collect(Collectors.groupingBy(Person::getAge));
// 拼接名字
String namesJoined = people.stream()
.map(Person::getName)
.collect(Collectors.joining(", "));
}
}
4.2.3 统计(count)
import java.util.Arrays;
import java.util.List;
public class CountOperation {
public static void main(String[] args) {
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
long count = names.stream()
.count();
System.out.println("Number of names: " + count);
}
}
4.2.4 查找(findFirst、findAny)
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
public class FindOperation {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
Optional<Integer> firstEven = numbers.stream()
.filter(n -> n % 2 == 0)
.findFirst();
if (firstEven.isPresent()) {
System.out.println("First even number: " + firstEven.get());
}
Optional<Integer> anyEven = numbers.parallelStream()
.filter(n -> n % 2 == 0)
.findAny();
if (anyEven.isPresent()) {
System.out.println("Any even number: " + anyEven.get());
}
}
}
4.2.5 匹配(allMatch、anyMatch、noneMatch)
import java.util.Arrays;
import java.util.List;
public class MatchOperation {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(2, 4, 6, 8);
boolean allEven = numbers.stream()
.allMatch(n -> n % 2 == 0);
System.out.println("All numbers are even: " + allEven);
boolean anyGreaterThanFive = numbers.stream()
.anyMatch(n -> n > 5);
System.out.println("Any number is greater than 5: " + anyGreaterThanFive);
boolean noneGreaterThanTen = numbers.stream()
.noneMatch(n -> n > 10);
System.out.println("None of the numbers is greater than 10: " + noneGreaterThanTen);
}
}
4.2.6 归约(reduce)
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
public class ReduceOperation {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
// 无初始值的归约
Optional<Integer> sumWithoutInitial = numbers.stream()
.reduce((a, b) -> a + b);
if (sumWithoutInitial.isPresent()) {
System.out.println("Sum without initial value: " + sumWithoutInitial.get());
}
// 有初始值的归约
int sumWithInitial = numbers.stream()
.reduce(10, (a, b) -> a + b);
System.out.println("Sum with initial value: " + sumWithInitial);
}
}
五、并行流
并行流可以利用多核处理器并行处理元素,提高处理效率。但并行流并不适用于所有场景,使用时需要注意线程安全和性能开销。
import java.util.Arrays;
import java.util.List;
public class ParallelStreamExample {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
numbers.parallelStream()
.map(n -> n * 2)
.forEach(System.out::println);
}
}
六、Stream 的使用场景和注意事项
6.1 使用场景
- 数据过滤和筛选:当需要从大量数据中筛选出符合条件的元素时,Stream 的 filter 操作非常方便。
- 数据转换:使用 map 和 flatMap 操作可以将数据从一种类型转换为另一种类型。
- 数据分组和聚合:collect 操作可以实现数据的分组和聚合,如按条件分组、求和、计数等。
6.2 注意事项
- 流的一次性使用:Stream 只能被使用一次,一旦调用了终止操作,流就会被关闭,再次使用会抛出 IllegalStateException。
- 并行流的使用:并行流虽然可以提高处理效率,但在数据量较小或操作本身线程安全开销较大时,并行流可能会降低性能。在使用并行流前,需要对数据量和操作复杂度进行评估。
七、总结
Java 8 的 Stream API 为集合数据处理提供了一种强大而灵活的方式。通过声明式的编程风格和丰富的操作方法,开发者可以更高效地处理集合元素,编写更加简洁、易读和可维护的代码。同时,并行流的支持使得在多核处理器上可以充分发挥性能优势。但在使用 Stream API 时,需要注意流的一次性使用和并行流的适用场景。
你觉得这篇关于 Java 8 Stream API 的文章如何?如果你对文章还有其他的想法,比如增加某些 API 的详细使用案例、修改内容侧重点等,都可以随时告诉我。
猜你喜欢
- 2025-06-23 java8的stream使用小示例(java stream的用法)
- 2025-06-23 Java 中的 Lambda 表达式深入解析:从语法糖到高阶函数
- 2025-06-23 实战解析Android架构设计原则(android的架构)
- 2025-06-23 搭建mcp服务器用java17,可是项目开发用的是java8怎么实现?
- 2025-06-23 Java Stream:集合处理的api(java集合流操作)
- 2025-06-23 Java 8新特性全面剖析:让编程变得更简单优雅
- 2025-06-23 Java 8新特性全面解析与最佳实践:掌握未来编程的艺术
- 2025-06-23 Java 8日期时间API新特性揭秘与深度解析
你 发表评论:
欢迎- 最近发表
-
- java8的stream使用小示例(java stream的用法)
- Java 中的 Lambda 表达式深入解析:从语法糖到高阶函数
- 实战解析Android架构设计原则(android的架构)
- 搭建mcp服务器用java17,可是项目开发用的是java8怎么实现?
- Java Stream:集合处理的api(java集合流操作)
- Java 8新特性全面剖析:让编程变得更简单优雅
- Java 8新特性全面解析与最佳实践:掌握未来编程的艺术
- Java 8日期时间API新特性揭秘与深度解析
- Java 8 Stream API 详解(java.stream)
- Java机器学习库(Java ML)(二、聚类)
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)