您好,欢迎来到爱够旅游网。
搜索
您的当前位置:首页Java 8 Stream API:强大而灵活的数据处理流水线

Java 8 Stream API:强大而灵活的数据处理流水线

来源:爱够旅游网

Stream 中⽂称为 “流”,通过将集合转换为这么⼀种叫做 “流”的元素队列,通过声明性⽅式,能够对集合中的每个元素进⾏⼀系列并⾏或串⾏的流⽔线操作

元素是特定类型的对象,所以元素集合看作⼀种流, 流在管道中传输, 且可以在管道的节点上进⾏处理, ⽐如 排序,聚合,过滤等操作

操作详情

  • 数据元素便是原始集合,如list,set,map

  • 生成流,可以使串行流stream或者并行流parallelStream

  • 中间操作,可以使排序,聚合,过滤,转换等

  • 终端操作,很多流操作本身就会返回一个流,所以多个操作可以直接连接起来,最后统一进行收集

开发前数据准备

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private Long id;
    private String name;
    private Integer age;
}@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserDTO {
    private Long id;
    private String name;
    private Integer age;
}@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private Long id;
    private String name;
    private Integer age;
}@Data
@AllArgsConstructor
@NoArgsConstructor
public class VideoOrder {
    private String tradeNo;
    private String title;
    private int money;
}

Map操作

在日常开发中,对象转换是必不可少的,比如:mapper层实体类获取,到业务层转换为DTO,业务层到控制器AO等。

 public static void testMap(){
        List<User> list = Arrays.asList(
                new User(1L, "张三", 18),
                new User(2L, "李四", 20),
                new User(3L, "王五", 33),
                new User(4L, "赵六", 44));
        List<UserDTO> userDTOList = list.stream().map(obj -> {
            UserDTO userDTO = new UserDTO(obj.getId(), obj.getName(), obj.getAge());
            return userDTO;
        }).collect(Collectors.toList());
​
        userDTOList.forEach(System.out::println);
    }

filter条件过滤

有时候我们获取数据库的列表,有些数据不是我们想要的,这时候我们可以过滤掉不需要的数据。如下面示例过滤掉字符串长度大于7的字符串。

 public static void testFilter(){
        List<String> list = Arrays.asList(
               "SpringBoot",
               "SpringCloud",
               "Spring",
               "SpringMVC",
               "mybatis",
               "html",
                "git"
               );
        List<String> stringList = list.stream().filter(obj -> obj.length() > 7).collect(Collectors.toList());
        System.out.println(stringList);
    }

sorted排序

sorted对流进行自然排序,其中的元素需要实现comparable接口 sorted(Comparatorcomparator)用于自定义升降序

 public static void testSorted(){
        List<String> list = Arrays.asList(
                "SpringBoot",
                "SpringCloud",
                "Spring",
                "SpringMVC",
                "mybatis",
                "html",
                "git"
        );List<String> collect = list.stream().sorted().collect(Collectors.toList());
        System.out.println(collect);
        //根据长度进行排序
        List<String> collect1 = list.stream().sorted(Comparator.comparing(String::length)).collect(Collectors.toList());
        System.out.println(collect1);//limit截取
        List<String> collect2 = list.stream().sorted(Comparator.comparing(String::length).reversed()).limit(3).collect(Collectors.toList());
        System.out.println(collect2);
    }

match匹配元素

allMatch检查是否匹配所有元素,符合才返回true
anyMatch检查是否至少匹配一个元素

示例:匹配列表中字符串长度大于5的数据,allMatch->false,anyMatch->true

 public static void testAllOrAnyMatch(){
        List<String> list = Arrays.asList(
                "SpringBoot",
                "SpringCloud",
                "Spring",
                "SpringMVC",
                "mybatis",
                "html",
                "git"
        );boolean allMatch = list.stream().allMatch(obj -> obj.length() > 5);
        System.out.println(allMatch);
        boolean anyMatch = list.stream().anyMatch(obj -> obj.length() > 10);
        System.out.println(anyMatch);
    }

求最值(max,min等)

示例:求以下列表中年龄最大最小值

public static void testMaxMin(){
        List<User> list = Arrays.asList(
                new User(1L, "张三", 18),
                new User(2L, "李四", 20),
                new User(3L, "王五", 33),
                new User(4L, "赵六", 44));
        Optional<User> userOptional = list.stream().max(Comparator.comparingInt(User::getAge));
        System.out.println(userOptional.get().getAge());Optional<User> userOptional1 = list.stream().min(Comparator.comparingInt(User::getAge));
        System.out.println(userOptional1.get().getAge());
    }

reduce聚合操作

reduce聚合操作,根据一定的规则将stream中的元素计算后返回一个唯一的值

常用方法 Optionalreduce(BinaryOperatoraccumulator)

  • accumulator计算的累加器

常用方法二 T reduce(T identity,BinaryOperatoraccumulator)

  • identity:用户提供一个循环计算的初始值

accumulator计算的累加器

​示例:第一个元素与第二个元素累加在和第三个元素相加,直到全部加完

Integer value = Stream.of(1, 2, 3, 4, 5, 6).reduce((item1,item2) -> item1 + item2).get();
        System.out.println(value);//不适用lambda表达式
Integer value1 = Stream.of(1, 2, 3, 4, 5, 6).reduce(new BinaryOperator<Integer>() {
    @Override
    public Integer apply(Integer integer, Integer integer2)
 {
        return integer + integer2;
    }
}).get();
 //10作为初始值,然后和第一个数相加,结果再与第二个数相加,直到所有的数相加完成为止
