Java Stream API 核心方法详解(初学者友好)
本文详细介绍了Java Stream API的7种流创建方法,适合初学者快速掌握Stream的核心用法。内容涵盖从集合、数组、元素、数值范围创建流,以及生成无限流的方法(generate/iterate)和空流创建。每个方法都通过语法说明、核心作用、操作类型和传统写法与Stream API写法的对比示例来讲解,帮助读者理解函数式编程的优势。特别强调了无限流的limit控制,以及空流避免NPE的作用
·
📚 文章目录
这里写目录标题
-
- Java Stream API 核心方法详解(初学者友好)
-
- 1. Stream 的创建
-
- 2. 中间操作(Intermediate Operations)
-
- 3. 终端操作(Terminal Operations)
-
- 3.a 匹配与查找(短路操作)
- 3.a.1 `anyMatch()` — 任一匹配
-
- 3.a.2 `allMatch()` — 全部匹配
-
- 3.a.3 `noneMatch()` — 无一匹配
-
- 3.a.4 `findFirst()` — 查找第一个元素
-
- 3.a.5 `findAny()` — 查找任意元素
-
- 3.b 消费与收集
- 3.b.1 `forEach()` — 遍历消费
-
- 3.b.2 `forEachOrdered()` — 有序遍历
-
- 3.b.3 `collect()` — 收集到集合或其他容器
-
- 3.b.4 `toArray()` — 转为数组
-
- 3.b.5 `reduce()` — 归约/聚合
-
- 3.b.6 `count()` — 计数
-
- 3.b.7 `min()` — 最小值
-
- 3.b.8 `max()` — 最大值
-
- 3.c 数值流特有方法
-
- 真实业务场景示例(稍复杂)
-
这里写目录标题
- Java Stream API 核心方法详解(初学者友好)
-
- 1. Stream 的创建
- 2. 中间操作(Intermediate Operations)
- 3. 终端操作(Terminal Operations)
-
- 3.a 匹配与查找(短路操作)
- 3.a.1 `anyMatch()` — 任一匹配
- 3.a.2 `allMatch()` — 全部匹配
- 3.a.3 `noneMatch()` — 无一匹配
- 3.a.4 `findFirst()` — 查找第一个元素
- 3.a.5 `findAny()` — 查找任意元素
- 3.b 消费与收集
- 3.b.1 `forEach()` — 遍历消费
- 3.b.2 `forEachOrdered()` — 有序遍历
- 3.b.3 `collect()` — 收集到集合或其他容器
- 3.b.4 `toArray()` — 转为数组
- 3.b.5 `reduce()` — 归约/聚合
- 3.b.6 `count()` — 计数
- 3.b.7 `min()` — 最小值
- 3.b.8 `max()` — 最大值
- 3.c 数值流特有方法
- 真实业务场景示例(稍复杂)
Java Stream API 核心方法详解(初学者友好)
✍️ 作者:默语 | 微信:Solitudemind
📬 公众号:默语摸鱼

