使用 Comparator 按 Map 值对 Map 进行排序

Sorting Map using Comparator by Map value

小伙子们 我不确定我是否看到了适合我情况的答案,尽管有很多看起来相似的答案。 反正我是个JAVA菜鸟,还请多多包涵

这是交易: 1. 我有一些 class 是礼物,比方说,一个名字是字符串的人。 2. Aslo 我有一个 Comparator (MyComparator),它为 Persons 实现了一个 Comparator 接口。 Comparator 的构造函数假定所有可比较对象(Persons)都将保存在 Map 中。 在 Comparator 中,我有一个 int compare (Person p1, Person p2) 方法,它是通过以下方式编写的:

   public int compare (Person personOne, Person personTwo) {
      if (personsMap.get(personOne)>personsMap.get(personTwo)) {
         return 1;
      } else if (personsMap.get(personOne)<personsMap.get(personTwo)) {
         return -1;
      } else {
        return 0;
      }

当我运行这样的事情时:

public static void main (String[] args) {
    Person p1 = new Person ("Willy");
    Person p2 = new Person ("Billy");
    Person p3 = new Person ("Dilly");

    Map<Person, Integer> t = new HashMap<Person, Integer>();
    t.put(p1,12);
    t.put(p2,2);
    t.put(p3,100);

    List<Person> pl = new Arrays.asList(p1,p2,p3);
        Collections.sort(pl, new MyComparator(t));
}

我在下一行的 MyComparator 中得到 NPE:

 if (personsMap.get(p1)>personsMap.get(p2)) 

请给我一个线索,如何解决这个问题。 提前致谢。

请出示您的 Comparator class 代码。以下代码适用于您的情况。 但不清楚为什么要使用 map 而不是 Person

中的一个字段
public class Clazz {
    public static void main (String[] args) {
        Person p1 = new Person ("Willy");
        Person p2 = new Person ("Billy");
        Person p3 = new Person ("Dilly");

        Map<Person, Integer> t = new HashMap<Person, Integer>();
        t.put(p1,12);
        t.put(p2,2);
        t.put(p3,100);

        List<Person> pl = Arrays.asList(p1,p2,p3);
        Collections.sort(pl, new MyComparator(t));
        // [Person{name='Billy'}, Person{name='Willy'}, Person{name='Dilly'}]
        System.out.println(pl);
    }
}

class Person {
    private final String name;

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

    @Override
    public String toString() {
        return "Person{" +
            "name='" + name + '\'' +
            '}';
    }
}
class MyComparator implements Comparator<Person> {

    private Map<Person, Integer> t;

    public MyComparator(Map<Person, Integer> t) {
        this.t = t;
    }

    public int compare(Person o1, Person o2) {
        if (t.get(o1) < t.get(o2)) return -1;
        if (t.get(o1) == t.get(o2)) return 0;
        return 1;
    }
}

适合我....

    public class Person {
    String name;

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

    public static void main (String[] args) {
        Person p1 = new Person ("Willy");
        Person p2 = new Person ("Billy");
        Person p3 = new Person ("Dilly");

        Map<Person, Integer> t = new HashMap<Person, Integer>();
        t.put(p1,12);
        t.put(p2,2);
        t.put(p3,100);

        List<Person> pl = Arrays.asList(p1, p2, p3);
        Collections.sort(pl, new MyComparator(t));
    }

}

class MyComparator implements  Comparator<Person>{
      private Map<Person, Integer> personsMap;

    public MyComparator(Map<Person, Integer> t) {
          this.personsMap = t;
    }

    public int compare (Person personOne, Person personTwo) {
          if (personsMap.get(personOne)>personsMap.get(personTwo)) {
             return 1;
          } else if (personsMap.get(personOne)<personsMap.get(personTwo)) {
             return -1;
          } else {
            return 0;
          }
}
}

我猜你没有在比较器的构造函数中初始化地图..

public MyComparator(Map<Person, Integer> t) {
        this.personsMap = t;
}

这是最有可能患上 NPE 的情况。但是您还没有插入所有比较器 class 所以这只是一个猜测 ..

请注意,您可以使用流和 lambda 以函数式方式执行此操作,而无需定义适当的比较器。我用 String 作为键,但你当然可以使用 Person.

Map<String, Integer> map = new HashMap<>();
map.put("Willy", 12);
map.put("Billy", 2);
map.put("Dilly", 100);

List<String> list = map.entrySet()
                    .stream()
                    .sorted(Comparator.comparing(Entry::getValue))
                    .map(e -> e.getKey())
                    .collect(Collectors.toList());

System.out.println(list);
// ["Billy", "Willy", "Dilly"]