使用比较器按地图值对地图进行排序

时间:2016-05-24 15:07:15

标签: java sorting maps

小伙子 我不确定我是否已经看到任何适合我情况的答案,尽管对于看起来相似的情况有很多答案。 无论如何,我是一个JAVA菜鸟,所以请放纵。

这是交易: 我有一些课程,比方说,一个名字的人是一个字符串。 2.我有一个Comparator(MyComparator),它为Persons实现了Comparator接口。 比较器的构造函数假定所有可比较的对象(人员)将保存在Map中。 在Comparator中我有一个int比较(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)) 

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

4 个答案:

答案 0 :(得分:0)

请出示您的Comparator课程代码。以下代码适用于您的情况。 但目前尚不清楚为何使用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;
    }
}

答案 1 :(得分:0)

为我工作....

    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;
          }
}
}

答案 2 :(得分:0)

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

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

这是您可以拥有NPE的最可能的情况。但是你还没有插入所有的比较器类,所以这只是猜测..

答案 3 :(得分:0)

请注意,您可以使用streams和lambda以功能方式执行此操作,而无需定义正确的Comparator。我使用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"]