stream流

 Stream()的操作:

package com.example.stream;/*
 * Copyright 2013- Smartdot Technologies Co., Ltd. All rights reserved.
 * SMARTDOT PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 *
 */


import org.apache.ibatis.logging.stdout.StdOutImpl;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import sun.rmi.transport.StreamRemoteCall;

import javax.print.DocFlavor;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author
 * @description
 * @since 2021/3/26 11:18
 */
@SpringBootApplication
public class main {

    public static void main(String[] args) {
        List<String> list=new ArrayList<>();
        for(int i=0;i<10;i++){
            list.add(String.valueOf(i));
        }
        //获取一个顺序流
        Stream<String> stream=list.stream();
        //获取一个并行流
        Stream<String> parallelStream=list.parallelStream();

        //使用arrays中的stream()方法,将数据转换成流
        Integer[] nums=new Integer[10];
        Stream<Integer>stream1= Arrays.stream(nums);

        /**
         * stream的静态方法: of(),iterate(),generate()
         */
        Stream<Integer> stream2=Stream.of(1,2,3,4);
        //初始值为 0 , 通过迭代函数,生成一个流,迭代次数为3
        Stream<Integer> stream3=Stream.iterate(0,(x) ->x+2).limit(3);
        stream3.forEach(System.out::println);
         //流generate(Supplier s)返回无限顺序无序流,其中每个元素由提供的供应商生成。这适用于生成恒定流,随机元素流等。
        Stream<Double> stream4=Stream.generate(Math::random).limit(3);
        stream4.forEach(System.out::println);
        //等价于:
        Stream<Double> stream5;
        Stream.generate(new Random()::nextDouble).limit(3).forEach(System.out::println);

        /**
         * 除了直接创建并行流,还可以通过parallel()把顺序流转换成并行流
         */
        Optional<Integer> findFirst=list.stream().parallel().filter(each->each>4).findFirst();

        //无状态操作
        /**
         * filter :筛选,是按照一定的规则校验流中的元素,将符合条件的元素提取到新的流中的操作
         */
        List<Integer> listfilter=Arrays.asList(3,6,7,8);
        Stream<Integer> stream6=listfilter.stream();
        stream6.filter(x->x>5).forEach(System.out::println);
        /**
         * 映射(map,flatMap,peek)
         */
        /**
         * ①map:一个元素类型为 T 的流转换成元素类型为 R 的流,这个方法传入一个Function的函数式接口,
         * 接收一个泛型T,返回泛型R,map函数的定义,返回的流,表示的泛型是R对象;
         *
         *
         * 简言之:将集合中的元素A转换成想要得到的B
         */


        /**
         * flatMap:接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流。
         *
         * 简言之:与Map功能类似,区别在于将结合A的流转换成B流
         *
         */

        /**
         * peek: ③peek:peek 操作接收的是一个 Consumer<T> 函数。顾名思义 peek 操作会按照 Consumer<T>
         *     函数提供的逻辑去消费流中的每一个元素,同时有可能改变元素内部的一些属性。
         */
        //你会发现执行之后没有输出任何字符串?
        Stream<String> stream7=Stream.of("hello","felord.cn");
        stream7.peek(System.out::println).collect(Collectors.toList());
        /**
         * 这是因为流的生命周期有三个阶段
         *
         * 起始生成阶段。
         *
         * 中间操作会逐一获取元素并进行处理。可有可无。所有中间操作都是惰性的,因此,流在管道中流动之前,任何操作都不会产生任何影响。
         *
         * 终端操作。通常分为 最终的消费 (foreach 之类的)和 归纳 (collect)两类。还有重要的一点就是终端操作启动了流在管道中的流动。
         *
         */
        //因此我们改为如下即可:
//        Stream<String> stream7=Stream.of("hello","felord.cn");
//        stream7.peek(System.out::println).collect(Collectors.toList());
        //有状态 stateful 操作
        // distinct: 返回由该流的不同元素组成的流(去重)  distinct 使用hashCode 和 equals
        Stream<String> stream8=Stream.of("1","3","34","4");
        stream8.distinct().forEach(System.out::println);
        stream8.sorted().distinct().forEach(System.out::println);

//        limit:获取流中n个元素的返回流
         Stream<Integer> stream9=Stream.of(3,20,39,8,9);
         stream.limit(3).forEach(System.out::println);

        /**
         * skip :在丢失流的第n个元素之后,返回由该流的其余元素组成的流
         *
         */
        Stream<Integer> stream10=Stream.of(3,40,30,4,3);
        stream10.skip(3).forEach(System.out::println);

        /**
         * anyMatch: Steam中只要有一个元素符合传入的值就返回true
         *
         * allMatch: stream中要全部符合传入的值才会返回true
         *
         * noneMatch: stream 中没有一个符合传入的值就会返回true
         */
        Stream<Integer> stream11=Stream.of(3,4,3,4,32,44,3);
        System.out.println("result="+stream11.anyMatch(s->s==3));
        //输入 result=true

        /**
         * findFirst 用于返回满足条件的第一个元素
         */
        Stream<Integer> stream12=Stream.of(3,4,30,4,35,43);
        System.out.println(stream12.findFirst().get());
        //输出: 3
        //还可以结合filter进行处理
        System.out.println("result="+stream12.filter(s-> s > 3).findFirst().get());


        /**
         * forEach 该方法接收一个Lambda表达式,然后在Stream的每一个元素上执行该表达式
         */
        List<String> strList=Arrays.asList("12","3","jark","aray","ark");
        strList.stream().forEach(s->{
            if("jark".equalsIgnoreCase(s)){
                System.out.println(s);
            }
        });
        //输出结果为 jark
        String aa="jark";
        strList.stream().forEach(s->{
            if(aa.equalsIgnoreCase(s)){
                System.out.println(s);
            }
        });


    }
}

