Не работает лямбда выражение в Collectors.toMap()

128
09 декабря 2020, 19:30

Пытаюсь собрать мапу с помощью стрима, падает ClassCastException. В общем, есть класс Person:

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

Мне нужно создать Map с помощью stream, и объекты там должны быть отсортированы по возрасту. Я пишу:

Person person1 = new Person("b", 1);
Person person2 = new Person("c", 2);
Person person3 = new Person("a", 3);
List<Person > personList = new ArrayList<>();
personList.add(person1);
personList.add(person2);
personList.add(person3);
Map<String, Person> map = personList.stream()
                .sorted().collect(Collectors.toMap((o -> o.getName()), o -> o)); 

У меня падает ClassCastException. Не могу понять как должно выглядеть лямбда выражение внутри toMap(). И еще вопрос, как указать методу sorted сравнивать объекты именно по возрасту, у меня получалось только по имени, я использовал compareTo(), но int - примитив и тут этот вариант не работает.

Буду благодарен за любую помощь.

Answer 1

Во-первых, классу Person нужны геттеры

class Person {
    private String name;
    private int age;
    public Person (String name, int age) {
        this.name = name;
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public int getAge() {
        return age;
    }
}

Во-вторых, методу sorted нужен компаратор, который будет сравнивать элементы

Map<String, Person> map = personList.stream()
  .sorted(Comparator.comparingInt(Person::getAge))
  .collect(Collectors.toMap(Person::getName, Function.identity()));

А чтобы гарантировать сохранение упорядоченности элементов в результирующей коллекции, стоит явно указать её реализацию:

.collect(Collectors.toMap(Person::getName,
                          Function.identity(),
                          (a, b) -> a,
                          LinkedHashMap::new));

UPD: Чтобы собрать в Map один элемент с самым большим возрастом

Map<String, Person> map = personList.stream()
  .sorted(Comparator.comparingInt(Person::getAge).reversed())
  .limit(1)
  .collect(Collectors.toMap(Person::getName, Function.identity()));

Но тогда непонятно, зачем нужен Map для одного элемента. Можно просто

Person person = personList.stream()
                          .max(Comparator.comparingInt(Person::getAge))
                          .get();
READ ALSO
Экранирование html символов в строках

Экранирование html символов в строках

Есть JSON со строковым значениемВ этом значении есть недопустимые символы (абзац, кавычки и т

153
Почему выдаёт ошибку StringIndexOutOfBoundsException: String index out of range

Почему выдаёт ошибку StringIndexOutOfBoundsException: String index out of range

Есть два класса: Bot и ParserДо недавнего времени бот парсил весь текст как надо, но после добавления класса TheGame появилась эта ошибка

132
Синхронизация Map

Синхронизация Map

Если из разных потоков в HashMap добавляются (только добавляются и не более того) записи, то необходимо ли при этом синхронизировать вызов метода...

153
A JNI error has occured, please check your installation and try again

A JNI error has occured, please check your installation and try again

При запускеjar файла возникает следующая ошибка:

272