Stream是Java8最常用且比较突出的特性,它可以协助你对集合或者数组等“容器”进行非常复杂的查找、过滤和数据映射等操作。
利用Stream完成上述操作需要经历创建流、针对数据流的中间操作和终止操作三个步骤。
下面分别对这三个步骤中涉及的方法进行了总结。
创建Stream流
创建数据流的过程也就是通过数据源(集合、数组)得到流,以备后续操作。
//创建Stream方式一:通过集合@Testpublic void test1() {ArrayList<String> arrayList = new ArrayList<>();//此种方法得到顺序流Stream<String> stream = arrayList.stream();//返回一个并行流Stream<String> parallelStream = arrayList.parallelStream();}//创建Stream方式二:通过数组@Testpublic void test2() {int[] arr = {1, 2, 3, 4};IntStream arrStream = Arrays.stream(arr);}//创建Stream 方式三:通过Stream的of()@Testpublic void test3(){Stream<Integer> integerStream = Stream.of(1, 2, 3, 4);}
上述代码段中提供了三种创建流的方式,而在方式一中stream()方法生成的是顺序流,而parallelStream()生成并行流。
Stream中间操作
1-中间操作之过滤与筛选
@Testpublic void test4(){ArrayList<Integer> arrayList = new ArrayList<>();for (int i =0; i < 10; i++){arrayList.add(i);}//生成流Stream<Integer> stream = arrayList.stream();//filter--接受lambda表达式,从流中排除某些元素// 过滤出元素大于5的值并打印stream.filter(s -> s > 5).forEach(System.out :: println);//limit(n) --截断流,使其元素不超过给定数量arrayList.stream().limit(6).forEach(System.out::println);//skip(n)--跳过元素,n表示跳过元素的数量,若n大于总数,那么返回空流arrayList.stream().skip(5).forEach(System.out::println);//distinct()--去除流中重复的数据arrayList.add(1);//可以将重复的1去除arrayList.stream().distinct().forEach(System.out::println);}
上述代码片段总结了Stream流中的过滤与筛选操作。
filter()函数用来过滤不满足要求的元素;limit()表示截断并提取集合中的前n个元素;
skip()函数表示跳过集合中的前n个元素,返回集合中剩余的元素;distinct()函数表示去除集合中的重复元素。
2-中间操作之映射
@Testpublic void test5(){ArrayList<Integer> arrayList = new ArrayList<>();for (int i =0; i < 10; i++){arrayList.add(i);}//生成流Stream<Integer> stream = arrayList.stream();//map--接收一个函数,将流中的每个元素经过函数的映射转换为一个新的元素// 将集合中的每个元素值都减1stream.map(s -> s -1 ).forEach(System.out :: println);//flatmap--接收一个函数作为参数,将流中的每个参数都换成另外一个流,然后再把这些流串成一个流返回Stream<Integer> stream1 = arrayList.stream().flatMap(StreamAPITest::changeElmToStream);stream1.forEach(System.out::println);}public static Stream<Integer> changeElmToStream(Integer i){ArrayList list = new ArrayList();list.add(i);return list.stream();}
在中间操作之映射操作中,我们介绍了两种方法分别是map()和flatMap(),这两种方法的区别是map()方法只能处理一个集合生成的流,而flatMap()方法可以处理流中包含流的情况。
上述代码片段中调用StreamAPITest::changeElmToStream方法引用将原集合中的元素都作为一个流返回,这样就形成了一条流中包含了很多流的情况,而flatMap接受这些流之后会有一个类似于合并的操作,也就是将这些流串成一条流并返回。
3-中间操作之排序
@Testpublic void test06(){//sorted()--自然排序List<Integer> integerList = Arrays.asList(12, 98, 20, 63, 78);integerList.stream().sorted().forEach(System.out :: println);}
sorted()函数是对集合中的元素进行排序。
终止操作
1-终止操作之匹配与查找
@Testpublic void test07(){ArrayList<Integer> arrayList = new ArrayList<>();for (int i =0; i < 10; i++){arrayList.add(i);}//生成流Stream<Integer> stream = arrayList.stream();//allMatch(Predicate p)--检查是否匹配所有元素。boolean allMatch = stream.allMatch(e -> e > 0);System.out.println(allMatch);//结果返回的是false//anyMatch(Predicate p)--检查是否存在某个元素符合条件。boolean anyMatch = arrayList.stream().anyMatch(e -> e > 0);System.out.println(anyMatch);//返回结果为true//noneMatch(Predicate p)--检查是否没有匹配的元素boolean noneMatch = arrayList.stream().noneMatch(e -> e < 0);System.out.println(noneMatch);//返回结果为true表示集合里没有小于0的元素//findFirst()--查找第一个元素Optional<Integer> first = arrayList.stream().findFirst();System.out.println(first);//findAny()--返回集合中的任意一个元素Optional<Integer> any = arrayList.stream().findAny();System.out.println(any);}
上述代码片段中,allMatch(Predicate p)方法用于检查集合中的每个元素是否都符合p规则,都符合则返回true;
类似的anyMatch(Predicate p)用于判断是否存在某个元素符合p规则;
noneMatch(Predicate p)表示是否存在没有符合p规则的元素;findFirst()方法返回集合中第一个元素;
2-终止操作之返回元素中的个数及最值
@Testpublic void test08(){ArrayList<Integer> arrayList = new ArrayList<>();for (int i =0; i < 10; i++){arrayList.add(i);}//生成流Stream<Integer> stream = arrayList.stream();//count--返回流中的元素个数long count = stream.count();System.out.println(count);//max(Comparator c)--返回集合中的最大值Optional<Integer> max = arrayList.stream().max(Integer::compareTo);System.out.println(max);//min(Comparator c)--返回集合中的最小值Optional<Integer> min = arrayList.stream().min(Integer::compareTo);System.out.println(min);//forEach(Consumer c)--内部迭代arrayList.stream().forEach(System.out::println);}
3-终止操作之归约
@Testpublic void test09(){ArrayList<Integer> arrayList = new ArrayList<>();for (int i =0; i < 10; i++){arrayList.add(i);}//生成流Stream<Integer> stream = arrayList.stream();//reduce(BinaryOperator)//可以将流中元素结合起来,得到一个值Optional<Integer> reduce = stream.reduce(Integer::sum);System.out.println(reduce);}
上述代码段中,reduce()方法中调用求和方法,并将求和的值作为结果返回。
4-终止操作之收集
@Testpublic void test10(){ArrayList<Integer> arrayList = new ArrayList<>();for (int i =0; i < 10; i++){arrayList.add(i);}//生成流Stream<Integer> stream = arrayList.stream();//collect(Collect c) --将流转换为其他形式。接收一个Collector接口的实现,用于//查找集合中值大于5的数,并将其放在list中返回List<Integer> integerList = stream.filter(e -> e > 5).collect(Collectors.toList());System.out.println(integerList);}




