专栏首页Kevin-ZhangCGJAVA8新特性之List的各种用法(最大、最小、平均值、分组、求和、遍历、过滤、排序)

JAVA8新特性之List的各种用法(最大、最小、平均值、分组、求和、遍历、过滤、排序)

构建一个User实体类供演示

public class Users {

    /**
     * ID
     */
    private Long id;
    /**
     * 用户名
     */
    private String name;
    /**
     * 年龄
     */
    private int age;
    /**
     * 工号
     */
    private String jobNumber;
    /**
     * 性别
     */
    private String sex;
    /**
     * 注册时间
     */
    private Date entryDate;
    /**
     * 成员组织
     */
    private BigDecimal familyMemberQuantity;

    private Long userId;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getJobNumber() {
        return jobNumber;
    }

    public void setJobNumber(String jobNumber) {
        this.jobNumber = jobNumber;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public Date getEntryDate() {
        return entryDate;
    }

    public void setEntryDate(Date entryDate) {
        this.entryDate = entryDate;
    }

    public BigDecimal getFamilyMemberQuantity() {
        return familyMemberQuantity;
    }

    public void setFamilyMemberQuantity(BigDecimal familyMemberQuantity) {
        this.familyMemberQuantity = familyMemberQuantity;
    }

    public Long getUserId() {
        return userId;
    }

    public void setUserId(Long userId) {
        this.userId = userId;
    }

    @Override
    public String toString() {
        return "Users{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", jobNumber='" + jobNumber + '\'' +
                ", sex='" + sex + '\'' +
                ", entryDate=" + DateFormatUtils.format(entryDate, "yyyy-MM-dd HH:mm:ss") +
                ", familyMemberQuantity=" + familyMemberQuantity +
                '}';
    }
}

一、根据字段分组得到多个List集合

构建一个产生Users的静态法

     /**
     * 生产虚拟用户
     *
     * @return
     */
    public static List<Users> produceUser() {
        List<Users> usersList = new ArrayList<>();
        for (int i = 1; i <= 10; i++) {
            Users users = new Users();
            users.setId(Long.valueOf(i));
            users.setName("kobe" + i);
            users.setAge(15 + new Random().nextInt(5));
            users.setJobNumber("jobNumber" + i);
            if (i % 2 == 0) {
                users.setSex("男");
            } else {
                users.setSex("女");
            }
            users.setEntryDate(new Date());
            users.setFamilyMemberQuantity(new BigDecimal(i));
            usersList.add(users);
        }
        return usersList;
    }

利用Java8 特性,根据对象的某个属性进行分组

@Test
    public void groupByGender() {
        List<Users> list = produceUser();
        // 根据性别进行分组
        Map<String, List<Users>> collect = list.stream().collect(Collectors.groupingBy(Users::getSex));
        Set<Map.Entry<String, List<Users>>> entries = collect.entrySet();
        entries.forEach(item -> {
            // 性别 男 / 女
            String gender = item.getKey();
            // 男集合 / 女集合
            List<Users> usersList = item.getValue();
            System.out.println(gender);
            usersList.forEach(user -> System.out.println(user));
        });
    }

输出结果如下

二、集合求和

2.1 根据对象中的某个字段求和

    /**
     * 根据年龄字段求总和
     */
    @Test
    public void getSumByStream() {
        List<Users> list = produceUser();
        int sum = list.stream().mapToInt(Users::getAge).sum();
        System.out.println("共计:" + list.size() + "个用户,所有年龄总和为:" + sum);
        // 求最大年龄
        Integer integer = list.stream().map(Users::getAge).max(Integer::compareTo).get();
        System.out.println(integer);
        // 得到最大年龄对象
        Users users = list.stream().max(Comparator.comparingInt(Users::getAge)).get();
        System.out.println(users);
        // 求平均年龄
        System.out.println(list.stream().mapToInt(Users::getAge).average().getAsDouble());
        // 求最大年龄
        System.out.println(list.stream().mapToInt(Users::getAge).max().getAsInt());
    }

输出结果如下

2.2 List<数值型> 求和

