Stream流

Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象。

这种风格将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选, 排序,聚合等。

元素流在管道中经过中间操作(intermediate operation)的处理,最后由最终操作(terminal operation)得到前面处理的结果。

特点:

        1 . 不是数据结构,不会保存数据。

        2. 不会修改原来的数据源,它会将操作后的数据保存到另外一个对象中。(peek方法可以修改流中的元素)

        3. 惰性求值,流在中间处理过程中,只是对操作进行了记录,并不会立即执行,需要等到执行终止操作的时候才会进行实际的计算。

Stream的操作符大体上分为两种:中间操作符和终止操作符。

Stream分类

中间操作

(intermediate operation)

有状态

(stateful)

distinct()、sorted()、limit(long maxSize)、skip(long n)

无状态

(stateless)

 
filter()、map()、mapToInt()、mapToLong()、mapToDouble()、
flatMap()、flatMapToInt()、flatMapToLong()、flatMapToDouble()、

结束操作

(terminal operation)

短路

(short-circuiting)

 

 
anyMatch()、allMatch()、noneMatch()、findFirst()、findAny()

非短路

(non short-circuiting)

 
forEach()、forEachOrdered()、toArray()、reduce()、
collect()、count()、max()、min()
 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

具体用法

public class Stream_example {

    public static void main(String[] args) {
        List<Integer> numList = Arrays.asList(-2,1,2,4,3,3,5);
        List<Integer> twoList = Arrays.asList(7,8,9,11);

        /***************Intermediate中间操作*****************/
        //sorted排序:默认升序,降序,自定义升降序
        numList.stream().sorted().forEach(System.out::println);
        numList.stream().sorted(Comparator.reverseOrder()).forEach(System.out::println);
        numList.stream().sorted(Comparator.comparing(Integer::intValue).reversed()).forEach(System.out::println);
        numList.stream().sorted((o1, o2) -> {
            if (o1.getName().equals(o2.getName())) {
                return o1.getAge() - o2.getAge();
            } else {
                return o1.getName().compareTo(o2.getName());
            }
        });

        //filter:按条件过滤元素
        numList.stream().filter(e -> e > 2).forEach(System.out::println);
        numList.stream().filter(Objects::nonNull).forEach(System.out::println);

        //distinct:去重
        numList.stream().distinct().forEach(System.out::println);

        //skip:跳过前n个元素
        numList.stream().skip(2).forEach(System.out::println);

        //limit:截取前n个元素
        numList.stream().limit(14).forEach(System.out::println);

        //map、mapToInt、mapToLong、mapToDouble、mapToObj:每个元素遍历执行
        numList.stream().mapToDouble(e -> e * 2).forEach(System.out::println);
        numList.stream().map(e -> new Function<Integer, Long>() {
            @Override
            public Long apply(Integer i) {
                return i * 3L;
            }
        }).forEach(System.out::println);

        //flatMap:将多个流合并压缩成一个流
        Stream.of(numList, twoList).flatMap(e -> e.stream()).forEach(System.out::println);
        Stream.of(numList, twoList).flatMap(Collection::stream).forEach(System.out::println);

        //concat: 流拼接
        Stream.concat(numList.stream(), twoList.stream());

        //peek:可查看流中的元素,用于调试,如同于map,peek接收的是Consumer表达式,没有返回值
        numList.stream().filter(e -> e > 2).peek(e -> System.out.println("Filtered value: " + e)).forEach(System.out::println);
        numList.stream().peek(e -> e.setAge(100)).forEach(System.out::println);

        //parallelStream:并行流,无序,线程不安全;基于fork/join框架
        numList.parallelStream().forEach(System.out::println);

        //sequential:将并行流转成串行流
        numList.parallelStream().filter(e -> e > 2).sequential().forEach(System.out::println);

        //parallel:将串行流转成并行流
        numList.stream().filter(e -> e > 2).parallel().forEach(System.out::println);

        /*************terminal operation.终端操作*****************/
        //forEach:遍历每个元素,forEachOrdered常用于并行流
        numList.stream().forEach(System.out::println);
        numList.stream().forEachOrdered(System.out::println);

        //toArray:返回包含此流元素的数组
        Object[] array = numList.stream().toArray();
        Integer[] integers = numList.stream().toArray(Integer[]::new);

        //collect:返回各种类型
        String s = numList.stream().map(x -> x + "").collect(Collectors.joining("|"));
        Long collect = numList.stream().collect(Collectors.counting());
        List<Integer> list = numList.stream().collect(Collectors.toList());
        ArrayList<Integer> arrayList = numList.stream().collect(Collectors.toCollection(ArrayList::new));
        LinkedList<Object> linkedList = numList.stream().collect(LinkedList::new, LinkedList::add, LinkedList::addAll);
        String sb = numList.stream().collect(StringBuilder::new, StringBuilder::append, StringBuilder::append).toString();
        HashMap<Object, Object> hashMap = numList.stream().collect(HashMap::new, (x, y) -> {
            x.put(y, y);
        }, HashMap::putAll);
        list.stream().map(Student::getAge).collect(Collectors.maxBy(Integer::compare)).get();//最大值
        list.stream().collect(Collectors.summingInt(Student::getAge));//总和
        list.stream().collect(Collectors.averagingDouble(Student::getAge));//平均值
        Map<Integer, List<Student>> ageMap = list.stream().collect(Collectors.groupingBy(Student::getAge));//分组
        Map<Integer, Map<Integer, List<Student>>> typeAgeMap = list.stream().collect(Collectors.groupingBy(Student::getType, Collectors.groupingBy(Student::getAge)));//多重分组
        Map<Boolean, List<Student>> partMap = list.stream().collect(Collectors.partitioningBy(v -> v.getAge() > 10));//分区,一部分大于10,一部分小于等于10


        //min:返回当前流中最小元素,max同理
        Integer integer = numList.stream().min(Integer::compareTo).get();
        Integer integer1 = numList.stream().min(Integer::compare).get();
        int min = numList.stream().mapToInt(i -> i).min().getAsInt();

        //count:统计条数
        long count = numList.stream().count();
        long sum = numList.stream().mapToLong(e -> 1L).sum();

        //allMatch:判断的条件里,所有元素匹配,才返回true
        //anyMatch:判断的条件里,任意一个元素匹配,才返回true
        //noneMatch:判断的条件里,所有元素都不匹配,才返回true
        boolean b = numList.stream().allMatch(x -> x>2);
        boolean b1 = numList.stream().anyMatch(x -> x > 2);
        boolean b2 = numList.stream().noneMatch(x -> x == 0);

        //findFirst:返回列表中的第一个元素
        //findAny:一般返回第一个结果,并行情况下不能确保是第一个
        //orElse:返回对象,如果没有,则返回x
        Integer inte = numList.parallelStream().findFirst().get();
        Integer inte1 = numList.stream().findAny().get();
        Integer inte2 = numList.stream().filter(e -> e > 2).findAny().orElse(null);

        //关联累加
        Integer reduce = numList.stream().reduce(Integer::sum).get();
        Integer reduce1 = numList.stream().reduce((a, c) -> a + c).get();
        Integer reduce2 = numList.stream().reduce(100, Integer::sum);
        Integer reduce3 = numList.stream().reduce(100, (a, c) -> a + c);
        Long reduce4 = numList.stream().reduce(100L, (a, c) -> a + c, (a, c) -> 0L);

        /***************short-circuiting terminal operation.短路操作*****************/
        //summaryStatistics:返回各种汇总数据
        IntSummaryStatistics summaryStatistics = numList.stream().mapToInt(e -> e).summaryStatistics();
        IntSummaryStatistics intSummaryStatistics = IntStream.of(4, 5, 6, 7).summaryStatistics();
        System.out.println(summaryStatistics.getMax());
        System.out.println(summaryStatistics.getMin());
        System.out.println(summaryStatistics.getSum());
        System.out.println(summaryStatistics.getAverage());
        System.out.println(summaryStatistics.getCount());


        /*************** 流重用 *****************/
        System.out.println("----------------------------------");
        Iterable<Integer> iterable = () -> IntStream.range(1, 10).map(i -> ++i).iterator();
        for (Integer item : iterable) {
            System.out.println(item);
        }

        System.out.println("-----------------无限流-----------------");
        IntStream naturalNumbers = IntStream.iterate(1, x -> x + 1);
        naturalNumbers.limit(5).forEach(System.out::println);

    }
}

 

posted @ 2020-10-12 18:01  柒月丶  阅读(199)  评论(0)    收藏  举报