278. Java Stream API - 限制与跳过操作全解析

39 阅读2分钟

278. Java Stream API - 限制与跳过操作全解析


🎯 本节目标

  • 理解基于索引skip()limit() 方法
  • 理解基于条件dropWhile()takeWhile() 方法(Java 9 引入)
  • 学会如何安全、高效地选择你想要的元素子集
  • 避免常见陷阱

🚶 skip()limit() —— 基于索引的流操作


📌 方法介绍

方法作用
skip(n)跳过前 n 个元素
limit(n)保留前 n 个元素

这两个方法接收一个 long 参数,操作的是流中元素的顺序,适合用于分页、子集筛选等场景。


⚠️ 小陷阱:操作顺序影响结果!

❌ 错误思路:
ints.stream().skip(2).limit(8)

如果你想取第 3 个到第 8 个元素,这样写其实取的是第 3 到第 10 个元素(共 8 个),因为 limit 是在 skip 后的流上操作的!


✅ 正确示例:取第 3 到第 7 个元素

List<Integer> ints = List.of(1, 2, 3, 4, 5, 6, 7, 8, 9);

List<Integer> result = ints.stream()
                           .skip(2)   // 跳过前 2 个(得到 3, 4, 5, 6, 7, 8, 9)
                           .limit(5)  // 保留前 5 个(即 3 ~ 7)
                           .toList();

System.out.println("result = " + result);

🔽 输出:

result = [3, 4, 5, 6, 7]

🧠 类比记忆: 就像拿书页一样:先撕掉前 2 页(skip),然后从当前页开始只保留前 5 页(limit)。


🧠 Java 9 新特性:基于条件的筛选


🌊 dropWhile(predicate) —— 丢弃直到不满足条件为止

📌 一旦条件为假,从那一刻开始,所有元素都保留,不再判断。

✅ 示例:
List<Integer> nums = List.of(1, 2, 3, 4, 5, 0, 6);

List<Integer> dropped = nums.stream()
                            .dropWhile(n -> n < 4)
                            .toList();

System.out.println("dropWhile result = " + dropped);

🔽 输出:

dropWhile result = [4, 5, 0, 6]

📌 说明:1、2、3 被丢弃;从遇到 4 起(第一次不满足 n < 4),后续元素全都保留。


🌟 takeWhile(predicate) —— 保留直到不满足条件为止

📌 一旦条件为假,后续所有元素都将被丢弃,不会再次开启

✅ 示例:
List<Integer> nums = List.of(1, 2, 3, 4, 1, 0);

List<Integer> taken = nums.stream()
                          .takeWhile(n -> n < 4)
                          .toList();

System.out.println("takeWhile result = " + taken);

🔽 输出:

takeWhile result = [1, 2, 3]

📌 说明:当遇到 4 时条件不满足,后续的 10 都不再处理。


🧱 类比记忆(门的模型):

方法行为类比
dropWhile()丢弃直到条件不满足,门打开后一直开着门开了就不关了
takeWhile()保留直到条件不满足,门关了就不再开门关了就不开了

🧩 实战练习建议

☑️ 取前 10 个大于 50 的偶数:

List<Integer> data = IntStream.range(1, 1000).boxed().toList();

List<Integer> result = data.stream()
                           .filter(n -> n % 2 == 0 && n > 50)
                           .limit(10)
                           .toList();

☑️ 取连续小于 100 的元素:

List<Integer> result = data.stream()
                           .takeWhile(n -> n < 100)
                           .toList();

✅ 总结比较

方法类型使用场景说明
skip(n)索引操作跳过前 n 个
limit(n)索引操作取前 n 个
dropWhile(p)条件操作跳过直到遇到不满足条件的值
takeWhile(p)条件操作保留直到遇到不满足条件的值