Как выполнить потоковую сортировку на основе множественных сравнений вложенного объекта? - PullRequest
0 голосов
/ 11 октября 2019

Пример модели:

Мне нужно отсортировать поток автомобилей по полу водителя, а затем по его возрасту.

public class Car {
    String color;
    Driver driver; 
}
public class Driver {
    String name;
    Integer age;
    String gender;  
}
public List<Car> sortCars(List<Car> cars) {
    return cars.stream()
        .sorted(Comparator
                .comparing(car -> -1 /* car.getDriver().getGender() */ )
                .thenComparing(car -> -1 /* car.getDriver().getAge() */ ))
        .collect(Collectors.toList());
}

Я не хочусоздавать специальные классы Comparator или реализовывать интерфейсы Comparator. Возможен ли мой вариант использования? Я просматривал ТАК в течение последнего часа, и ни один из ответов не работает.

Ответы [ 2 ]

2 голосов
/ 11 октября 2019

Возможно, вывод типа недостаточно силен. Это сработало для меня:

return cars.stream()
        .sorted(Comparator.comparing(car -> ((Car) car).getDriver().getGender())
                .thenComparingInt(car -> ((Car) car).getDriver().getAge()))
        .collect(Collectors.toList());
1 голос
/ 11 октября 2019

Ответ от @Kartik работает. Но если вы хотите избежать каста, у вас есть еще две опции:

Опция 1:

 Comparator<Car> com1 = Comparator.comparing(car -> car.getDriver().getGender());
 Comparator<Car> com2 = Comparator.comparing(car -> car.getDriver().getAge());

, затем:

cars.stream().sorted(com1.thenComparing(com2)).collect(Collectors.toList());

Опция 2:

Сообщите компилятору, что вы сравниваете Car s:

cars.stream().sorted(Comparator.comparing((Car car) -> car.getDriver().getGender())
    .thenComparing(car -> car.getDriver().getAge()))
                    .collect(Collectors.toList());

EDIT: На самом деле, у вас есть еще больше вариантов. Согласно комментарию @Andreas, вы можете передать тип по Comparator.<Car, String>comparing или просто написать свою собственную comparing функцию, которая будет выглядеть следующим образом:

sorted((car1, car2) -> {/*function body that returns -1, 0, 1 */}

Кроме того, если у вас есть List<Car>, выхотите отсортировать, вы можете напрямую использовать sort() метод:

cars.sort(com1.thenComparing(com2));
...