特点:

使用stream接口从此告别for循环

流程

第一步:把集合转换为流stream

第二步:操作stream流

第三步:stream流在管道中经过中间操作的处理,最后由最终操作得到前面处理的结束

操作符:

两种: 中间操作符,终止操作符

 

map和flatMap的区别:

map:对流中每一个元素进行处理

flatMap: 流扁平化,把一个流中的“每个值”都换成另外一个流,然后把所有的流连接起来称为另外一个流

 

看源码应该就能看出来区别了吧

map函数式接口抽象方法的返回值是R,flatMap函数式接口抽象方法返回值是Stream< R >

所以flatMap作用就是将返回的Stream< R >拆开,再组合每个值成新的Stream< R >

@Test
    public void test2() {
        Student[] students = new Student[] { new Student("a.a", 1), new Student("b.b", 2),
                new Student("c.c", 3), new Student("d.d", 4), new Student("e.e", 5) };
        // Stream流中间操作---映射map
        Arrays.asList(students).stream().map(Student::getName).forEach(System.out::println);
        System.out.println("*********************************");
        // 比较区别,map(s->s.split("\\."))收集之后的结果是Stream<String[]>
        Arrays.asList(students).stream().map(Student::getName).map(s->s.split("\\.")).forEach(arr-> System.out.println(Arrays.toString(arr)));
        System.out.println("*********************************");
        // Stream流中间操作---扁平化映射flatmap,看源码可以发现,Function函数式接口的第二个参数是Stream<? extends R>
        // 也即,lambda表达式的返回值是Stream<? extends R>类型
        // 那作用也就显而易见了,把每个返回值的Stream,再一个个拆开,最后综合所有的变成一个新的Stream
        Arrays.asList(students).stream().map(Student::getName).flatMap(s->Arrays.stream(s.split("\\."))).forEach(System.out::println);
    }

中间操作:

