有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

在Java中,按对象参数对映射<对象,列表<对象>>进行排序

你能帮我把这样的地图分类吗

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

其中键对象的一个参数为numberOfSeats 而且整个地图应该按照最多的座位数按相反的顺序排序。 我试着用streamAPI来实现它,但似乎无法实现

比如:

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

共 (3) 个答案

  1. # 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. # 2 楼答案

    因为你明确地说你有一个Map<Object,List<Object>>,我将把这个限制在那个场景中

    首先,创建一些测试数据

    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;
        }
    }
    
  3. # 3 楼答案

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

    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