记录一个JAVA8,Stream的应用

今天看到一道题:

已知一个List<User>集合,User有name(String)和 age(int)属性,请按照年龄从小到大顺序输出每一个年龄的用户(名)列表。

        例如:List为[{张三,23},{李四,21},{王五,23}]

        输出:21:[李四] , 23:[张三,王五]

首先我想到的就是封装成MAP,把年龄作为key,姓名作为一个List存为value:

    public static void getOrderedMap1(List<User> userList){
        //对userList排序
        Collections.sort(userList);
        //封装
        Map<Integer,List<String>> userMap = new HashMap<>(userList.size());
        //遍历
        for (User user:userList){
            List<String> username = userMap.get(user.getAge());
            //表里没有对应的年龄,就创建新的姓名表
            if (username==null){
                username = new ArrayList<>();
                username.add(user.getName());
                //插入到userMap
                userMap.put(user.getAge(), username);
            }else {
                //有年龄就直接加名字
                username.add(user.getName());
            }
        }
        userMap.forEach((age,names)->{
            System.out.println(
                    age+":"+names
            );
        });
    }

这个解法好理解,但是手写起来可能有点复杂了,于是利用java8的特性,有了解法2:

    public static void getOrderedMap2(List<User> userList) {
        Map<Integer, List<String>> userMap = new HashMap<>(userList.size());
        //对userList排序
        userList.sort(User::compareTo);
        userList.forEach(user -> {
            if (userMap.get(user.getAge())==null){
                List<String> nameList = new ArrayList<>();
                nameList.add(user.getName());
                userMap.put(user.getAge(),nameList);
            }else {
                userMap.get(user.getAge()).add(user.getName());
            }
        });

        userMap.forEach((age, names) -> {
            System.out.println(
                    age + ":" + names
            );
        });
    }

同样的方式,先排序,再判断,生成Map丢进去,遍历输出。

我们都既然用了Stream了,干脆就直接用到底吧

    public static void getOrderedMap3(List<User> userList) {
        userList.stream().collect(Collectors.groupingBy(User::getAge, Collectors.toMap(User::getAge, User::getName, (name1, name2) -> name1 + "," + name2))).forEach((age, users) -> {
            System.out.println(age + ":[" + users.get(age) + "]");
        });
    }

这个就更简单了,甚至很粗暴,我们慢慢来讲解。

首先我们把userList作为一个流进行处理。

Collectors

Collectors 类实现了很多归约操作,例如将流转换成集合和聚合元素。

groupingBy 这个方法是用于生成一个拥有分组功能的Collector,User::getAge表示了我们获得一个根据年龄分组的对象,以及一个Collector对象。

toMap方法是根据给定的键生成器和值生成器生成的键和值保存到一个map中返回,键和值的生成都依赖于元素,可以指定出现重复键时的处理方案和保存结果的map。

我们把遍历的age作为map的key, name作为map的value存入map,重复建处理方案是:当两个name重复,name存入的value应该是“name1,name2”

所以就实现了分类存储。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

PigeonEssence

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值