
在 Java Stream API 中,除了 filter(按条件筛选)和 distinct(去重),用于筛选与切片的常用操作还有 limit、skip,以及结合有序流的 takeWhile 和 dropWhile(Java 9 新增)。这些操作主要用于对数据流进行截取、跳过或按顺序条件筛选,属于中间操作,返回新的流。
limit(long n):截取前 n 个元素n 个元素;若流中元素数量小于 n,则保留所有元素。n 个元素,就会停止处理后续元素(适合大流量场景优化)。示例:
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
// 截取前3个元素
numbers.stream()
.limit(3)
.forEach(System.out::print); // 输出:1 2 3skip(long n):跳过前 n 个元素n 个元素;若流中元素数量小于 n,则返回空流。skip 没有短路性,需要处理完前 n 个元素才能返回结果(对于大 n 可能效率较低)。示例:
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
// 跳过前2个元素,保留剩余元素
numbers.stream()
.skip(2)
.forEach(System.out::print); // 输出:3 4 5组合使用 limit 和 skip(实现分页效果):
List<Integer> data = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
int pageSize = 3;
int pageNum = 2; // 第2页(从0开始或1开始需注意)
// 跳过前 (pageNum-1)*pageSize 个元素,再取 pageSize 个元素(模拟第2页)
data.stream()
.skip((pageNum - 1) * pageSize) // 跳过前3个(1,2,3)
.limit(pageSize) // 取接下来3个(4,5,6)
.forEach(System.out::print); // 输出:4 5 6takeWhile(Predicate<T>)(Java 9+):按顺序保留满足条件的元素,直到不满足为止示例:
List<Integer> numbers = Arrays.asList(2, 4, 6, 7, 8, 10);
// 保留连续的偶数,直到遇到第一个奇数(7)为止
numbers.stream()
.takeWhile(n -> n % 2 == 0)
.forEach(System.out::print); // 输出:2 4 6(7及之后的8、10被丢弃)dropWhile(Predicate<T>)(Java 9+):按顺序丢弃满足条件的元素,直到不满足为止示例:
List<Integer> numbers = Arrays.asList(2, 4, 6, 7, 8, 10);
// 丢弃连续的偶数,直到遇到第一个奇数(7),保留7及后续所有元素
numbers.stream()
.dropWhile(n -> n % 2 == 0)
.forEach(System.out::print); // 输出:7 8 10操作 | 作用 | 关键特点 |
|---|---|---|
filter | 保留所有满足条件的元素 | 遍历所有元素,不依赖顺序 |
distinct | 去除重复元素(基于 equals) | 需遍历所有元素,可能影响性能 |
limit(n) | 截取前 n 个元素 | 短路性,适合大流量截取 |
skip(n) | 跳过前 n 个元素 | 无短路性,需处理完前 n 个元素 |
takeWhile(pred) | 保留连续满足条件的元素,直到不满足 | 依赖顺序(有序流),短路性 |
dropWhile(pred) | 丢弃连续满足条件的元素,直到不满足 | 依赖顺序(有序流),找到第一个不满足即停止 |
这些操作可单独或组合使用,例如 skip + limit 实现分页,takeWhile 处理有序数据的前缀筛选等,灵活满足各种数据流切片需求。