287. Java Stream API - 通过数字范围创建 Stream
✅ 核心概念
如果你想创建一个包含一系列连续整数的 Stream,比如 0, 1, 2, 3...,最直接的方法是使用 Java 提供的 数值专用流(primitive stream):
IntStream:用于整数LongStream:用于长整型DoubleStream:用于浮点数
🔨 两种创建方式:
| 方法 | 是否包含结束值 |
|---|---|
range(start, end) | ❌ 不包含 end |
rangeClosed(start, end) | ✅ 包含 end |
📌 示例 1:使用 IntStream.range
IntStream.range(0, 5)
.forEach(System.out::print);
输出结果:
01234
📌 示例 2:使用 LongStream.rangeClosed
LongStream.rangeClosed(1, 5)
.forEach(System.out::print);
输出结果:
12345
📌 适用于:
- 循环替代
- 构造模拟数据
- 下标遍历数组或集合
📌 示例 3:使用范围索引访问数组
String[] letters = {"A", "B", "C", "D"};
List<String> listLetters = IntStream.range(0, 10)
.mapToObj(index -> letters[index % letters.length])
.collect(Collectors.toList());
System.out.println("listLetters = " + listLetters);
输出结果:
listLetters = [A, B, C, D, A, B, C, D, A, B]
🧠 解读:
index % letters.length实现循环访问数组mapToObj(...)将IntStream转换为对象流Stream<String>,才能收集为List<String>
🧠 为什么要用 mapToObj(...)?
因为 IntStream 是一个 基本类型流,无法直接用于装箱类型(如 String, Integer 等)操作。
IntStream.range(0, 5) // 基本类型 int
.mapToObj(i -> "Num" + i) // 装箱为 Stream<String>
.forEach(System.out::println);
🧪 示例 4:创建随机下标访问字符
String[] emojis = {"😊", "🚀", "🔥", "🎯"};
List<String> randomSequence = IntStream.range(0, 8)
.mapToObj(i -> emojis[(int)(Math.random() * emojis.length)])
.collect(Collectors.toList());
System.out.println("randomSequence = " + randomSequence);
输出结果(可能不同):
randomSequence = [🔥, 😊, 😊, 🚀, 🎯, 😊, 🔥, 🎯]
🎯 总结:何时使用 range() / rangeClosed()?
| 场景 | 推荐方法 |
|---|---|
| 遍历数组下标 | IntStream.range(0, array.length) |
| 包含起止值的区间(如 1-100) | IntStream.rangeClosed(1, 100) |
| 构造序列模拟数据 | 任意 |
💡 练习题(培训互动)
请补全以下代码,使其打印 10 个 0~9 的平方值:
List<Integer> squares = IntStream.range(0, ____)
.map(n -> n * n)
.boxed()
.collect(Collectors.toList());
System.out.println("squares = " + squares);
正确答案:
10