• Stream


    目录

    一 函数式接口

    1 特点

    2 核心函数式接口

    1) Consumer

    2) Supplier

    3) Function

    4) Predicate

    5) 扩展:BiFunction

    二 Stream

    1 stream操作过程

    1) 中间操作

    2)终端操作

    2 创建Stream对象

    1) 通过集合获得Stream对象

    2) 其他

    3 终端操作

    forEach()

    count() , max() , min()

    collect()

    4 中间操作

    filter()

    map()

    sorted()

    limit() & skip()


    函数式接口

    1 特点

    • 接口中有且仅有一个抽方法

    • 可以使用lambda表达式

    • 可以使用@FunctionalInterface声明接口

    • 在函数式接口中,可以定义多个默认的非抽象方法

    2 核心函数式接口

    jdk中给我们提供了一些常用的函数式接口

    jdk1.8以前,就存在函数式特点接口 : Compartor ,Comparable

    jdk1.8以后,提供了一些常用的函数式接口,其中有4个核心接口

    1) Consumer

    消费型接口 ,传递参数,使用参数做一个处理。没有返回值 void accept(T t);

    1. Consumer mc = (String s1)->{
    2. System.out.println(s1.length());
    3. };
    4. mc.accept(s);
    5. //-------------------------------------------
    6. Consumer mc1 = (String s1)->{
    7. System.out.println(s1.length());
    8. };
    9. Consumer mc2 = (String s1)->{
    10. System.out.println(s1.toUpperCase());
    11. };
    12. Consumer mc3 = s1->{
    13. System.out.println(s1.substring(0,5));
    14. };
    15. //mc2.accept(s);
    16. //这是一个链式操作,先实现消费功能mc3,再实现消费功能mc2,最后实现消费功能mc1
    17. mc3.andThen(mc2.andThen(mc1)).accept(s);

    2) Supplier

    供给型接口, 无需要传递参数,返回对象 T get();

    1. //需要产生一个随机数
    2. //创建了一个对象 Object obj = new Object()
    3. Supplier s1 = ()->{
    4. Random r = new Random();
    5. return r.nextInt(10);
    6. };
    7. Integer num = s1.get() ;

    3) Function

    功能型接口,需要传递参数,根据参数做处理,将处理结果返回 R apply(T t); Function

    1. String s = "dmc is good" ;
    2. //需要实现功能,将字符串转换成大小
    3. Function f1 = (String s1)->{
    4. return s1.toUpperCase();
    5. };
    6. System.out.println( f1.apply(s) );
    7. //---------------------------------------------
    8. String s = "dmc is good" ;
    9. //需要实现功能,将字符串转换成大小
    10. Function f1 = (String s1)->{
    11. System.out.println("1操作");
    12. return s1.toUpperCase();
    13. };
    14. //System.out.println( f1.apply(s) );
    15. Function f2 = s1->{
    16. System.out.println("2操作");
    17. return s1.substring(0,3);
    18. };
    19. //f1处理后,再进行一次f2的处理
    20. //System.out.println( f1.andThen(f2).apply(s) );
    21. //f1处理前,先进行一次f2的处理
    22. System.out.println( f1.compose(f2).apply(s) );

    4) Predicate

    断言型接口,传递参数,根据参数做判断,返回boolean boolean test(T t)

    1. //判断user登录信息是否正确
    2. Predicate p1 = (User user1)->{
    3. return user1.uname.equals("dmc") && user1.upass.equals("123");
    4. };
    5. System.out.println(p1.test(user)?"登录成功":"登录失败");
    6. //----------------------------------------------
    7. User user = new User("dmc","1234") ;
    8. //判断user登录信息是否正确
    9. Predicate p1 = (User user1)->{
    10. return user1.uname.equals("dmc") ;
    11. };
    12. Predicate p2 = (User user1)->{
    13. return user1.upass.equals("123") ;
    14. };
    15. //函数式接口中的链式功能,基于的是一个对象
    16. System.out.println(p1.or(p2).test(user)?"登录成功":"登录失败");
    17. System.out.println(p1.negate().test(user));

    5) 扩展:BiFunction

    R apply(T t,U u); BiFunction

    1. Num num = new Num(10,20);
    2. Function f1 = (num1)->num.x + num.y ;
    3. //------------------------------------------
    4. //二元操作功能
    5. BiFunction b1 = (x , y)-> x+y ;
    6. System.out.println(b1.apply(10,20));

    二 Stream

    1 stream操作过程

    stream操作分为2部分

    如果没有终端操作,中间操作无法验证结果。

    只有终端操作执行时,中间操作才开始执行。(在终端操作执行前,中间操作只是一个标记)

     

    1) 中间操作

    中间操作本身不会执行,只是一个标记,会在终端操作执行时才执行。

    中间操作语法会返回一个Stream对象,可以以链式的方式增加多个中间操作(标记)

    2)终端操作

    要么返回一个具体的数据,要么就执行遍历操作,什么都不返回(void)

    整个流操作在执行终端操作方法时就结束了(如果有后续操作,也不是流操作,或者是一个新的流操作)

    2 创建Stream对象

    1) 通过集合获得Stream对象

    jdk1.8之后,为List , Set , Conllection 增加Stream()方法获得流对象

    流对象中装载的就是集合中的数据

    list.stream()
    set.stream()
    collection.stream()

    2) 其他

    1. //上面我们通过集合获得流的时候是先把数据存到集合里,在获得流的时候将数据存到流里
    2. //下面的这种方法是直接将数据存到流里面
    3. Stream.of(1,2,3,4,5);
    4. //这种是通过传入一个Supplier,然后通过Supplier返回的对象存入到流中,通过limit的参数表示在流中存入多少个Supplier提供的对象
    5. Stream.generate(()->"dmc").limit(100);
    6. //这种是在流中存入数据1~100
    7. Stream.iterate(1,(i)->++i).limit(100)

    3 终端操作

    forEach()

    1. 参数是个Consumer 消费型接口
    2. //执行forEach方法时,底层就会遍历每一个元素,每次(底层)遍历获得一个元素,就会调用我们提供的消费功能进行处理(策略模式)
    3. List cars = Arrays.asList(
    4. new Car("宝马","蓝色",300000),
    5. new Car("奔驰","黑色",400000),
    6. new Car("奥迪","红色",450000),
    7. new Car("保时捷","蓝色",600000),
    8. new Car("本田","白色",2000000),
    9. new Car("比亚迪","白色",220000),
    10. new Car("理想","黑色",250000)
    11. );
    12. cars.stream()
    13. .forEach(System.out::println);

    count() , max() , min()

    1. Object obj = cars.stream()
    2. .filter(car->car.color.equals("白色"))
    3. .count();
    4. System.out.println(obj);
    5. //-------------------------------------------
    6. Object obj = cars.stream()
    7. .max((c1,c2)->c1.price - c2.price);
    8. System.out.println(obj);

    collect()

    1. //汇总
    2. //collect终端方法执行时,会遍历所有的元素,会将每个元素的price属性值收集起来,求和
    3. Object obj = cars.stream()
    4. .collect(Collectors.summingInt(car->car.price));
    5. System.out.println(obj);
    6. //分组(汇总)
    7. Object obj = cars.stream()
    8. .collect(Collectors.groupingBy(car->car.color));
    9. System.out.println(obj);
    10. Object obj = cars.stream()
    11. .collect(Collectors.groupingBy(car->{
    12. if(car.price<=300000){
    13. return "便宜" ;
    14. }else{
    15. return "昂贵" ;
    16. }
    17. }));
    18. System.out.println(obj);

    4 中间操作

    filter()

    1. 参数是个Predict 断言型接口
    2. cars.stream()
    3. .filter(car->"黑色".equals(car.color))
    4. .forEach(System.out::println);

    map()

    1. 参数是函数型接口 Function
    2. //map就是在所有的属性中,抽取出部分需要的属性
    3. //案例中就是在car的3个属性中,抽取出cname和price2个属性
    4. cars.stream()
    5. .map(car->{return new Car2(car.cname,car.price); })
    6. .forEach(System.out::println);
    7. List ---> List

    sorted()

    1. 可以没有参数,默认是按照升序排列的,还有一个带参数的方法Stream sorted(Comparatorsuper T> comparator);
    2. 可以自定义排序规则
    3. //排序
    4. cars.stream()
    5. .sorted((c1,c2)->c1.price-c2.price)
    6. .forEach(System.out::println);
    7. //关于比较器,可以看TreeSet

    limit() & skip()

    1. limit(long n1)表示从stream中取出n1的个数
    2. skip(long n2) 表示跳过stream中的前面n2个数
    3. //分页,从那条记录开始,取几条记录, 从0开始取3条(0,1,2),从3开始取3条(3,4,5),从6开始取3条(7,8,9)
    4. cars.stream()
    5. .sorted((c1,c2)->c1.price-c2.price)
    6. .skip(4) //跳过几个,因为时从0开始条,这个条过几个,也可以理解为从第几个开始
    7. .limit(3)
    8. .forEach(System.out::println);

  • 相关阅读:
    使用tcpdump抓取vpp接口中的报文
    华为云云耀云服务器L实例评测|云耀云服务器L实例部署JumpServer开源堡垒机
    npm环境搭建
    2020 号门牌,总共需要多少个字符 2
    一台PoE交换机可以为多少个设备提供供电?
    手写一个 Redis LruCache 缓存机制
    CentOS7.8忘记密码后如何重置
    目标检测4--Adaptive Training Sample Selection(ATSS)算法
    微服务项目:尚融宝(52)(核心业务流程:充值服务(2))
    在网页中实现响应性字体
  • 原文地址:https://blog.csdn.net/caijigskg/article/details/127943026