    /**
     * 根据List求和
     */
    @Test
    public void getListSumByJava8() {
        List<Integer> listInt = new ArrayList();
        List<Double> listDoub = new ArrayList();
        for (int i = 0; i < 500; i++) {
            listInt.add(new Random().nextInt(1000));
            listDoub.add(new Random().nextDouble());
        }
        System.out.println("=======数值型Integer求和======");
        Integer integer = listInt.stream().reduce(Integer::sum).orElse(0);
        System.out.println(integer);
        System.out.println("=======数值型Double求和======");
        Double integer1 = listDoub.stream().reduce(Double::sum).orElse(0.00);
        System.out.println(integer1);
        // 取最大值
        System.out.println(listInt.stream().reduce(Integer::max).orElse(0));
        System.out.println(listInt.stream().mapToInt(Integer::valueOf).max().getAsInt());
        // 取最小值
        System.out.println(listInt.stream().reduce(Integer::min).orElse(0));
        // 取平均值
        System.out.println(listInt.stream().mapToInt(Integer::valueOf).average().getAsDouble());
    }

输出结果如下

三、遍历List集合

    /**
     * 遍历对象
     */
    @Test
    public void traverseByJava8(){
        List<Users> list = produceUser();
        list.forEach(System.out::println);
    }

输出结果如下

四、过滤List集合

    /**
     * 过滤对象
     */
    @Test
    public void filterByJava8() {
        List<Users> list = produceUser();
        System.out.println("原始数据为:");
        System.out.println("==============过滤后的数据为===============");
        list.forEach(System.out::println);
        //筛选出年龄大于3岁小于8岁的对象
        List<Users> collect = list.stream().filter(s -> s.getAge() > 13 && s.getAge() < 18).collect(Collectors.toList());
        System.out.println("过滤结束后的数据为:");
        collect.forEach(System.out::println);
    }

输出结果如下

五、获取List中的最大最小值

5.1 根据特定需求中的某个字段求最大最小

    /**
     * 求最大最小值,根据业务类型选择合适的类型值
     */
    @Test
    public void maxOrMinByJava8() {
        List<Users> list = produceUser();
        //根据mapTO**得到最大最小  ---写法一
        double asDouble = list.stream().mapToDouble(Users::getAge).max().getAsDouble();
        System.out.println("将最大值转换为Double类型进行展示,最大为:" + asDouble);
        double asDouble1 = list.stream().mapToDouble(Users::getAge).min().getAsDouble();
        System.out.println("将最小值转换为Double类型进行展示,最小为:" + asDouble1);
        int asInt = list.stream().mapToInt(Users::getAge).max().getAsInt();
        System.out.println("将最大值转换为Int类型进行展示,最大为:" + asInt);
        //根据map得到最大最小  ---写法二(推荐)
        Integer integer = list.stream().map(Users::getAge).max(Integer::compareTo).get();
        System.out.println("将最大值转换为字段对应类型进行展示,最大为:" + integer);
        Integer integer1 = list.stream().map(Users::getAge).min(Integer::compareTo).get();
        System.out.println("将最小值转换为字段对应类型进行展示,最小为:" + integer1);
    }

输出结果如下

5.2 根据特定需求中的某个字段求平均值

    /**
     * 求最大最小值,根据业务类型选择合适的类型值
     */
    @Test
    public void avgByJava8() {
        List<Users> list = produceUser();
        double avgAge = list.stream().mapToDouble(Users::getAge).average().getAsDouble();
        System.out.println("平均年龄为:" + avgAge);
    }

输出结果如下

六、根据需求将List转为Map

    /**
     * List -> Map
     * 需要注意的是:
     * toMap 如果集合对象有重复的key,会报错Duplicate key ....
     * user1,user2的id都为1。
     * 可以用 (k1,k2)->k1 来设置,如果有重复的key,则保留key1,舍弃key2
     */
    @Test
    public void mapToListByJava8() {
        List<Users> list = produceUser();
        Map<Long, Users> map = list.stream().collect(Collectors.toMap(Users::getId, a -> a, (k1, k2) -> k1));
        for (Map.Entry<Long, Users> entry : map.entrySet()) {
            Long key = entry.getKey();
            System.out.println("map中的key是:" + key);
            System.out.println("map中的value是:" + entry.getValue().toString());
        }

        // 根据ID和年龄获得map
        Map<Long, Integer> collect = list.stream().collect(Collectors.toMap(Users::getId, item -> Optional.ofNullable(item.getAge()).orElse(0)
                , (k1, k2) -> k1));
        System.out.println(collect.toString());
    }

输出结果如下

七、List排序

