对HashMap集合的值中对象进行排序

363 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。 ​

问题

 对一个key为Integet, value为User对象  (User对象中有name和age属性)  的HashMap 通过User的age属性进行倒序排序

 你怎么排?   如果不用TreeMap可以排出来吗?   返回值需要是HashMap类型你怎么弄?

第一步   构建User对象 以及HashMap集合


    static class User {
        int age;
        String name;

        public User(int age, String name) {
            this.age = age;
            this.name = name;
        }

        @Override
        public String toString() {
            return "User{" +
                    "age=" + age +
                    ", name='" + name + ''' +
                    '}';
        }
    }

    static HashMap<Integer, User> map = new HashMap<Integer, User>() {{
        this.put(7, new User(3, "面筋哥"));
        this.put(1, new User(2, "王花花"));
        this.put(5, new User(5, "栓蛋"));
        this.put(4, new User(1, "张三丰"));
        this.put(2, new User(4, "寒王"));
    }};

 

第二步   排序算法1  通过TreeMap排序

    
  private static void sortedTreeMap() {
        // 创建 TreeMap 自定义比较器
        TreeMap<Integer, User> tree = new TreeMap<>(((o1, o2) -> Integer.compare(map.get(o2).age, map.get(o1).age)));
        // 遍历原 Map 添加到 TreeMap
        map.forEach((k, v) -> {
            tree.put(k, v);
        });
        // 得到排序结果
        tree.forEach((k, v) -> {
            System.out.println(k + ": " + v);
        });
   }

第三步   排序算法2 通过StreamApi 排序

  
  private static void sortedStream() {
        // 将 map 转化为 tream流
        map.entrySet().stream()
                // 进行排序
                .sorted(Collections.reverseOrder(Map.Entry.comparingByValue((o1, o2) -> Integer.compare(o1.age, o2.age))))
                // 遍历排序结果
                .forEach(System.out::println);
   }

第四步   排序算法3***  最好的答案

 HashMap是通过hash码进行分桶, 那么值肯定是乱的, 就算排序完毕重新放进去也是乱的, 但是HashMap有个

 子类 LinkedHshMap 

 LinkedHshMap 内部维持了一个双向链表,  可以保持顺序  既然让返回HashMap  那么就可以用到它


    /**
     * List + Connections + linkedHashMap 排序
     */
    private static void sortLinkedHashMap() {
        // 先将 Map 的值放到 List 集合中
        ArrayList<Map.Entry<Integer, User>> list = new ArrayList<>(map.entrySet());
        // 通过 Collections 的 sort 方法进行排序
        Collections.sort(list, (o1, o2) -> Integer.compare(o2.getValue().age, o1.getValue().age));
        // 到这里list已经排序完了 将 List 的数据放到 LinkedHashMap 中
        LinkedHashMap<Integer, User> linkedHashMap = new LinkedHashMap<Integer, User>() {{
            list.forEach((s) -> {
                this.put(s.getKey(), s.getValue());
            });
        }};
        // 遍历排序结果
        linkedHashMap.forEach((k, v) -> {
            System.out.println(k + ": " + v);
        });
    }

 第五步   测试结果

A:\Work\jdk1.8\bin\java.exe ... 

5=User{age=5, name='栓蛋'}
2=User{age=4, name='寒王'}
7=User{age=3, name='面筋哥'}
1=User{age=2, name='王花花'}
4=User{age=1, name='张三丰'}

5: User{age=5, name='栓蛋'}
2: User{age=4, name='寒王'}
7: User{age=3, name='面筋哥'}
1: User{age=2, name='王花花'}
4: User{age=1, name='张三丰'}

5: User{age=5, name='栓蛋'}
2: User{age=4, name='寒王'}
7: User{age=3, name='面筋哥'}
1: User{age=2, name='王花花'}
4: User{age=1, name='张三丰'}


Process finished with exit code 0

结束

  这就是对本题的讲解  可能不是特别好的方法  感觉有用就点个赞吧 如果有错误或更好的方法评论区请多多指出  相互学习共同进步