/**
     * filter: 过滤不合符条件的
     */
    @Test
    public void filter(){
        List<String> strings= Arrays.asList("a","b","fc");
        //将集合转化为流
        //创建的是串行流 collect(Collectors.toList()) 将流转换成集合
        List<String> filter=strings.stream().filter(str->str.contains("f")).collect(Collectors.toList());
        System.out.println(filter);
        //从这步可以看出中间操作符返回的是流
        Stream<String> d = strings.stream().filter(str -> strings.contains("d"));
        //创建的是并行流
        strings.parallelStream();
    }


    /**
     * distinct 去重
     */
    @Test
    public void distinct(){
        List<String> strings= Arrays.asList("b","b","c","3");
        Stream<String> distinctd = strings.stream().distinct();
        System.out.println(distinctd);

    }

    /**
     * 会返回一个不超过给定长度的流
     */
    @Test
    public void limit(){
        List<String> strings= Arrays.asList("b","b","c","3");
        List<String> limited = strings.stream().limit(3).collect(Collectors.toList());
        System.out.println(limited);
    }

    /**
     * 获取流中除掉前面的n个元素的其他所有元素
     */
    @Test
    public void skip(){
        List<String> strings= Arrays.asList("b","b","c","3");
        List<String> sout = strings.stream().skip(3).collect(Collectors.toList());
        System.out.println(sout);  //3
    }
    /**
     * 接受一个函数作为参数,这个函数会被应用到每个元素上,并将其映射成一个新的元素
     */

    @Test
    public void map(){
        List<String> strings= Arrays.asList("b","b","c","3");
        List<String> collect = strings.stream().map(str ->{
            str.concat("it-heyufu");
            return "a";
                }
        ).collect(Collectors.toList());
        List<String> collect1 = strings.stream().map(str -> str + "abc").collect(Collectors.toList());
        System.out.println(collect);
        System.out.println(collect1);
        //结果: [bit-heyufu, bit-heyufu, cit-heyufu, 3it-heyufu]
    }

    @Test
    public void map2flatmap(){
        List<String> strings= Arrays.asList("bd","bc","cc","3");
        Stream<String> objectStream = strings.stream().flatMap(str -> this.getchar(str));
        List<String> collect = objectStream.collect(Collectors.toList());
        collect.forEach(System.out::println);
        //_____>等价于
        collect.forEach(s-> System.out.println(s));

        /**
         * 解析flatmap
         *  扁平化处理
         */
        System.out.println(collect);
        List<String> stringa= Arrays.asList("bd","bc","cc","3");
        Stream<Stream<String>> streamStream = stringa.stream().map(str -> this.getchar(str));

    }

    /**
     * 功能: 将字符串转换为流
     * @param a
     * @return
     */
    public static Stream<String> getchar(String a){
        List<String> list=Arrays.asList(a);
        Stream<String> stream = list.stream();
        return stream;
    }

    @Test
    public void storted(){
        List<String> strings= Arrays.asList("bd","bc","cc","3");
        List<String> collect = strings.stream().sorted().collect(Collectors.toList());
        System.out.println(collect);
    }

终止操作符

@Test
    public void collect(){
        List<String> list=Arrays.asList("d","abc","bbb","ddd","bbb","abce");
        //set的形式是有去重的作用
        Set<String> collect = list.stream().collect(Collectors.toSet());
        System.out.println(collect);

    }

    /**
     *  reduce 可以将流中的元素反复结合起来得到一个结果
     */
    @Test
    public void reduce(){
        List<String> list=Arrays.asList("d","abc","bbb","ddd","bbb","abce");
        Optional<String> reduce = list.stream().reduce((acc, item) -> {
            return acc + item;
        });
        if(reduce.isPresent()) System.out.println(reduce.get());

    }

    /**
     * 功能描述: 获取集合中元素数量
     */
    @Test
    public void count(){
        List<String> list=Arrays.asList("d","abc","bbb","ddd","bbb","abce");
        long count = list.stream().count();
        System.out.println(count);
    }

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值