简体   繁体   English

如何使用比较器实现Treemap?

[英]how to implement Treemap with comparator?

The error that i was facing in this Question has been solved and is written below in answer section. 我在此问题中遇到的错误已解决,并写在下面的“答案”部分。

The problem was that the below definition of TreeMap is throwing a compiler error and I wanted to know the reason. 问题是,TreeMap的以下定义引发了编译器错误,我想知道原因。

Comparator<Student> comparator=new Comparator<Student>() {

            @Override
            public int compare(Student o1, Student o2) {
                // TODO Auto-generated method stub
                if(o1.roll<=o2.roll)
                    return -1;
                else return 1;
            }
        };
        TreeMap<Integer, Student> map=new TreeMap<>(comparator);

I dont understand the reason this implementation of Treemap is wrong. 我不了解Treemap的此实现错误的原因。 Can anyone please explain me about what is going on in here? 谁能解释一下这里发生的事情吗?

compare() needs to handle three cases: less than, greater than, and equal. compare()需要处理三种情况:小于,大于和等于。 You need to return 0 when they're equal. 当它们相等时,您需要返回0

if (o1.roll == o2.roll) {
    return 0;
}
else if (o1.roll < o2.roll) {
    return -1;
}
else {
    return 1;
}

Integer.compare(int x, int y) can do all of this for you: Integer.compare(int x, int y)可以为您完成所有这些操作:

public int compare(Student o1, Student o2) {
    return Integer.compare(o1.roll, o2.roll);
}

In Java 8 you can create the entire comparator in a single line: 在Java 8中,您可以在一行中创建整个比较器:

Map<Integer, Student> map = new TreeMap<>(Comparator.comparingInt(s -> s.roll));

TL;DR: A comparator for a TreeMap<Integer, Student> needs to compare Integer s, not Student s. TL; DR: TreeMap<Integer, Student>比较器需要比较Integer而不是Student

A TreeMap<Integer, Student> maps from integers (“the keys”) to student objects (“the values”) and keeps the mappings sorted by the integers. TreeMap<Integer, Student>从整数(“键”)到学生对象(“ values”)的映射,并按整数对映射进行排序。 Therefore the constructor does not accept a Comparator<Student> as argument. 因此,构造函数不接受Comparator<Student>作为参数。

According to the documentation of TreeMap<K,V> , the constructor taking a comparator as argument is declared as 根据TreeMap<K,V>的文档,以比较器为参数的构造函数声明为

    TreeMap​(Comparator<? super K> comparator)

This means that the comparator must work on type K , the type of the keys, or some supertype of K . 这意味着比较器必须在类型K ,键的类型或K某些超类型上工作。 In your case, K is Integer . 在您的情况下, KInteger

Since the Integer class already defines an ordering, the so-called natural ordering, I suggest you don't need a comparator at all: 由于Integer类已经定义了一种顺序,即所谓的自然顺序,因此我建议您根本不需要比较器:

    TreeMap<Integer, Student> map = new TreeMap<>();        

If you wanted to store the students by their roll number, just insert them like this: 如果您想按学生的roll号存储他们,只需像这样插入他们:

        Student me = new Student();
        map.put(me.roll, me);

The side effect will be that the map is sorted by roll . 副作用是地图按roll排序。

PS The information in the answer by John Kugelman is correct too, a comparator needs to handle three cases. PS John Kugelman回答中的信息也是正确的,比较器需要处理三种情况。 And Comparator.comparingInt(s -> s.roll) or Comparator.comparingInt(Student::getRoll) (if the class has such a getter) is recommended, not only for the terseness, even more because it's less error-prone. 推荐使用Comparator.comparingInt(s -> s.roll)Comparator.comparingInt(Student::getRoll) (如果该类具有这种吸气剂),不仅是为了简洁,而且还因为它不容易出错而被推荐使用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM