好久不写了,今天看代码的时候发现有个同事在用新特性写出来的代码比我写出的代码简洁了好多。就是用Stream的3个新特性组合使用的,赶紧去研究了一下。好了,废话到此为止,上代码。
1、iterate的使用(final T seed, final UnaryOperator f)
作用:指定一个常量seed,生成从seed到常量f(由UnaryOperator返回的值得到)的流。根据起始值seed(0),每次生成一个指定递增值(n+1)的数,limit(5)用于截断流的长度,即只获取前5个元素。
public static void main(String[] args) {
List<Integer> collect1 = Stream.iterate(0, n -> n + 1).limit(3).collect(Collectors.toList());
System.out.println(collect1.toString());
Stream.iterate(0, n -> n + 1).limit(5).forEach(a -> {
System.out.println(a);
});
}
2、skip方法
用于跳过前面n个元素,然后再返回新的流,如图所示:
List<Integer> collect1 = Stream.of(1,2,3,4,5,6,7,8,9,10).skip(5).collect(Collectors.toList());
System.out.println(collect1.toString());
方法skip()的参数n的四种情况:
(1)当n<0时,抛IllegalArgumentException异常;
(2)当n=0时,相当没有跳过任何元素,原封不动、完璧归赵;
(3)当0<n<length时,跳过n个元素后,返回含有剩下的元素的流;
(4)当n>=length时,跳过所有元素,返回空流。
3、limit方法
它是用于限制流中元素的个数,即取前n个元素,返回新的流,如图所示:
List<Integer> collect1 = Stream.of(1, 2, 3, 4, 5, 6).limit(3).collect(Collectors.toList());
System.out.println(collect1.toString());
方法limit()的参数n的四种情况:
(1)当n<0时,抛IllegalArgumentException异常;
(2)当n=0时,不取元素,返回空流;
(3)当0<n<length时,取前n个元素,返回新的流;
(4)当n>=length时,取所有元素,原封不动、完璧归赵。
4、对无限流的操作
流Stream分为有限流和无限流,前面的例子我们都是使用的有限流,与Java集合类不同,流是可以无限的。对于无限流,skip()和limit()表现出了极大的差异,先上代码:
Stream.iterate(1, i -> i + 1)
.filter(num -> (num & (num - 1)) == 0)
.limit(10)
.forEach(System.out::println);
System.out.println("----------------");
Stream.iterate(1, i -> i + 1)
.filter(num -> (num & (num - 1)) == 0)
.skip(10)
.forEach(System.out::println);
上述代码的结果是:
通过limit()输出了前十个2的n次方值:
1, 2, 4, 8, 16, 32, 64, 128, 256, 512
而skip()跳过了前10个,继续输出,但会不断执行下去(会有int的溢出现象):
8388608
16777216
33554432
67108864
134217728
268435456
536870912
1073741824
-2147483648
…
执行后可以发现,limit()是可以将无限流转化为有限流的,所以我们也可以认为它是一个短路操作。而skip()则不行,不管你跳过了前面多少个元素,总还是会有源源不断的元素过来,无法收敛。
5组合使用
- 集合的subList方法
List<Integer> list = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9).collect(Collectors.toList());
System.out.println(list.subList(3, 7).toString());
List<Integer> result = list.stream()
.skip(3)
.limit(7 - 3)
.collect(Collectors.toList());
System.out.println(result.toString());
- 分页的应用
int pageSize = 10;
int pageIndex = 1;
List<Integer> list = Stream.iterate(0, n -> n + 1).limit(20)
.skip((pageIndex - 1) * pageSize)
.limit(pageSize).collect(Collectors.toList());
System.out.println(list.toString());
6、总结
1、本文介绍了Java 8的Stream接口中两个常用的方法:skip()和limit(),比较简单易懂,也介绍了怎么组合使用。需要注意的是,如果Stream过大或是无限流,小心skip()会有性能问题。
2、当心使用,因为代码简洁了很多,但是后人维护起来的时候很可能看不懂