Bootstrap

Stream使用技巧(1)------数据处理技巧

Stream使用技巧(1)------数据处理技巧

一. 背景

作为java8新特性之一的Stream API为开发者带来了极大的便利,它可以对我们需要操作的集合进行非常复杂的操作,以活的我们想要的结果.

本文不会告诉你什么是Stream,毕竟网上花里胡哨的使用教程已经让我应接不暇,本系列博文只是记录一些Stream的使用技巧,便于方便的查找和参考.

本博文会无限更新,有新的使用方法会逐渐添加进来,如果有小伙伴有新奇的使用技巧,也可以发出来一起分享.

本文中默认使用的对象user如下:

    @Data
    class User {
        /** 名字 **/
        private String name;
        /** 年龄 **/
        private Integer age;
        /** 性别 true男false女 **/
        private boolean sex;

        User(String name, Integer age, boolean sex) {
            this.age = age;
            this.name = name;
            this.sex = sex;
        }
    }
二. 使用案例
1. List<User>转Map<String, Integer>
  • 需求描述:

    有一个List集合,其中的每一个元素都是对象,想变成一个Map,其中key是对象的一个属性,value也是对象的一个属性或者对象本身.

  • 伪代码:

        @Test
        public void test1() {
            User a = new User("张三", 20, true);
            User b = new User("李四", 30, true);
            User c = new User("王五", 40, true);
            List<User> list = new ArrayList<User>();
            list.add(a);
            list.add(b);
            list.add(c);
            //变成Map, key是name, value是age
            Map<String, Integer> collect = list.stream().collect(Collectors.toMap(User::getName, User::getAge));
            System.out.println(collect);
        }
    
    
  • 结果:

    {李四=30, 张三=20, 王五=40}
    

2. List<User>转List<String>
  • 需求描述:

    List对象中,提取出每一个User对象的name属性,放在List里面

  • 伪代码:

        @Test
        public void test1() {
            User a = new User("张三", 20, true);
            User b = new User("李四", 30, true);
            User c = new User("王五", 40, true);
            List<User> list = new ArrayList<User>();
            list.add(a);
            list.add(b);
            list.add(c);
            //取出每一个user的name变成list
            List<String> collect = list.stream().map(User::getName).collect(Collectors.toList());
            System.out.println(collect);
        }
        
    
  • 结果:

    [张三, 李四, 王五]
    
3. List<User>转Map<Integer, Map<String, User>>
  • 需求描述

    用户集合中的用户,先按照年龄分组,再按照姓名分组,最终将用户分开

  • 伪代码:

        @Test
        public void test1() {
            User a = new User("张三", 20, true);
            User b = new User("李四", 30, true);
            User c = new User("王五", 40, true);
            User d = new User("花木兰", 40, false);
            User e = new User("李师师", 50, false);
    
            List<User> list = new ArrayList<User>();
            list.add(a);
            list.add(b);
            list.add(c);
            list.add(d);
            list.add(e);
            //取出每一个user的name变成list
            Map<Integer, Map<String, User>> collect =
                    list.stream().collect(Collectors.groupingBy(
                            User::getAge,
                            Collectors.toMap(User::getName, x -> x))
                    );
            System.out.println(collect);
        }
    
  • 结果:

    {50={李师师=SampleStream.User(name=李师师, age=50, sex=false)}, 20={张三=SampleStream.User(name=张三, age=20, sex=true)}, 40={王五=SampleStream.User(name=王五, age=40, sex=true), 花木兰=SampleStream.User(name=花木兰, age=40, sex=false)}, 30={李四=SampleStream.User(name=李四, age=30, sex=true)}}
    
4. List<User>取出一个属性转List<Integer>, 并去重
  • 需求描述

    取出用户集合中的Age字段,放在一个List中,并去重

  • 伪代码:

      @Test
      public void test1() {
          User a = new User("张三", 20, true);
          User b = new User("李四", 30, true);
          User c = new User("王五", 40, true);
          User d = new User("花木兰", 40, false);
          User e = new User("李师师", 50, false);
    
          List<User> list = new ArrayList<User>();
          list.add(a);
          list.add(b);
          list.add(c);
          list.add(d);
          list.add(e);
          //取出每一个user的name变成list
          List<Integer> collect = list.stream().map(User::getAge).distinct().collect(Collectors.toList());
          System.out.println(collect);
      }
    
  • 结果:

    [20, 30, 40, 50]
    
5. List<User>去重并提出空值
  • 需求描述

    用户集合中有两个用户是相同的,且有个null对象,需要得到一个去重去空后的集合

  • 伪代码:

      @Test
      public void test1() {
          User a = new User("张三", 20, true);
          User b = new User("李四", 30, true);
          User c = new User("王五", 40, true);
          User d = new User("王五", 40, false);
          User e = new User("李师师", 50, false);
    
          List<User> list = new ArrayList<User>();
          list.add(a);
          list.add(b);
          list.add(c);
          list.add(d);
          list.add(e);
          list.add(null);
          System.out.println("去重前: " + list);
          //取出每一个user的name变成list
          ArrayList<User> collect = list.stream().filter(Objects::nonNull).collect(
                  Collectors.collectingAndThen(
                          Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(User::getName))),
                          ArrayList::new)
          );
          System.out.println("去重后: " + collect);
      }
    
  • 结果:

    去重前: [SampleStream.User(name=张三, age=20, sex=true), SampleStream.User(name=李四, age=30, sex=true), SampleStream.User(name=王五, age=40, sex=true), SampleStream.User(name=王五, age=40, sex=false), SampleStream.User(name=李师师, age=50, sex=false), null]
    去重后: [SampleStream.User(name=张三, age=20, sex=true), SampleStream.User(name=李四, age=30, sex=true), SampleStream.User(name=李师师, age=50, sex=false), SampleStream.User(name=王五, age=40, sex=true)]
    
结语:

在本篇博文中,列举了java8中Stream API在实际开发中的一些应用技巧,记录在这里,以后有需要的时候可以及时查阅

个人公众号<橙耘自留地>日前已经开通,后续博主发布的文章都会一并更新到公众号,如有需要,自行查阅.

关于橙耘自留地,是我个人聚焦互联网技术栈学习分享的一个平台,创立之初是因为目前业内各种技术课程资料层次不齐,褒贬不一,有时候一门课花费高价买入,其实内含草包,有时偶尔低价得之,却又大有干货.因此我会根据大家的意见和评价,选择不同的技术栈去学习,一为提升我自己的技术,二为大家梳理出质量比较好的课程,以作参考.同时,相关的学习心得也会一并更新到博客和公众号.

qrcode_for_gh_c1462e34b232_344

;