Коллекции Treemap и TreeSet Не могу дописать компаратор

Рейтинг: -1Ответов: 1Опубликовано: 17.05.2023

Задача реализовать компаратор, сортировка которым расставит кандидатов по убыванию их приоритета найма в астронавты. Ничего кроме класса компаратора менять нельзя.

Программа в main в итоге должна выводить имена двух самых лучших кандидатов

  1. тот у кого больше опыта;
  2. если опыт одинаковый то тот, у кого в имени с фамилией (т.е. name) больше букв s или S (от слова space - космос; было решено, что медийность - важная часть космонавтики);
  3. если по этому критерию оказываются равны, то тот, у кого имя с фамилией (т.е. name) короче (так легче будет запоминать имена астронавтов по всему миру)
import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet;


public class Main {

    public static void main(String[] args) {
        TreeSet<Person> candidates = new TreeSet<>(new SpacePersonComparator());
        candidates.add(new Person("Sonya Popova", 35, 15));
        candidates.add(new Person("Dazdraperma Sponzhova", 33, 15));
        candidates.add(new Person("Salavat Netologshvili", 23, 13));
        candidates.add(new Person("Sasha Sun", 31, 15));
        candidates.add(new Person("Svetlana Morkov", 38, 15));
        candidates.add(new Person("Sasha Sosnova", 38, 11));

        Iterator<Person> it = candidates.iterator();
        System.out.println(it.next());
        System.out.println(it.next());
    }
}
class Person {
    private String name;
    private int age;
    private int experience;

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

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public int getExperience() {
        return experience;
    }

    @Override
    public String toString() {
        return name;
    }
}
class SpacePersonComparator implements ... { // укажите интерфейс
        // имплементируйте его

}

Ответы

▲ 2Принят

Компаратор SpacePersonComparator должен реализовать интерфейс Comparator<Person>, то есть, в нём следует переопределить метод Comparator::compare.

При этом сравнение по опыту работы (experience) и количеству букв 'S' должно выполняться в обратном порядке (чтобы люди были отсортированы по убыванию).

Вариант реализации в классическом стиле до Java 8:

class SpacePersonComparator implements Comparator<Person> {
    @Override
    public int compare(Person p1, Person p2) {
        int res = Integer.compare(p2.getExperience(), p1.getExperience()); // по убыванию опыта
        if (res == 0) {
            res = Integer.compare(countS(p2.getName()), countS(p1.getName())); // по убыванию количества 'S'
        }
        if (res == 0) {
            res = Integer.compare(p1.getName().length(), p2.getName().length()); // по возрастанию длины имени
        }
        return res;
    }    

    private static int countS(String name) {
        return name.replaceAll("[^Ss]", "").length();
    }
}

Результат теста:

Sasha Sun
Sonya Popova

Начиная с Java 8, в котором появились функциональные интерфейсы, лямбда-выражения, ссылки на методы, реализация компараторов в отдельном классе уже не является необходимой, и они могут определяться в "декларативном" стиле:

Comparator<Person> spacePersonComparator = Comparator.
    comparing(Person::getExperience, Comparator.reverseOrder())
    .thenComparing(p -> countS(p.getName()), Comparator.reverseOrder())
    .thenComparingInt(p -> p.getName().length());

TreeSet<Person> candidates = new TreeSet<>(spacePersonComparator);
// ...