Integer value3 = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9).reduce(10, (sum, item) -> sum + item);

拼接字符串(joining)

​示例:将"springBoot", “SpingMVC”, "mybatis"使用[]拼接

String collect = Stream.of("springBoot", "SpingMVC", "mybatis").collect(Collectors.joining(",", "[", "]"));
分组(partitionBy)

​示例:将list中的数据进行分组,长度大于8的为一组,其他为另外一组

 List<String> list = Arrays.asList(
                "SpringBoot",
                "SpringCloud",
                "Spring",
                "SpringMVC",
                "mybatis",
                "html",
                "git"
        );
        Map<Boolean, List<String>> listMap = list.stream().collect(partitioningBy(obj -> obj.length() > 8));
        listMap.forEach((key,value)->{
            System.out.println(key);
            value.forEach(System.out::println);
            System.out.println();
        });

分组(group by)

根据学生的省份进行分组,并统计最大值、最小值、总人数、总和、平均值

 //根据学生的省份进行分组
List<Student> students = Arrays.asList(new Student("⼴东", 23),
        new Student("⼴东", 24),
        new Student("⼴东", 23),
        new Student("北京", 22),
        new Student("北京", 20),
        new Student("北京", 20),
        new Student("海南", 25));Map<String, List<Student>> collect = students.stream().collect(Collectors.groupingBy(obj -> obj.getProvince()));
collect.forEach((key,value)->{
    System.out.println(key);
    value.forEach(System.out::println);
});//统计学生的各个年龄信息
IntSummaryStatistics summaryStatistics = students.stream().collect(Collectors.summarizingInt(Student::getAge));
System.out.println("平均值:"+summaryStatistics.getAverage());
System.out.println("人数:"+summaryStatistics.getCount());
System.out.println("最大值:"+summaryStatistics.getMax());
System.out.println("最小值:"+summaryStatistics.getMin());
System.out.println("总和:"+summaryStatistics.getSum());

demo测试

  • 电商订单数据处理,根据下面的list1和list2个10个订单
  • 统计出同时被两个人购买的商品列表
  • 统计出两个人都买的商品的差集
  • 统计处全部被购买商品的去重并集
  • 统计两个人的分别购买订单的平均
  • 价格统计两个人的分别购买订单的总价格
public static void test1(){
      //总价 35
      List<VideoOrder> videoOrders1 = Arrays.asList(
              new VideoOrder("20190242812", "springboot教程", 3),
              new VideoOrder("20194350812", "微服务SpringCloud", 5),
              new VideoOrder("20190814232", "Redis教程", 9),
              new VideoOrder("20190523812", "⽹⻚开发教程", 9),
              new VideoOrder("201932324", "百万并发实战Netty", 9));
      //总价 
      List<VideoOrder> videoOrders2 = Arrays.asList(
              new VideoOrder("2019024285312", "springboot教程", 3),
              new VideoOrder("2019081453232", "Redis教程", 9),
              new VideoOrder("20190522338312", "⽹⻚开发教程", 9),
              new VideoOrder("2019435230812", "Jmeter压⼒测试", 5),
              new VideoOrder("20193232411", "Git+Jenkins持续集成", 7),
              new VideoOrder("20193232424", "Idea全套教程", 21));//交集
      List<VideoOrder> intersectionList = videoOrders1.stream().filter(videoOrders2::contains).collect(Collectors.toList());
      System.out.println("交集=:"+intersectionList);//差集1
      List<VideoOrder> diffList1 = videoOrders1.stream().filter(obj -> !videoOrders2.contains(obj)).collect(Collectors.toList());
      System.out.println("差集1="+diffList1);//差集2
      List<VideoOrder> diffList2 = videoOrders2.stream().filter(obj -> !videoOrders1.contains(obj)).collect(Collectors.toList());
      System.out.println("差集2="+diffList2);//并集
      List<VideoOrder> allVideoOrder = videoOrders1.parallelStream().collect(Collectors.toList());
      allVideoOrder.addAll(videoOrders2);
      System.out.println("并集="+allVideoOrder);//去重并集
      List<VideoOrder> allVideoOrderDistinct = allVideoOrder.stream().distinct().collect(Collectors.toList());
      System.out.println("去重并集="+allVideoOrderDistinct);//两个订单平均价格
      double videoOrderAvg1 = videoOrders1.stream().collect(Collectors.averagingInt(VideoOrder::getMoney));
      System.out.println("订单1平均价格="+videoOrderAvg1);double videoOrderAvg2 = videoOrders2.stream().collect(Collectors.averagingInt(VideoOrder::getMoney));
      System.out.println("订单2平均价格="+videoOrderAvg2);//两个订单总价格
      long sum1 = videoOrders1.stream().collect(Collectors.summarizingInt(VideoOrder::getMoney)).getSum();
      System.out.println("订单1总价格="+sum1);
      long sum2 = videoOrders2.stream().collect(Collectors.summarizingInt(VideoOrder::getMoney)).getSum();
      System.out.println("订单2总价格="+sum2);
}

Stream API的引入极大地简化了Java中对集合数据的操作,通过一系列链式调用的方法,可以非常方便地对数据进行过滤、映射、聚合等多种操作。无论是简单的数据处理任务还是复杂的业务逻辑,Stream API都能提供简洁而强大的解决方案。希望本文的示例能够帮助您更好地理解和应用这一强大的特性​。

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- igbc.cn 版权所有 湘ICP备2023023988号-5

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务