首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >如何从Map中获得按值排序然后按键排序的条目列表

如何从Map中获得按值排序然后按键排序的条目列表
EN

Stack Overflow用户
提问于 2022-03-22 14:26:53
回答 4查看 557关注 0票数 1

我的问题是如何根据Map内容的值和键对其进行排序,从而得到条目的List

首先,需要按照降序对条目进行排序,然后如果值发生冲突,还需要按照降序中的对它们进行排序。

给定的示例

代码语言:javascript
代码运行次数:0
运行
复制
Map<String,Integer> data = new HashMap();
data.put("a",10);
data.put("b",3);
data.put("c",10);

期望顺序:

代码语言:javascript
代码运行次数:0
运行
复制
["c", 10], ["a",10], ["b",3]
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2022-03-22 14:46:41

代码语言:javascript
代码运行次数:0
运行
复制
public class Person implements Comparable<Person>{

    private String name;
    private Integer age;

    public Person(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public int compareTo(Person person) {
        if(this.age!= person.age){
            return person.age.compareTo(this.age);
        } else {
         return person.name.compareTo(this.name);
        }
    }

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

    public static void main(String argsp[]){
        Map<String,Integer> data = new HashMap();
        data.put("a",10);
        data.put("b",3);
        data.put("c",10);

        List<Person> collect = data.entrySet().stream().map(entry -> new Person(entry.getKey(), entry.getValue())).collect(Collectors.toList());
        Collections.sort(collect);
        collect.stream().forEach(person-> System.out.println(person));

    Collection<Map.Entry<String,Integer>> result  = collect.stream().map(person -> 
            new AbstractMap.SimpleEntry<String, Integer>(person.name, person.age)).collect(Collectors.toList());


    }
}

结果:

代码语言:javascript
代码运行次数:0
运行
复制
Person{name='c', age=10}
Person{name='a', age=10}
Person{name='b', age=3}
票数 -1
EN

Stack Overflow用户

发布于 2022-03-22 16:45:17

为此,需要定义一个Comparator

为此,您可以使用静态方法,这些方法是作为、Java 8的增强添加到ComparatorMap.Entry接口中的。

comparingByValue()Map.Entry接口的comparingByKey()两种方法都将分别为值和键生成比较器。为了得到一个降阶方法,需要对其应用reversed()方法。

两个比较器都与thenComparing()方法链接在一起。

代码语言:javascript
代码运行次数:0
运行
复制
Comparator<Map.Entry<String, Integer>> valDescThenKeyDesc =
       Map.Entry.<String, Integer>comparingByValue().reversed()
           .thenComparing(Map.Entry.<String, Integer>comparingByKey().reversed());

请注意,编译器是,无法根据比较器的结果类型推断comparingByValue()comparingByKey()的正确参数类型,只能基于的。

因此,comparingByValue()comparingByKey()都需要显式地提供泛型类型信息<String, Integer> (键和值的类型)。

如果一开始看起来太难理解,您可能会将它分成几行(在本例中,类型推断工作得很好):

代码语言:javascript
代码运行次数:0
运行
复制
Comparator<Map.Entry<String, Integer>> byValDesc =
       Map.Entry.comparingByValue().reversed();

Comparator<Map.Entry<String, Integer>> byKeyDesc =
       Map.Entry.comparingByKey().reversed();

Comparator<Map.Entry<String, Integer>> valDescThenKeyDesc =
       byValDesc.thenComparing(byKeyDesc);

下一步是创建一个排序的条目列表。

为此,您可以通过将条目集传递给构造函数来手动创建条目的List,然后在其上应用sort()方法,或者使用Stream

为了用流来实现它,首先,我们需要获得一个条目流。通过传递给定的比较器执行sorting()操作,并通过应用终端操作collect()将结果收集到列表中。

代码语言:javascript
代码运行次数:0
运行
复制
public static List<Map.Entry<String, Integer>> getMapEntryList(Map<String,Integer> data,
                                                               Comparator<Map.Entry<String, Integer>> comparator) {
    return data.entrySet().stream()
            .sorted(comparator)
            .collect(Collectors.toList());
}

main()

代码语言:javascript
代码运行次数:0
运行
复制
public static void main(String[] args) {
    Map<String,Integer> data = Map.of("a",10, "b",3,"c",10);

    Comparator<Map.Entry<String, Integer>> valDescThenKeyDesc =
            Map.Entry.<String, Integer>comparingByValue().reversed()
                    .thenComparing(Map.Entry.<String, Integer>comparingByKey().reversed());

    List<Map.Entry<String, Integer>> result = getMapEntryList(data, valDescThenKeyDesc);
    
    System.out.println(result);
}

输出

代码语言:javascript
代码运行次数:0
运行
复制
[c=10, a=10, b=3]
票数 3
EN

Stack Overflow用户

发布于 2022-03-22 14:54:29

使用流api和自定义Comparator

代码语言:javascript
代码运行次数:0
运行
复制
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;

public class Main {

  static Map<String, Integer> createTestMap() {
    Map<String, Integer> data = new HashMap();
    data.put("a", 10);
    data.put("b", 3);
    data.put("c", 10);
    return data;
  }

  public static void main(String[] args) {
    var sorted = createTestMap().entrySet().stream()
        .sorted(Comparator
            .comparing(Map.Entry<String, Integer>::getValue)
            .thenComparing(Map.Entry<String, Integer>::getKey).reversed())
        .collect(Collectors.toList());
    for (var kv : sorted) {
      System.out.println(
          String.format("%s\t%s", kv.getKey(), kv.getValue()));
    }
  }
  }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71573763

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档