Stream流

本文深入探讨Java Stream API,解释为何需要流,流与集合的区别,以及流的操作如过滤、映射、限制等。通过实例展示了如何从集合、数组生成流,以及中间操作和终端操作的使用,如reduce、collect等,强调了内部迭代和一次遍历原则。最后,通过示例展示了Stream在数据处理中的高效性和灵活性。
摘要由CSDN通过智能技术生成

Stream流

1、为什么需要 Stream?

首先:流就是从支持数据处理操作的源生成的元素序列

(1) 元素序列:和集合一样,流提供了一个接口,可以访问特定元素的一组有序值。因为集合时数据结构,所以它的主要目的是以特定的时间/空间复杂度储存和访问数据。但流的目的是表达计算。因此,集合讲的是数据,流讲的是计算
(2):流会从源中获取要处理的流,有序集合生成流时会保持原来的顺序。
(3)数据处理操作:对数据进行处理,包括过滤,排序,遍历等。流操作还可以顺序执行和并行执行。
(4)流水线:很多流操作会返回处理后的流,这样我们就可以将多个操作链接起来。
(5)内部迭代:流的迭代是在背后进行的,跟迭代器显式迭代不太一样。

2、 流和集合的区别

(1)什么时候进行读取和计算:
集合是一个内存中的数据结构,包含数据结构中目前所有的值,我们要先把所有的数据加载到集合中以后才可以对集合进行操作。就像我们我们用DVD看电影,包含电影的所有东西。要看必须要有完整的电影。
流则是在概念上的固定的数据结构,其元素则是按需计算。例如我们在网上看电影,只需要加载目前进度的后面几分钟的电影就行。这样做有很大的好处,就是只有在我们需要的时候才会加载值。

(2)流只能遍历一次:
流和迭代器一样只能遍历一次,或者说只能消费一次。如果我们对一个流消费两次,那么代码会抛出java.lang.IllegalStateException:流已被操作或关闭。除非我们从数据源那再获取一个流。于此相反,我们可以对集合进行任意次的操作。

(3)内部迭代和外部迭代:
我们使用集合或者迭代器的时候,需要我们自己去声明如何进行迭代,例如使用for循环或者是hasNext显性的去获取每一个元素,然后再在方法体中说明如何操作这些元素。这个就是外部迭代。对于流来说,你只需要申明对流进行什么操作。流会自动在内部对元素进行迭代。这就是内部迭代。

3、流的操作

java.util.stream.Stream中的Stream接口定义了很多操作。它们可以分成两大类:中间操作和终端操作。

1,Collection体系的集合可以使用默认方法 stream()生成流

       List<String> list = new ArrayList<>();
       Stream<String> stringStream =  list.stream();

       Set<String> set = new HashSet<>();
       Stream<String> stringStream1 = set.stream();

2, Map集合间接生成流

 Map<String,Integer> map  = new HashMap<>();
 Stream<String> keyStream = map.keySet().stream();
 Stream<Integer> valueStream = map.values().stream();
Stream<Map.Entry<String,Integer>> stream=map.entrySet().stream();

3、数组可以通过吧Stream接口的静态方法 of(T…values)[可变参数]生成流

String[] strings ={"小华","小崔","小帅"};
Stream<String> strArrStream =  Stream.of(strings);
Stream<String> stringStream2 = Stream.of("hello","word","java");
Stream<Integer> intArrStream = Stream.of(10,20,30);

4,数组工具类 Arrays.stream()

String[] strings1 ={"小","崔","帅"};
Stream<String> arraysStream = Arrays.stream(strings1);
System.out.println(arraysStream);

5 Stream流自己的静态方法 iterator() 和 generate()

Stream<Double> generate = Stream.generate(() -> (Math.random()));
Stream<Double> limit = generate.limit(10);
limit.forEach(s-> System.out.println(s));

在这里插入图片描述
中间操作

