Как реализовать Treemap с компаратором? - PullRequest
0 голосов
/ 01 сентября 2018

Ошибка, с которой я столкнулся в этом Вопросе, была устранена и описана ниже в разделе ответов.

Проблема заключалась в том, что приведенное ниже определение 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);

Я не понимаю причину неправильной реализации Treemap. Может кто-нибудь объяснить мне, что здесь происходит?

Ответы [ 2 ]

0 голосов
/ 01 сентября 2018

TL; DR: Компаратор для TreeMap<Integer, Student> должен сравнивать Integer с, а не Student с.

A TreeMap<Integer, Student> отображается из целых чисел («ключи») в объекты учащихся («значения») и сохраняет сопоставления, отсортированные по целым числам. Поэтому конструктор не принимает Comparator<Student> в качестве аргумента.

Согласно документации TreeMap<K,V>, конструктор, принимающий компаратор в качестве аргумента, объявляется как

    TreeMap​(Comparator<? super K> comparator)

Это означает, что компаратор должен работать с типом K, типом клавиш или некоторым супертипом K. В вашем случае K - это Integer.

Поскольку класс Integer уже определяет порядок, так называемый естественный порядок, я полагаю, вам вообще не нужен компаратор:

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

Если вы хотите сохранить учеников по номеру roll, просто вставьте их так:

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

Побочным эффектом будет то, что карта отсортирована по roll.

PS Информация в ответе Джона Кугельмана также верна, компаратору необходимо обработать три случая. И Comparator.comparingInt(s -> s.roll) или Comparator.comparingInt(Student::getRoll) (если класс имеет такой метод получения) рекомендуется не только для краткости, но даже больше, потому что он менее подвержен ошибкам.

0 голосов
/ 01 сентября 2018

compare() необходимо обработать три случая: меньше, больше и равно. Вам нужно вернуть 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) может сделать все это для вас:

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

В Java 8 вы можете создать весь компаратор в одной строке:

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