【问题标题】:Sorting a Map<Object, List<Object>> by Object Parameter in Java在 Java 中按对象参数对 Map<Object, List<Object>> 进行排序
【发布时间】:2021-05-11 06:47:15
【问题描述】:

你能帮我整理一下这样的地图吗

Map<Object, List<Object>> halls = new HashMap()<>;

其中关键对象的参数之一是 numberOfSeats 并且整个地图应该按照座位数的倒序排列。 我尝试用 streamAPI 来做,但我似乎无法让它工作。

类似:

 halls.entrySet().stream().sorted((h1, h2) -> h1.getSeatsNumber.compareTo(h2.getSeatsNumber));

【问题讨论】:

    标签: java sorting object stream maps


    【解决方案1】:

    不使用HashMap,而是创建一个按键排序的TreeMap,并提供一个自定义比较器:

    Map<MyObject, List<MyObject>> halls = new TreeMap<>(
            Comparator.comparingInt(MyObject::getSeatsNumber).reversed()
    );
    

    如果您有一组MyObject 需要收集到地图中,可以使用Collectors.groupingByTreeMap 的供应商来完成:

    List<MyObject> list = new ArrayList<>(); // input list of MyObject
    
    Map<MyObject, List<MyObject>> halls2 = list
            .stream()
            .collect(Collectors.groupingBy(
                x -> x,
                () -> new TreeMap<>(
                    Comparator.comparingInt(MyObject::getSeatsNumber).reversed()
                ),
                Collectors.toList()
            ));
    

    【讨论】:

      【解决方案2】:

      您可以使用按键比较,例如:

      halls.entrySet().stream()
                  .sorted(Map.Entry.comparingByKey(Comparator.comparing(YourObject::numberOfSeats).reversed()))
                  .collect(toMap(Map.Entry::getKey, Map.Entry::getValue, (s1, s2) -> s1, LinkedHashMap::new));
      

      如果你想对地图进行排序,你应该使用 LinkedHashMap。

      【讨论】:

        【解决方案3】:

        既然你特别说你有一个Map&lt;Object,List&lt;Object&gt;&gt;,我就把它限制在那个场景中。

        首先,创建一些测试数据。

        Map<Object, List<Object>> halls = Map.of(new MyClass(1),
                List.of("G", "H"), new MyClass(4), List.of("C", "D"),
                new MyClass(7), List.of("A", "B"), new MyClass(3),
                List.of("E", "F"));
        

        现在对现有地图进行排序。要保留排序,您可以使用 LinkedHashMap 来维护插入顺序。但是,新添加的项目不会被排序,而是简单地添加到末尾。

        在这种情况下,您必须将密钥转换为您的实际班级名称才能获得席位,因为Object 对该方法一无所知。要颠倒排序,只需颠倒Integer.compare 方法中e1e2 的顺序即可。如果您使用 MyClass 而不是 Object 作为密钥,这可能会更容易一些。

        Map<Object, List<Object>> result = halls.entrySet().stream()
                .sorted((e1, e2) -> Integer.compare(
                        ((MyClass) e2.getKey()).getSeatsNumber(),
                        ((MyClass) e1.getKey()).getSeatsNumber()))
                .collect(Collectors.toMap(Entry::getKey,
                        Entry::getValue, (a, b) -> a,
                        LinkedHashMap::new));
        
        result.entrySet().forEach(System.out::println);
        

        以上打印。

        seats:7=[A, B]
        seats:4=[C, D]
        seats:3=[E, F]
        seats:1=[G, H]
        

        这是包含toString 覆盖的测试类。

        class MyClass {
            int seats = 0;
            
            public MyClass(int seats) {
                this.seats = seats;
            }
            
            public int getSeatsNumber() {
                return seats;
            }
            
            public String toString() {
                return "seats:"+seats;
            }
        }
        

        【讨论】:

          猜你喜欢
          • 2021-05-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-08-19
          • 2021-03-26
          • 2011-07-09
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多