中间操作会返回一个新的流,例如从peopleList.stream()产生的流,在经过filter()以后,会产生一个新的流,给sorted()使用,在sorted()使用以后会产生一个流给map。这样不断的传递下去,就相当于工厂的流水线。还有很重要的一点,除非流水线触发一个终端操作,不然中间操作不会执行任何处理。因为中间操作能够合并起来,在终端操作时一次性全部处理。

        List<String> nameList2 = peopleList.stream()
                //过滤出年龄小于40的人
                .filter(people1 ->{System.out.println("filter:"+people1.getAge());
                    return people1.getAge()<40;} )
                //获取名称
                .map(people -> {
                    System.out.println("map"+people.getName());
                    return people.getName();
                })
                //直取前三个
                .limit(2)
                //返回结果
                .collect(Collectors.toList());

在这里插入图片描述
终端操作
终端操作会从流水线中生成结果。返回结果可以是List,Integer,甚至是void。
在这里插入图片描述

 Stream<String> stringStream =  Stream.of("a","m","c","u","e");
        String reduceString = stringStream.reduce("120", (str1, str2) -> str1 + str2);
        System.out.println(reduceString);//120amcue

        Stream<Integer>  integerStream = Stream.of(1,2,3,4,5,6);
        Integer reduceInteger = integerStream.reduce(100,(v1,v2)->v1+v2);
        System.out.println(reduceInteger);//121
 System.out.println("=====");
        Stream<String> stringStream5 = Stream.of("z","d","a","b","c");
        //计算元素个数 stringStream5使用这一次之后就不能再使用了
        Long collect = stringStream5.collect(Collectors.counting());
        System.out.println(collect);//5
        //拼接字符串  直接全部打印,不用循环遍历打印
        Stream<String> stringStream6 = Stream.of("z","d","a","b","c");
        String collect1 = stringStream6.collect(Collectors.joining());
        System.out.println(collect1);//zdabc

        //把流中的元素收集到lsit集合容器中
        Stream<String> stringStream7 = Stream.of("z","d","a","b","c");
        List<String> collect2 = stringStream7.collect(Collectors.toList());
        System.out.println(collect2);//[z, d, a, b, c]
        //把流中的元素收集到set集合容器中
        Stream<String> stringStream8 = Stream.of("z","d","a","b","c");
        Set<String> collect3 = stringStream8.collect(Collectors.toSet());
        System.out.println(collect3);//[a, b, c, d, z]

        Stream<String> stringStream9 = Stream.of("z","d","a","b","c");
        ArrayList<String> collect5 = stringStream9.collect(Collectors.toCollection(() -> new ArrayList<String>()));
        System.out.println(collect5);//[z, d, a, b, c]

System.out.println("+++++");
        Stream<Integer> stringStream10 = Stream.of(1,5,3,2,6);
        IntSummaryStatistics collect6 = stringStream10.collect(Collectors.summarizingInt(v -> v));
        System.out.println(collect6.getMax());
        System.out.println(collect6.getCount());
//6  5
/*分组*/
        ArrayList<Student> arrayList = new ArrayList<>();
        Student s1 = new Student("张三","男","#5",1);
        Student s2 = new Student("李二","男","#5",1);
        Student s3 = new Student("张五","女","#5",1);
        Student s5 = new Student("张6","男","#5",1);
        Student s6 = new Student("张9","女","#5",1);
        arrayList.add(s1);
        arrayList.add(s2);
        arrayList.add(s3);
        arrayList.add(s5);
        arrayList.add(s6);

        /*获取学生集合的Stream 流*/
        Stream<Student> studentStream = arrayList.stream();
        Map<String, List<Student>> collect4 = studentStream.collect(Collectors.groupingBy((stu) -> stu.getSex()));
        collect4.forEach((k,v)-> System.out.println(k+"======"+v));
/*女======[Stream.Student@c4437c4, Stream.Student@433c675d]
男======[Stream.Student@3f91beef, Stream.Student@1a6c5a9e, Stream.Student@37bba400]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值