释放双眼,带上耳机,听听看~!
欢迎来到今天的 Java 教程!Stream API 是 Java 8 引入的强大工具。让集合操作更简洁、更高效。
一、Stream 基础
1.1 什么是 Stream
Stream 是数据元素的序列。支持聚合操作:
import java.util.*;
i... 
欢迎来到今天的 Java 教程!Stream API 是 Java 8 引入的强大工具。让集合操作更简洁、更高效。
一、Stream 基础
1.1 什么是 Stream
Stream 是数据元素的序列。支持聚合操作:
import java.util.*;
import java.util.stream.*;
List<String> list = Arrays.asList("Java", "Python", "Go", "Rust");
// 创建 Stream
Stream<String> stream = list.stream();
1.2 Stream 特点
- 不存储数据:只是数据源的视图
- 不修改源数据:操作返回新 Stream
- 惰性求值:中间操作延迟执行
- 只能遍历一次:用完需要重新创建
二、创建 Stream
2.1 从集合创建
List<String> list = Arrays.asList("a", "b", "c");
// 方式 1:stream()
list.stream();
// 方式 2:parallelStream()
list.parallelStream();
2.2 从数组创建
int[] arr = {1, 2, 3, 4, 5};
// 方式 1:Arrays.stream()
IntStream stream = Arrays.stream(arr);
// 方式 2:Stream.of()
Stream<Integer> stream2 = Stream.of(1, 2, 3);
2.3 生成 Stream
// 无限流(需要 limit)
Stream<Double> randoms = Stream.generate(Math::random);
randoms.limit(5).forEach(System.out::println);
// 迭代流
Stream.iterate(0, n -> n + 2)
.limit(5)
.forEach(System.out::println); // 0, 2, 4, 6, 8
三、中间操作
3.1 过滤(filter)
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6);
// 筛选偶数
numbers.stream()
.filter(n -> n % 2 == 0)
.forEach(System.out::println); // 2, 4, 6
3.2 映射(map)
List<String> words = Arrays.asList("hello", "world");
// 转大写
words.stream()
.map(String::toUpperCase)
.forEach(System.out::println); // HELLO, WORLD
// 提取长度
words.stream()
.map(String::length)
.forEach(System.out::println); // 5, 5
3.3 扁平化(flatMap)
List<List<Integer>> nested = Arrays.asList(
Arrays.asList(1, 2),
Arrays.asList(3, 4),
Arrays.asList(5, 6)
);
// 扁平化
nested.stream()
.flatMap(List::stream)
.forEach(System.out::println); // 1, 2, 3, 4, 5, 6
3.4 去重(distinct)
List<Integer> numbers = Arrays.asList(1, 2, 2, 3, 3, 3);
numbers.stream()
.distinct()
.forEach(System.out::println); // 1, 2, 3
3.5 排序(sorted)
List<Integer> numbers = Arrays.asList(5, 2, 8, 1, 9);
// 自然排序
numbers.stream()
.sorted()
.forEach(System.out::println); // 1, 2, 5, 8, 9
// 自定义排序
numbers.stream()
.sorted(Comparator.reverseOrder())
.forEach(System.out::println); // 9, 8, 5, 2, 1
3.6 限制(limit, skip)
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
// 取前 3 个
numbers.stream().limit(3)
.forEach(System.out::println); // 1, 2, 3
// 跳过前 2 个
numbers.stream().skip(2)
.forEach(System.out::println); // 3, 4, 5
// 组合使用
numbers.stream().skip(1).limit(3)
.forEach(System.out::println); // 2, 3, 4
四、终端操作
4.1 遍历(forEach)
List<String> list = Arrays.asList("a", "b", "c");
list.stream().forEach(System.out::println);
4.2 收集(collect)
List<String> list = Arrays.asList("Java", "Python", "Go");
// 收集到 List
List<String> result = list.stream()
.filter(s -> s.length() > 3)
.collect(Collectors.toList());
// 收集到 Set
Set<String> set = list.stream()
.collect(Collectors.toSet());
// 收集到 String
String joined = list.stream()
.collect(Collectors.joining(", ")); // "Java, Python, Go"
4.3 归约(reduce)
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
// 求和
int sum = numbers.stream()
.reduce(0, (a, b) -> a + b); // 15
// 求最大值
Optional<Integer> max = numbers.stream()
.reduce(Integer::max); // 5
// 求乘积
int product = numbers.stream()
.reduce(1, (a, b) -> a * b); // 120
4.4 匹配(anyMatch, allMatch, noneMatch)
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
// 是否有偶数
boolean hasEven = numbers.stream()
.anyMatch(n -> n % 2 == 0); // true
// 是否都大于 0
boolean allPositive = numbers.stream()
.allMatch(n -> n > 0); // true
// 是否没有负数
boolean noNegative = numbers.stream()
.noneMatch(n -> n < 0); // true
4.5 查找(findAny, findFirst)
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
// 查找第一个偶数
Optional<Integer> firstEven = numbers.stream()
.filter(n -> n % 2 == 0)
.findFirst(); // 2
// 查找任意元素(并行流有用)
Optional<Integer> any = numbers.stream()
.findAny();
4.6 统计(count, min, max)
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
// 计数
long count = numbers.stream().count(); // 5
// 最小值
Optional<Integer> min = numbers.stream().min(Integer::compareTo);
// 最大值
Optional<Integer> max = numbers.stream().max(Integer::compareTo);
五、数值流
5.1 IntStream、LongStream、DoubleStream
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
// 转换为 IntStream
IntStream intStream = numbers.stream().mapToInt(Integer::intValue);
// 统计信息
IntSummaryStatistics stats = numbers.stream()
.mapToInt(Integer::intValue)
.summaryStatistics();
System.out.println("平均值:" + stats.getAverage()); // 3.0
System.out.println("总和:" + stats.getSum()); // 15
System.out.println("最大值:" + stats.getMax()); // 5
System.out.println("最小值:" + stats.getMin()); // 1
六、分组和分区
6.1 分组(groupingBy)
class Person {
String name;
int age;
String city;
// 构造方法、getter 省略
}
List<Person> people = Arrays.asList(
new Person("张三", 25, "北京"),
new Person("李四", 30, "上海"),
new Person("王五", 25, "北京")
);
// 按年龄分组
Map<Integer, List<Person>> byAge = people.stream()
.collect(Collectors.groupingBy(Person::getAge));
// 按城市分组
Map<String, List<Person>> byCity = people.stream()
.collect(Collectors.groupingBy(Person::getCity));
6.2 分区(partitioningBy)
// 按是否成年分区
Map<Boolean, List<Person>> byAdult = people.stream()
.collect(Collectors.partitioningBy(p -> p.getAge() >= 18));
// true 分区:所有成年人
// false 分区:所有未成年人
七、并行流
List<Integer> numbers = IntStream.rangeClosed(1, 1000000)
.boxed()
.collect(Collectors.toList());
// 串行流
long start = System.currentTimeMillis();
numbers.stream()
.mapToInt(Integer::intValue)
.sum();
System.out.println("串行:" + (System.currentTimeMillis() - start));
// 并行流
start = System.currentTimeMillis();
numbers.parallelStream()
.mapToInt(Integer::intValue)
.sum();
System.out.println("并行:" + (System.currentTimeMillis() - start));
关注我们获取更多 Java 教程和最佳实践!
声明:本站所有文章,如无特殊说明或标注,均来自于互联网,下载的软件和资源请在24小时之内删除,本站提供的资源只可作为下载、学习交流使用,其版权归原作者所有,其产生的任何后果均自己承担,本站不作任何责任承担,具体可查看本站免责声明。如已声明或标注原创,任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理,客服链接:点此前往,投诉邮箱:nc08wlkj@163.com。