1. Stream 的创建
1.1 stream() — 从集合创建流
1) 语法说明
default Stream<E> stream()
- 由集合(List、Set等)创建一个顺序流。
- 无参数,返回Stream。
- 中间操作链的起点。
2) 核心作用
- 将集合转成流,方便使用Stream API对元素进行函数式操作。
3) 操作类型
- 创建操作(起点)
4) 旧写法示例(传统循环)
import java.util.List;
public class StreamCreateOld {
public static void main(String[] args) {
List<String> list = List.of("苹果", "香蕉", "橘子");
// 传统遍历打印
for (String fruit : list) {
System.out.println(fruit);
}
}
}
5) 新写法示例(Stream API)
import java.util.List;
public class StreamCreateNew {
public static void main(String[] args) {
List<String> list = List.of("苹果", "香蕉", "橘子");
// 从集合创建流并遍历打印
list.stream()
.forEach(System.out::println);
}
}
1.2 of() — 从元素创建流
1) 语法说明
static <T> Stream<T> of(T... values)
- 直接由给定的元素创建流。
- 参数为元素可变参数。
- 方便快速创建流。
2) 核心作用
- 直接用一组元素创建流,适合临时操作少量数据。
3) 操作类型
- 创建操作
4) 旧写法示例
public class StreamOfOld {
public static void main(String[] args) {
// 传统数组遍历
String[] fruits = {"苹果", "香蕉", "橘子"};
for (String fruit : fruits) {
System.out.println(fruit);
}
}
}
5) 新写法示例
import java.util.stream.Stream;
public class StreamOfNew {
public static void main(String[] args) {
// 直接用元素创建流并遍历
Stream.of("苹果", "香蕉", "橘子")
.forEach(System.out::println);
}
}
1.3 Arrays.stream() — 从数组创建流
1) 语法说明
static <T> Stream<T> stream(T[] array)
- 把数组转成流。
- 适用于已有数组操作。
2) 核心作用
- 方便把数组数据导入流式处理。
3) 操作类型
- 创建操作
4) 旧写法示例
public class ArraysStreamOld {
public static void main(String[] args) {
String[] arr = {"a", "b", "c"};
for (String s : arr) {
System.out.println(s);
}
}
}
5) 新写法示例
import java.util.Arrays;
public class ArraysStreamNew {
public static void main(String[] args) {
String[] arr = {"a", "b", "c"};
Arrays.stream(arr)
.forEach(System.out::println);
}
}
1.4 range() / rangeClosed() — 从数值范围创建数值流
1) 语法说明
static IntStream range(int startInclusive, int endExclusive)
static IntStream rangeClosed(int startInclusive, int endInclusive)
- 生成指定区间的数值流。
range不包含结束值,rangeClosed包含结束值。
2) 核心作用
- 快速生成连续的数值流,便于数值计算或索引处理。
3) 操作类型
- 创建操作
4) 旧写法示例
public class RangeOld {
public static void main(String[] args) {
// 传统循环打印1~5
for (int i = 1; i <= 5; i++) {
System.out.println(i);
}
}
}
5) 新写法示例
import java.util.stream.IntStream;
public class RangeNew {
public static void main(String[] args) {
// 打印1到5(包含5)
IntStream.rangeClosed(1, 5)
.forEach(System.out::println);
}
}
1.5 generate() — 生成无限流
1) 语法说明
static<T> Stream<T> generate(Supplier<T> s)
- 根据Supplier函数无限生成元素流。
- 流是无限的,需用limit限制大小。
2) 核心作用
- 生成基于规则的无限流,适合模拟数据、随机数等。
3) 操作类型
- 创建操作
4) 旧写法示例
import java.util.Random;
public class GenerateOld {
public static void main(String[] args) {
Random random = new Random();
for (int i = 0; i < 5; i++) {
System.out.println(random.nextInt(100));
}
}
}
5) 新写法示例
import java.util.Random;
import java.util.stream.Stream;
public class GenerateNew {
public static void main(String[] args) {
Random random = new Random();
// 生成5个随机数
Stream.generate(() -> random.nextInt(100))
.limit(5) // 限制流大小,防止无限循环
.forEach(System.out::println);
}
}
1.6 iterate() — 迭代生成无限流
1) 语法说明
static<T> Stream<T> iterate(T seed, UnaryOperator<T> f)
- 从初始元素
seed开始,不断对前一个元素应用函数f生成下一个。 - 生成无限流,通常用limit限制。
2) 核心作用
- 生成规则序列流,例如等差数列、斐波那契数列等。
3) 操作类型
- 创建操作
4) 旧写法示例
public class IterateOld {
public static void main(String[] args) {
int start = 1;
for (int i = 0; i < 5; i++) {
System.out.println(start);
start += 2; // 生成奇数序列
}
}
}
5) 新写法示例
import java.util.stream.Stream;
public class IterateNew {
public static void main(String[] args) {
// 生成前5个奇数
Stream.iterate(1, n -> n + 2)
.limit(5)
.forEach(System.out::println);
}
}
1.7 empty() — 创建空流
1) 语法说明
static<T> Stream<T> empty()
- 返回一个不包含元素的空流。
2) 核心作用
- 用于需要返回空流而非null的场景,避免空指针。
3) 操作类型
- 创建操作
4) 旧写法示例
import java.util.Collections;
import java.util.List;
public class EmptyOld {
public static void main(String[] args) {
List<String> emptyList = Collections.emptyList();
System.out.println(emptyList.size()); // 0
}
}
5) 新写法示例
import java.util.stream.Stream;
public class EmptyNew {
public static void main(String[] args) {
Stream<String> emptyStream = Stream.empty();
System.out.println("空流元素数量:" + emptyStream.count());
}
}
2. 中间操作(Intermediate Operations)
2.1 filter() — 过滤(筛选元素)
1) 语法说明
Stream<T> filter(Predicate<? super T> predicate)
- 接收一个Predicate函数,判断元素是否保留。
- 返回过滤后的新Stream。
2) 核心作用
- 根据条件筛选元素,便捷高效。
3) 操作类型
- 中间操作
4) 旧写法示例
import java.util.ArrayList;
import java.util.List;
public class FilterOld {
public static void main(String[] args) {
List<Integer> nums = List.of(5, 12, 9, 18, 3);
List<Integer> result = new ArrayList<>();
for (Integer n : nums) {
if (n > 10) {
result.add(n);
}
}
System.out.println("旧写法结果:" + result);
}
}
5) 新写法示例
import java.util.List;
import java.util.stream.Collectors;
public class FilterNew {
public static void main(String[] args) {
List<Integer> nums = List.of(5, 12, 9, 18, 3);
List<Integer> result = nums.stream()
.filter(n -> n > 10) // 过滤条件,大于10
.collect(Collectors.toList()); // 收集结果
System.out.println("新写法结果:" + result);
}
}
2.2 map() — 转换/映射
1) 语法说明
<R> Stream<R> map(Function<? super T, ? extends R> mapper)
- 接收一个Function函数,将元素转换成另一种形式。
- 返回转换后的Stream。
2) 核心作用
- 轻松实现类型转换、提取字段等操作。
3) 操作类型
- 中间操作
4) 旧写法示例
import java.util.ArrayList;
import java.util.List;
public class MapOld {
public static void main(String[] args) {
List<String> names = List.of("张三", "李四", "王五");
List<Integer> nameLengths = new ArrayList<>();
for (String name : names) {
nameLengths.add(name.length());
}
System.out.println("旧写法结果:" + nameLengths);
}
}
5) 新写法示例
import java.util.List;
import java.util.stream.Collectors;
public class MapNew {
public static void main(String[] args) {
List<String> names = List.of("张三", "李四", "王五");
List<Integer> nameLengths = names.stream()
.map(String::length) // 映射到字符串长度
.collect(Collectors.toList());
System.out.println("新写法结果:" + nameLengths);
}
}
2.3 flatMap() — 扁平化映射
1) 语法说明
<R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper)
- 将每个元素转换成一个流,然后把多个流合并成一个流。
2) 核心作用
- 解决嵌套流的平铺问题,比如把List转成List。
3) 操作类型
- 中间操作
4) 旧写法示例
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class FlatMapOld {
public static void main(String[] args) {
List<List<String>> listOfLists = Arrays.asList(
Arrays.asList("a", "b"),
Arrays.asList("c", "d")
);
List<String> flatList = new ArrayList<>();
for (List<String> list : listOfLists) {
for (String s : list) {
flatList.add(s);
}
}
System.out.println("旧写法结果:" + flatList);
}
}
5) 新写法示例
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class FlatMapNew {
public static void main(String[] args) {
List<List<String>> listOfLists = Arrays.asList(
Arrays.asList("a", "b"),
Arrays.asList("c", "d")
);
List<String> flatList = listOfLists.stream()
.flatMap(List::stream) // 把多层流扁平化为单层流
.collect(Collectors.toList());
System.out.println("新写法结果:" + flatList);
}
}
2.4 distinct() — 去重
1) 语法说明
Stream<T> distinct()
- 根据元素的
equals()和hashCode()去除重复元素。
2) 核心作用
- 去除流中重复元素,保证唯一性。
3) 操作类型
- 中间操作
4) 旧写法示例
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class DistinctOld {
public static void main(String[] args) {
List<String> list = List.of("apple", "banana", "apple", "orange");
Set<String> set = new HashSet<>();
for (String s : list) {
set.add(s);
}
System.out.println("旧写法结果:" + set);
}
}
5) 新写法示例
import java.util.List;
import java.util.stream.Collectors;
public class DistinctNew {
public static void main(String[] args) {
List<String> list = List.of("apple", "banana", "apple", "orange");
List<String> distinctList = list.stream()
.distinct() // 去重
.collect(Collectors.toList());
System.out.println("新写法结果:" + distinctList);
}
}
2.5 sorted() — 排序
1) 语法说明
Stream<T> sorted()
Stream<T> sorted(Comparator<? super T> comparator)
- 无参排序:按自然顺序排序(元素需实现Comparable)。
- 带参排序:自定义比较器。
2) 核心作用
- 对元素进行排序,支持自然排序或自定义排序规则。
3) 操作类型
- 中间操作
4) 旧写法示例
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class SortedOld {
public static void main(String[] args) {
List<Integer> nums = List.of(5, 2, 9, 1);
List<Integer> list = new ArrayList<>(nums);
Collections.sort(list);
System.out.println("旧写法排序结果:" + list);
}
}
5) 新写法示例
import java.util.List;
import java.util.stream.Collectors;
public class SortedNew {
public static void main(String[] args) {
List<Integer> nums = List.of(5, 2, 9, 1);
List<Integer> sortedList = nums.stream()
.sorted() // 自然排序
.collect(Collectors.toList());
System.out.println("新写法排序结果:" + sortedList);
}
}
2.6 peek() — 执行操作(调试用)
1) 语法说明
Stream<T> peek(Consumer<? super T> action)
- 对流中元素执行指定操作,返回同一流。
- 通常用于调试或打印。
2) 核心作用
- 方便在流操作链中观察中间元素状态,不影响流操作。
3) 操作类型
- 中间操作
4) 旧写法示例
无直接对比,传统方法需要在循环中打印。
5) 新写法示例
import java.util.List;
public class PeekNew {
public static void main(String[] args) {
List<String> names = List.of("张三", "李四", "王五");
names.stream()
.filter(n -> n.length() == 2)
.peek(n -> System.out.println("符合条件的元素:" + n)) // 打印调试
.map(String::toUpperCase)
.forEach(System.out::println);
}
}
2.7 limit() — 截断,取前N个
1) 语法说明
Stream<T> limit(long maxSize)
- 截取流中前
maxSize个元素。
2) 核心作用
- 用于分页或限制数据量。
3) 操作类型
- 中间操作
4) 旧写法示例
import java.util.List;
public class LimitOld {
public static void main(String[] args) {
List<String> list = List.of("a", "b", "c", "d");
for (int i = 0; i < 2 && i < list.size(); i++) {
System.out.println(list.get(i));
}
}
}
5) 新写法示例
import java.util.List;
public class LimitNew {
public static void main(String[] args
) {
List list = List.of(“a”, “b”, “c”, “d”);
list.stream()
.limit(2) // 取前2个元素
.forEach(System.out::println);
}
}
---
### 2.8 `skip()` — 跳过前N个
#### 1) 语法说明
```java
Stream<T> skip(long n)
- 跳过流中前
n个元素。
2) 核心作用
- 用于分页跳过前面数据。
3) 操作类型
- 中间操作
4) 旧写法示例
import java.util.List;
public class SkipOld {
public static void main(String[] args) {
List<String> list = List.of("a", "b", "c", "d");
for (int i = 2; i < list.size(); i++) {
System.out.println(list.get(i));
}
}
}
5) 新写法示例
import java.util.List;
public class SkipNew {
public static void main(String[] args) {
List<String> list = List.of("a", "b", "c", "d");
list.stream()
.skip(2) // 跳过前2个
.forEach(System.out::println);
}
}
3. 终端操作(Terminal Operations)
3.a 匹配与查找(短路操作)
3.a.1 anyMatch() — 任一匹配
1) 语法说明
boolean anyMatch(Predicate<? super T> predicate)
- 判断流中是否至少有一个元素匹配条件。
- 一旦找到满足条件的元素,立即返回
true(短路)。
2) 核心作用
- 快速检测是否存在符合条件的元素。
3) 操作类型
- 终端操作
4) 旧写法示例
import java.util.List;
public class AnyMatchOld {
public static void main(String[] args) {
List<Integer> nums = List.of(1, 3, 5, 8);
boolean found = false;
for (Integer n : nums) {
if (n % 2 == 0) {
found = true;
break;
}
}
System.out.println("旧写法是否存在偶数:" + found);
}
}
5) 新写法示例
import java.util.List;
public class AnyMatchNew {
public static void main(String[] args) {
List<Integer> nums = List.of(1, 3, 5, 8);
boolean found = nums.stream()
.anyMatch(n -> n % 2 == 0); // 判断是否存在偶数
System.out.println("新写法是否存在偶数:" + found);
}
}
3.a.2 allMatch() — 全部匹配
1) 语法说明
boolean allMatch(Predicate<? super T> predicate)
- 判断流中所有元素是否全部满足条件。
- 只要有一个不满足,立即返回
false(短路)。
2) 核心作用
- 验证数据是否全部符合条件。
3) 操作类型
- 终端操作
4) 旧写法示例
import java.util.List;
public class AllMatchOld {
public static void main(String[] args) {
List<Integer> nums = List.of(2, 4, 6, 8);
boolean allEven = true;
for (Integer n : nums) {
if (n % 2 != 0) {
allEven = false;
break;
}
}
System.out.println("旧写法是否全部偶数:" + allEven);
}
}
5) 新写法示例
import java.util.List;
public class AllMatchNew {
public static void main(String[] args) {
List<Integer> nums = List.of(2, 4, 6, 8);
boolean allEven = nums.stream()
.allMatch(n -> n % 2 == 0);
System.out.println("新写法是否全部偶数:" + allEven);
}
}
3.a.3 noneMatch() — 无一匹配
1) 语法说明
boolean noneMatch(Predicate<? super T> predicate)
- 判断流中没有任何元素满足条件。
- 找到一个匹配的即返回
false。
2) 核心作用
- 验证数据不含有符合条件的元素。
3) 操作类型
- 终端操作
4) 旧写法示例
import java.util.List;
public class NoneMatchOld {
public static void main(String[] args) {
List<String> words = List.of("apple", "banana", "pear");
boolean noneStartWithZ = true;
for (String w : words) {
if (w.startsWith("z")) {
noneStartWithZ = false;
break;
}
}
System.out.println("旧写法是否无以z开头:" + noneStartWithZ);
}
}
5) 新写法示例
import java.util.List;
public class NoneMatchNew {
public static void main(String[] args) {
List<String> words = List.of("apple", "banana", "pear");
boolean noneStartWithZ = words.stream()
.noneMatch(w -> w.startsWith("z"));
System.out.println("新写法是否无以z开头:" + noneStartWithZ);
}
}
3.a.4 findFirst() — 查找第一个元素
1) 语法说明
Optional<T> findFirst()
- 返回流中的第一个元素,使用
Optional包装。
2) 核心作用
- 获取流头部元素。
3) 操作类型
- 终端操作
4) 旧写法示例
import java.util.List;
public class FindFirstOld {
public static void main(String[] args) {
List<String> list = List.of("a", "b", "c");
String first = null;
if (!list.isEmpty()) {
first = list.get(0);
}
System.out.println("旧写法第一个元素:" + first);
}
}
5) 新写法示例
import java.util.List;
import java.util.Optional;
public class FindFirstNew {
public static void main(String[] args) {
List<String> list = List.of("a", "b", "c");
Optional<String> first = list.stream().findFirst();
first.ifPresent(s -> System.out.println("新写法第一个元素:" + s));
}
}
3.a.5 findAny() — 查找任意元素
1) 语法说明
Optional<T> findAny()
- 返回流中任意一个元素(并行流时效率更高)。
2) 核心作用
- 快速获取任意元素。
3) 操作类型
- 终端操作
4) 旧写法示例
和findFirst基本一致。
5) 新写法示例
import java.util.List;
import java.util.Optional;
public class FindAnyNew {
public static void main(String[] args) {
List<String> list = List.of("x", "y", "z");
Optional<String> any = list.stream().findAny();
any.ifPresent(s -> System.out.println("新写法任意元素:" + s));
}
}
3.b 消费与收集
3.b.1 forEach() — 遍历消费
1) 语法说明
void forEach(Consumer<? super T> action)
- 对流中每个元素执行指定动作。
2) 核心作用
- 遍历元素,执行操作(打印、保存等)。
3) 操作类型
- 终端操作
4) 旧写法示例
import java.util.List;
public class ForEachOld {
public static void main(String[] args) {
List<String> list = List.of("a", "b", "c");
for (String s : list) {
System.out.println(s);
}
}
}
5) 新写法示例
import java.util.List;
public class ForEachNew {
public static void main(String[] args) {
List<String> list = List.of("a", "b", "c");
list.stream()
.forEach(System.out::println);
}
}
3.b.2 forEachOrdered() — 有序遍历
1) 语法说明
void forEachOrdered(Consumer<? super T> action)
- 在并行流中保证遍历顺序。
2) 核心作用
- 并行流中确保元素按顺序消费。
3) 操作类型
- 终端操作
4) 旧写法示例
传统流没有并行,默认有序。
5) 新写法示例
import java.util.List;
public class ForEachOrderedNew {
public static void main(String[] args) {
List<String> list = List.of("a", "b", "c");
list.parallelStream()
.forEachOrdered(System.out::println); // 保证顺序输出
}
}
3.b.3 collect() — 收集到集合或其他容器
1) 语法说明
<R, A> R collect(Collector<? super T, A, R> collector)
- 把流中的元素收集成List、Set、Map或自定义结构。
2) 核心作用
- 最常用的终端操作,转换流为集合。
3) 操作类型
- 终端操作
4) 旧写法示例
import java.util.ArrayList;
import java.util.List;
public class CollectOld {
public static void main(String[] args) {
List<String> list = List.of("a", "b", "c");
List<String> result = new ArrayList<>();
for (String s : list) {
if (s.length() == 1) {
result.add(s);
}
}
System.out.println(result);
}
}
5) 新写法示例
import java.util.List;
import java.util.stream.Collectors;
public class CollectNew {
public static void main(String[] args) {
List<String> list = List.of("a", "bb", "c");
List<String> result = list.stream()
.filter(s -> s.length() == 1)
.collect(Collectors.toList());
System.out.println(result);
}
}
3.b.4 toArray() — 转为数组
1) 语法说明
Object[] toArray()
<T> T[] toArray(IntFunction<T[]> generator)
- 把流转换成数组。
- 第二个重载可指定数组类型。
2) 核心作用
- 转换成数组,方便与传统API兼容。
3) 操作类型
- 终端操作
4) 旧写法示例
import java.util.List;
public class ToArrayOld {
public static void main(String[] args) {
List<String> list = List.of("a", "b", "c");
String[] arr = new String[list.size()];
for (int i = 0; i < list.size(); i++) {
arr[i] = list.get(i);
}
for (String s : arr) {
System.out.println(s);
}
}
}
5) 新写法示例
import java.util.List;
public class ToArrayNew {
public static void main(String[] args) {
List<String> list = List.of("a", "b", "c");
String[] arr = list.stream()
.toArray(String[]::new);
for (String s : arr) {
System.out.println(s);
}
}
}
3.b.5 reduce() — 归约/聚合
1) 语法说明
Optional<T> reduce(BinaryOperator<T> accumulator)
T reduce(T identity, BinaryOperator<T> accumulator)
<U> U reduce(U identity, BiFunction<U,? super T,U> accumulator, BinaryOperator<U> combiner)
- 将流中的元素反复结合起来,得到一个值。
2) 核心作用
- 实现累加、连接、求最大最小等聚合运算。
3) 操作类型
- 终端操作
4) 旧写法示例
import java.util.List;
public class ReduceOld {
public static void main(String[] args) {
List<Integer> nums = List.of(1, 2, 3, 4, 5);
int sum = 0;
for (Integer n : nums) {
sum += n;
}
System.out.println("旧写法求和:" + sum);
}
}
5) 新写法示例
import java.util.List;
public class ReduceNew {
public static void main(String[] args) {
List<Integer> nums = List.of(1, 2, 3, 4, 5);
int sum = nums.stream()
.reduce(0, Integer::sum); // 累加
System.out.println("新写法求和:" + sum);
}
}
3.b.6 count() — 计数
1) 语法说明
long count()
- 返回流中元素个数。
2) 核心作用
- 统计元素数量。
3) 操作类型
- 终端操作
4) 旧写法示例
import java.util.List;
public class CountOld {
public static void main(String[] args) {
List<String> list = List.of("a", "b", "c");
int count = 0;
for (String s : list) {
count++;
}
System.out.println("旧写法数量:" + count);
}
}
5) 新写法示例
import java.util.List;
public class CountNew {
public static void main(String[] args) {
List<String> list = List.of("a", "b", "c");
long count = list.stream().count();
System.out.println("新写法数量:" + count);
}
}
3.b.7 min() — 最小值
1) 语法说明
Optional<T> min(Comparator<? super T> comparator)
- 返回流中最小元素(自定义比较器)。
2) 核心作用
- 找最小元素。
3) 操作类型
- 终端操作
4) 旧写法示例
import java.util.List;
public class MinOld {
public static void main(String[] args) {
List<Integer> nums = List.of(5, 2, 9, 1);
int min = nums.get(0);
for (Integer n : nums) {
if (n < min) {
min = n;
}
}
System.out.println("旧写法最小值:" + min);
}
}
5) 新写法示例
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
public class MinNew {
public static void main(String[] args) {
List<Integer> nums = List.of(5, 2, 9, 1);
Optional<Integer> min = nums.stream().min(Integer::compareTo);
min.ifPresent(m -> System.out.println("新写法最小值:" + m));
}
}
3.b.8 max() — 最大值
1) 语法说明
Optional<T> max(Comparator<? super T> comparator)
- 返回流中最大元素。
2) 核心作用
- 找最大元素。
3) 操作类型
- 终端操作
4) 旧写法示例
import java.util.List;
public class MaxOld {
public static void main(String[] args) {
List<Integer> nums = List.of(5, 2, 9, 1);
int max = nums.get(0);
for (Integer n : nums) {
if (n > max) {
max = n;
}
}
System.out.println("旧写法最大值:" + max);
}
}
5) 新写法示例
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
public class MaxNew {
public static void main(String[] args) {
List<Integer> nums = List.of(5, 2, 9, 1);
Optional<Integer> max = nums.stream().max(Integer::compareTo);
max.ifPresent(m -> System.out.println("新写法最大值:" + m));
}
}
3.c 数值流特有方法
3.c.1 sum() — 求和
1) 语法说明
int sum()
long sum()
double sum()
- 求数值流中所有元素之和。
2) 核心作用
- 快速求和。
3) 操作类型
- 终端操作
4) 旧写法示例
import java.util.List;
public class SumOld {
public static void main(String[] args) {
List nums = List.of(1, 2, 3);
int sum = 0;
for (int n : nums) {
sum += n;
}
System.out.println("旧写法求和:" + sum);
}
}
5) 新写法示例
import java.util.List;
public class SumNew {
public static void main(String[] args) {
List<Integer> nums = List.of(1, 2, 3);
int sum = nums.stream().mapToInt(Integer::intValue).sum();
System.out.println("新写法求和:" + sum);
}
}
3.c.2 average() — 求平均值
1) 语法说明
OptionalDouble average()
- 返回数值流的平均值,结果用OptionalDouble包装。
2) 核心作用
- 方便计算平均。
3) 操作类型
- 终端操作
4) 旧写法示例
import java.util.List;
public class AverageOld {
public static void main(String[] args) {
List<Integer> nums = List.of(2, 4, 6);
int sum = 0;
for (int n : nums) {
sum += n;
}
double avg = nums.size() > 0 ? (double) sum / nums.size() : 0;
System.out.println("旧写法平均值:" + avg);
}
}
5) 新写法示例
import java.util.List;
import java.util.OptionalDouble;
public class AverageNew {
public static void main(String[] args) {
List<Integer> nums = List.of(2, 4, 6);
OptionalDouble average = nums.stream()
.mapToInt(Integer::intValue)
.average();
average.ifPresent(avg -> System.out.println("新写法平均值:" + avg));
}
}
3.c.3 summaryStatistics() — 获取统计对象
1) 语法说明
IntSummaryStatistics summaryStatistics()
LongSummaryStatistics summaryStatistics()
DoubleSummaryStatistics summaryStatistics()
- 返回包含计数、总和、最小、最大、平均的统计结果对象。
2) 核心作用
- 一步得到多种统计信息,简化代码。
3) 操作类型
- 终端操作
4) 旧写法示例
import java.util.List;
public class SummaryOld {
public static void main(String[] args) {
List<Integer> nums = List.of(1, 2, 3);
int count = nums.size();
int sum = 0;
int min = Integer.MAX_VALUE;
int max = Integer.MIN_VALUE;
for (int n : nums) {
sum += n;
if (n < min) min = n;
if (n > max) max = n;
}
double avg = count > 0 ? (double) sum / count : 0;
System.out.println("旧写法统计:");
System.out.println("数量:" + count);
System.out.println("总和:" + sum);
System.out.println("最小:" + min);
System.out.println("最大:" + max);
System.out.println("平均:" + avg);
}
}
5) 新写法示例
import java.util.IntSummaryStatistics;
import java.util.List;
public class SummaryNew {
public static void main(String[] args) {
List<Integer> nums = List.of(1, 2, 3);
IntSummaryStatistics stats = nums.stream()
.mapToInt(Integer::intValue)
.summaryStatistics();
System.out.println("新写法统计:");
System.out.println("数量:" + stats.getCount());
System.out.println("总和:" + stats.getSum());
System.out.println("最小:" + stats.getMin());
System.out.println("最大:" + stats.getMax());
System.out.println("平均:" + stats.getAverage());
}
}
真实业务场景示例(稍复杂)
import java.util.*;
import java.util.stream.Collectors;
public class BusinessScenario {
static class Employee {
String name;
int age;
String department;
double salary;
Employee(String name, int age, String department, double salary) {
this.name = name;
this.age = age;
this.department = department;
this.salary = salary;
}
public String getName() { return name; }
public int getAge() { return age; }
public String getDepartment() { return department; }
public double getSalary() { return salary; }
@Override
public String toString() {
return String.format("%s, %d岁, 部门:%s, 薪资:%.2f", name, age, department, salary);
}
}
public static void main(String[] args) {
List<Employee> employees = Arrays.asList(
new Employee("张三", 25, "技术", 8000),
new Employee("李四", 32, "技术", 12000),
new Employee("王五", 28, "市场", 9000),
new Employee("赵六", 45, "市场", 15000),
new Employee("孙七", 38, "技术", 11000)
);
// 业务需求1:过滤出技术部门且年龄大于30的员工名单
List<Employee> filtered = employees.stream()
.filter(e -> "技术".equals(e.getDepartment()) && e.getAge() > 30)
.collect(Collectors.toList());
System.out.println("技术部门且年龄>30员工名单:");
filtered.forEach(System.out::println);
// 业务需求2:获取所有员工名字列表
List<String> names = employees.stream()
.map(Employee::getName)
.collect(Collectors.toList());
System.out.println("\n所有员工名字列表:" + names);
// 业务需求3:统计市场部门员工的平均薪资
double avgMarketSalary = employees.stream()
.filter(e -> "市场".equals(e.getDepartment()))
.mapToDouble(Employee::getSalary)
.average()
.orElse(0);
System.out.println("\n市场部门员工平均薪资:" + avgMarketSalary);
// 业务需求4:查找薪资最高的员工
employees.stream()
.max(Comparator.comparingDouble(Employee::getSalary))
.ifPresent(e -> System.out.println("\n薪资最高员工:" + e));
}
}
📮 联系方式
- 微信:Solitudemind
- 公众号:默语摸鱼
📢 加入默语共创社群矩阵
和一群优秀的技术人一起探索科技未来,共同成长 🚀
更多推荐




所有评论(0)