一、方法demo
generate(),通过Supplier生成一个Stream对象:
public static void main(String[] args) {Stream<String> stream = Stream.generate(UUID.randomUUID()::toString);stream.findFirst().ifPresent(System.out::println);}
执行结果:d1907a2a-3d5e-4c91-bb40-8a219cd97529
findFirst()为什么这个方法返回的是一个Optional?Optional是为了防止Null,如果流中没有元素,就会找不到元素,因此是为了规避空指针异常。
iterate(),这个方法有两个参数,一个参数是seed,一个参数是UnaryOperate(继承了Fuction),会返回一个无限的、串型的、有序的Stream,并且会对seed不断应用第二个参数位置上的函数。
对1不断应用item+2的函数,并且由于产生的是一个无限流,所以要对流加以限制,使用limit限制数量为5个。
public static void main(String[] args) {Stream.iterate(1,item->item + 2).limit(5).forEach(System.out::println);}
执行结果:1 3 5 7 9
empty(),生成一个空的Stream。
public static void main(String[] args) {Stream<String> stream = Stream.empty();stream.findFirst().ifPresent(System.out::println);}
没有结果,因为这是一个空的流。
综合例子,找出该流中大于2的元素,将每个元素乘2,忽略前两个元素,再取前两个元素,求出流中元素的和:
public static void main(String[] args) {Stream<Integer> stream = Stream.iterate(1, item -> item + 2).limit(6);//mapToInt()能避免自动拆箱和装箱,提高性能System.out.println(stream.filter(item->item>2).mapToInt(item->item*2).skip(2).limit(2).sum());}
执行结果:32
求上面例子的最大值:
public static void main(String[] args) {Stream<Integer> stream = Stream.iterate(1, item -> item + 2).limit(6);stream.filter(item -> item > 2).mapToInt(item -> item * 2).skip(2).limit(2).max().ifPresent(System.out::println);}
执行结果:18
求上面例子的最小值:
public static void main(String[] args) {Stream<Integer> stream = Stream.iterate(1, item -> item + 2).limit(6);stream.filter(item -> item > 2).mapToInt(item -> item * 2).skip(2).limit(2).min().ifPresent(System.out::println);}
执行结果:14
同时对上面的例子求最大值、最小值和总和:
public static void main(String[] args) {Stream<Integer> stream = Stream.iterate(1, item -> item + 2).limit(6);IntSummaryStatistics summaryStatistics =stream.filter(item -> item > 2).mapToInt(item -> item * 2).skip(2).limit(2).summaryStatistics();System.out.println(summaryStatistics.getMax());System.out.println(summaryStatistics.getMin());System.out.println(summaryStatistics.getSum());}
执行结果:18 14 32
public static void main(String[] args) {Stream<Integer> stream = Stream.iterate(1, item -> item + 2).limit(6);System.out.println(stream);//打印出流对象System.out.println(stream.filter(item -> item > 2));//打印返回新的流对象//这里没有关闭流,但是重复使用了。已经对流进行了filter,又对相同的流进行了distinctSystem.out.println(stream.distinct());}
在distinct()出报错了,这是因为一旦流被操作了,就不能重复的再去使用这个流。流一旦被关闭了,也不能重复的使用。之前的例子中的stream都是调用其某个方法返回的新的流。
解决办法:
public static void main(String[] args) {Stream<Integer> stream = Stream.iterate(1, item -> item + 2).limit(6);System.out.println(stream);Stream<Integer>stream1 = stream.filter(item->item>2);System.out.println(stream1);Stream<Integer>stream2 = stream1.distinct();System.out.println(stream2);}
二、内部迭代与外部迭代
外部迭代:for循环的方式。外部迭代是通过for循环和自己的代码对集合进行操作。
内部迭代:stream的方式。操作的不是集合了,而是集合转为的stream,自己的代码不是和流分开的,而是融合在一起。
流的原理:stream内部有一个集合,存放的是针对流内每一个元素的操作,只有一个循环,对每一个元素都同时应用不同的操作。只有一次循环。

集合和流的关注点区别:集合关注的是数据和数据存储:流关注的是对数据的计算。




