1.概述
Stream 作为 Java 8 的一大亮点,它与 java.io 包里的 InputStream 和 OutputStream 是完全不同的概念。Java 8 中的 Stream 是对集合(Collection)对象功能的增强,它专注于对集合对象进行各种非常便利、高效的聚合操作,或者大批量数据操作。
2.应用场景
在当今这个数据爆炸的时代,数据来源多样化、数据海量化,很多时候不得不脱离 RDBMS,以底层返回的数据为基础进行更上层的数据统计。而原有 Java 的集合 API 中,仅仅有极少量的辅助型方法,更多的时候是程序员需要用 Iterator 来遍历集合,然后完成相关的聚合应用逻辑。这是一种远不够高效而且相对比较笨拙的方法。在JDK8中使用 Stream 对象,不仅丰富了在业务层面对数据处理的方式,还可以让代码更加简洁、易读和高效。
3.快速入门分析
我们在使用Stream对象时,一般会按照如下为三个步骤进行操作:
- 第一步:创建Stream流对象。
- 第二步:Stream流中间操作。
- 第三步:Stream流终止操作。
Stream对象的操作过程,可通过下面的图进行进一步分析。
Steam对象简易应用,代码如下:
List<Integer> list = Arrays.asList(3, 2, 12, 5, 6, 11, 13);
long count = list.stream()
.filter(i -> i % 2 == 0)
.count();
System.out.println(count);
4.应用案例增强分析
4.1Stream对象创建
Stream对象的创建,常见方式有如下几种:
- 借助Collection接口中的stream()或parallelStream()方法
- 借助Arrays类中的stream(...)方法
- 借助Stream类中的of(...)方法。
- 借助Stream类中的iterator和generator方法(无限操作)
Stream对象创建,案例分析如下:
Collection<Integer> col=new ArrayList<>();
...
Stream<Integer> s1=col.stream();
Stream<Integer> s2=col.parallelStream();
IntStream s3=Arrays.stream(new int[] {1,2,3,4});
Stream<Integer> s4=Stream.of(10,20,30,40);
Stream<Integer> s5=Stream.iterate(2, (x)->x+2);
s5.forEach(System.out::println);
Stream<Double> s6=Stream.generate(()->Math.random());
s6.forEach(System.out::println);
4.2Stream中间操作
Stream 对象创建以后可以基于业务执行一些中间操作,但这些操作的结果需要借助终止操作进行输出,案例分析如下:
初始条件:给定list集合作为Stream操作的对象,代码如下:
List<Integer> list=Arrays.asList(100,101,102,200);
对数据进行过滤:
//输出集合中所有的偶数
//1.创建流
Stream<Integer> s1=list.stream();
//2.中间操作(过滤)
Stream<Integer> s2=s1.filter((n)->n%2==0);
//3.终止操作
s2.forEach(System.out::println);
//也可以将多个操作合在一起
list.stream().filter(n->n%2==0).forEach(System.out::println);
限定操作(limit)
list.stream().filter(n->n%2==0).limit(2).forEach(System.out::println);
跳过操作(skip)
list.stream().filter(n->n%2==0).skip(2).forEach(System.out::println);
去重操作(distinct)
list.stream().distinct().forEach(System.out::println);
排序操作(sorted):底层基于内部比较器Comparable或外部Comparator比较器进行比对
list.stream().sorted().forEach(System.out::println);
list.stream().sorted((s1,s2)->{//Comparator
return s1-s2;
}).forEach(System.out::println);
映射操作(map)
List<String> list=Arrays.asList("a","bc","def");
list.stream().map((x)->x.toUpperCase()).forEach(System.out::println);
list.stream().map((x)->x.length()).forEach(System.out::println);
4.3Stream终止操作
Stream终止操作是Stream的结束操作,案例分析如下:
初始条件定义,给定一个list集合:
List<Integer> list=Arrays.asList(10,11,12,13,14,15);
match操作
boolean flag=list.stream().allMatch((x)->x%2==0);
System.out.println(flag);
flag=list.stream().anyMatch((x)->x%2==0);
System.out.println(flag);
flag=list.stream().noneMatch((x)->x>20);
System.out.println(flag);
find操作
Optional<Integer> optional=list.stream().sorted().findFirst();
System.out.println(optional.get());
optional=list.parallelStream().filter((x)->x%2!=0).findAny();
System.out.println(optional.get());
count操作
long count=list.stream().count();
System.out.println(count);
求最大,最小值
optional=list.stream().max((x,y)->{return x-y;});
System.out.println(optional.get());
optional=list.stream().min((x,y)->{return x-y;});
System.out.println(optional.get());
forEach迭代操作
list.stream().forEach(System.out::println);
Reduce(规约)操作
//计算集合中所有元素的和,其中第一个参数0为初始值,然后与后面每个值累加
Integer sum=list.stream().reduce(0,(x,y)->{return x+y;});
System.out.println(sum);
Collector(收集)操作
List<Integer> result=
list.stream().map(x->x*2).collect(Collectors.toList());
System.out.println(result);
list.stream().map(x->x*2).collect(Collectors.toSet());
System.out.println(result);
double avg=
list.stream().collect(Collectors.averagingDouble(x->x));
System.out.println(avg);
Optional<Integer> max=
list.stream().collect(Collectors.maxBy((x,y)->{return x-y;}));
System.out.println(max.get());
Map<Object,List<Integer>> map=
list.stream().collect(Collectors.groupingBy(x->x%2==0));
System.out.println(map);