IntStream i = IntStream.of(1,2,3,4);
i.forEach(System.out::println);<!--forEach输入Consumer-->
i.forEach(System.out::println);<!--报错,stream has already been operated upon or closed-->
Collection接口使用的迭代,比如for-each,叫做外部迭代。流则是内部迭代,你只要告诉它干什么就行了。外部迭代你可以看到每一次迭代,而内部迭代你看不到,流帮你做了。
2.流操作
anyMatch方法参数为Predicate。返回一个boolean值,表示流中是否有元素满足Predicate。
List<Integer> list = Arrays.asList(1,2,3,4,2,3);
boolean result = list.stream().anyMatch(i->i==2);
allMatch方法与anyMatch差不多,表示所有的元素都满足才返回true。noneMatch方法表示没有元素满足。
这三个操作都是短路操作。短路操作就是不需要遍历所有的元素就能得到结果。就可&&和||操作符一样。limit方法就是一个短路操作。
findAny方法,没有参数,表示返回随机的一个元素。返回一个Optional,因为有可能元素不存在。
List<Integer> list = Arrays.asList(1,2,3,4,2,3);
Optional<Integer> result = list.stream().findAny();
System.out.println(result.orElse(0));
findFirst方法,没有参数,返回第一个元素。返回Optional。
3.5归约
流的reduce操作就是将流中的元素结合得到一个值。根据reduce方法中的操作,两两结合得到一个值,然后跟下一个元素结合,就这样一直到最后一个元素,得到最终的值。
List<Integer> list = Arrays.asList(1,2,3,4,2,3);
Optional<Integer> sum = list.stream().reduce(Integer::sum);<!--reduce可以指定初始值-->
Optional<Integer> max = list.stream().reduce(Integer::max);
Optional<Integer> min = list.stream().reduce(Integer::min);
流还有max和min方法,参数为Comparator。
List<Integer> list = Arrays.asList(1,2,3,4,2,3);
Optional<Integer> max = list.stream().max(comparing(Integer::intValue));
Optional<Integer> min = list.stream().min(comparing(Integer::intValue));
3.6数值流
上面讲的操作如Stream<Integer>会有装箱拆箱的操作。Stream中有IntStream、 DoubleStream和
LongStream分别表示流中的元素为int,double,long,这样可以避免装箱拆箱。
mapToInt、 mapToDouble和mapToLong着三个方法可以将Stream<T>转为数值流。数值流中有max,min,sum,average等方法。
List<A> list = Arrays.asList(new A(1),new A(5),new A(3));
int sum = list.stream().mapToInt(a->a.getNum()).sum();
OptionalInt max = list.stream().mapToInt(a->a.getNum()).max();
OptionalInt min = list.stream().mapToInt(a->a.getNum()).min();
OptionalDouble ave = list.stream().mapToInt(a->a.getNum()).average();
boxed() 方法可以将数值流转为对象流。
List<A> list = Arrays.asList(new A(1),new A(5),new A(3));
Stream<Integer> i = list.stream().mapToInt(a->a.getNum()).boxed();
IntStream和LongStream的静态方法,帮助生成这种范围:range和rangeClosed。这两个方法都是第一个参数接受起始值,第二个参数接受结束值。但range是不包含结束值的,而rangeClosed则包含结束值。
IntStream.range(1, 100).filter(i->i%2==0).count();