    /**
     * 排序(单字段/多字段排序)
     */
    @Test
    public void sortByJava8() {
        List<Users> list = produceUser();
        System.out.println("============未排序的数据=============");
        System.out.println(list.toString());
        try {
            //单字段排序,根据名字排序
            System.out.println("============单字段排序,根据名字排序=============");
            list.sort(Comparator.comparing(Users::getName));
            System.out.println(list.toString());
            //多字段排序,根据年龄再根据-->名字排序
            System.out.println("============多字段排序,根据年龄再根据-->名字排序=============");
            list.sort(Comparator.comparing(Users::getAge, (o1, o2) -> o2 - o1).thenComparing(Users::getName));
            System.out.println(list.toString());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

输出结果如下

八、List去重

     /**
     * 去重
     */
    @Test
    public void distinctByJava8() {
        List<String> numList = new ArrayList();
        numList.add("kevin");
        numList.add("kevin");
        numList.add("kevin1");
        numList.add("kevin2");
        numList.add("kevin1");
        numList.add("kevin2");
        System.out.println("===========未去重的数据============");
        System.out.println(numList.toString());
        System.out.println("===========去重后的数据============");
        List<String> collect = numList.stream().distinct().collect(Collectors.toList());
        System.out.println(collect.toString());
    }

输出结果如下

九、List的合并

首先了解下交集并集差集的概念,分别有三个区域A,B,C

9.1 List的合并之—>并集

    /**
     * 得到两个集合的并集
     */
    @Test
    public void listByJava8() {
        List<String> list1 = new ArrayList();
        list1.add("aaa");
        list1.add("bbb");
        list1.add("ccc");
        list1.add("aaa1");
        List<String> list2 = list1;
        list2.add("ddd");
        list2.add("aaa");
        list2.add("eee");
        list2.add("ccc");
        list2.add("fff");
        list2.add("aaa1");
        list2.add("aaa2");

        //根据整个对象是否一致来去重合并得到并集
        System.out.println("==========并集: 集合A{1, 2, 3} 和集合B {2, 3, 4} 的并集是 {1, 2, 3, 4}==========");
        System.out.println("---->并集写法一 [去重]");
        System.out.println("============并集举例一:根据List去重特性合并多个Lits============");
        List<String> collect = Stream.of(list1, list2).flatMap(Collection::stream).distinct().collect(Collectors.toList());
        System.out.println(collect.toString());
        System.out.println("---->并集写法二 ");
        System.out.println("============并集举例二:根据List得到并集============");
        List<String> collect1 = list1.stream().filter(s -> list2.contains(s)).distinct().collect(Collectors.toList());
        System.out.println(collect1);
        System.out.println("==========交集: 集合A {1,2,3} 和集合B {2,3,4} 的交集为 {2,3}。即{1,2,3}∩{2,3,4}={2,3}==========");
    }

输出结果如下

9.2 List的合并之—>交集(即两个或多个list重复的元素的集合)

    /**
     * 得到两个集合的交集
     */
    @Test
    public void listBingByJava8() {
        System.out.println("==========交集: 集合A {1,2,3} 和集合B {2,3,4} 的交集为 {2,3}。即{1,2,3}∩{2,3,4}={2,3}==========");
        List<String> list1 = new ArrayList();
        list1.add("aaa");
        list1.add("bbb");
        list1.add("ccc");
        list1.add("aaa1");
        List<String> list2 = list1;
        list2.add("ddd");
        list2.add("aaa");
        list2.add("eee");
        list2.add("ccc");
        list2.add("fff");
        list2.add("aaa1");
        list2.add("aaa2");
        //合并List
        List<String> collect = list1.stream().filter(s -> list2.contains(s)).collect(Collectors.toList());
        System.out.println("============多个List合并后的元数据===========");
        System.out.println(collect);
        // 获得元素出现频率的 Map,键为元素,值为元素出现的次数
        List<String> collect1 = collect.stream().collect(Collectors.toMap(a -> a, a -> 1, (a, b) -> a + b))
                //  Set<Entry>转换为Stream<Entry>
                .entrySet().stream()
                // 过滤出元素出现次数大于 1 的 entry
                .filter(entry -> entry.getValue() > 1)
                // 获得 entry 的键(重复元素)对应的 Stream
                .map(entry -> entry.getKey())
                // 转化为 List并去重
                .distinct().collect(Collectors.toList());
        System.out.println("========合并后得到处理得到重复的数据========");
        System.out.println(collect1);
    }

输出结果如下

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Java8新特性第3章

    Stream作为Java8的新特性之一,他与Java IO包中的InputStream和OutputStream完全不是一个概念。Java8中的Stream是对...

    企鹅号小编
  • Java8新特性第3章(Stream API)

    Stream作为Java8的新特性之一,他与Java IO包中的InputStream和OutputStream完全不是一个概念。Java8中的Stream是对...

    张磊BARON
  • 工作后, 你一定不能错过技术之JDK1.8的新特性

    而在企业开发中, 主要用到的便是Lambda表达式和Stream流 , 而在下面,我们便主要的去学习这两方面的知识

    时间静止不是简史
  • 使用 Stream API 高逼格 优化 Java 代码!

    Java8的新特性主要是Lambda表达式和流,当流和Lambda表达式结合起来一起使用时,因为流申明式处理数据集合的特点,可以让代码变得简洁易读

    搜云库技术团队
  • 【Java8新特性】03 Stream流式数据处理

    【Java8新特性】02 函数式接口和Lambda表达式实战练习:环绕执行模式使行为参数化

    爱笑的架构师
  • java8 stream的这些开发技巧,你值得好好收藏

    Stream、IntStream、LongStream、DoubleStream的父接口都是BaseStream。BaseStream的四个子接口方法都差不多,...

    苏三说技术
  • Stream API 学会这样用,简化代码真牛批!

    www.juejin.im/post/5d8226d4e51d453c135c5b9a

    Java技术栈
  • Java8新特性之Stream

    本来以为Java8的新特性需要3篇文章才能写完的,但是发现其实Stream的接口并不想象的那么多,今天就可以完结啦!

    用户8902830
  • 评审代码时,这样写就不会被怼了,干货

    在JDK版本普遍升级到8之后,最近参与了几次代码,好多人对JDK8中的用法不是特别熟熟悉,用的不对或者干脆用错的常有,代码评审时经常被说到,这里整理一波实用的技...

    阿伟
  • 用Java 8 stream流实现简洁的集合处理

    java 8已经发行好几年了,前段时间java 12也已经问世,但平时的工作中,很多项目的环境还停留在java1.7中。而且java8的很多新特性都是革命性的,...

    宜信技术学院
  • 网易三面:Stream如何提高遍历集合效率?

    例如,电商系统中的订单表,常常使用用户ID的Hash值来实现分表分库,这样是为了减少单个表的数据量,优化用户查询订单的速度。

    Java程序猿
  • 开发神器,拿走不谢【Java8 Stream】

    每一种开发语言都提供了丰富的工具库,作为当今最流行的的开发语言之一,Java肯定也不例外。

    林老师带你学编程
  • Java 8 - Stream基本实例及Stream的并行处理在线程上的表现

    集合是Java中使用最多的API 。 可以让你把数据分组并加以处理。尽管集合对于几乎任何一个Java应用都是不可或缺的,但集合操作却远远算不上完美。

    小小工匠
  • Java8新特性实践

    神秘的寇先森
  • Java8 Stream流

    关注公众号(CoderBuff)回复“stream”获取《Java8 Stream编码实战》PDF完整版。

    用户1148394
  • Java 8 中的 Streams API 详解

    Stream 作为 Java 8 的一大亮点,它与 java.io 包里的 InputStream 和 OutputStream 是完全不同的概念。它也不同于 ...

    编程十年
  • 学会lambda表达式,能让你少敲1000行代码!

    一颗雷布斯,假设有这样一个业务:有一张学历表,表里面存了我们这一生中的所有学历信息,学历类型type分别是0小学、1初中、2高中、3高中、4大学、5研究生、6博...

    一颗雷布斯
  • Java8 Stream新特性详解及实战

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 ...

    程序新视界
  • Java8新特性:Lambda表达式详解

    在 Java 版本的历次更新迭代中,Java8 是一个特殊的存在,与以往的版本升级不同。我们对 Java8 似乎抱有更大的期待,因为它是 Java5 之后最重要...

    南风

扫码关注云+社区

领取腾讯云代金券