Компаратор, сравнивающий внутреннее поле списка - PullRequest
1 голос
/ 09 октября 2019

У меня есть такая модель

class Person {
     Instant updateDate; // mandatory
     List<Account> accounts; // can be empty
}

class Account {
    Instant accountUpdateDate; // can be null
}  

Предположим, у меня есть список людей (у каждого человека есть список учетных записей, который может быть пустым)

Как я могу получить человека сmax accountUpdateDate, в противном случае я должен получить человека с max updateDate.

Что-то в этом роде

Comparator<Person> UPDATE_DATE_COMPARATOR = Comparator
    .comparing(person -> person.getAccounts().stream().map(Account::getAccountUpdateDate)..., Comparator.nullsFirst(naturalOrder()))
    .thenComparing(Person::getUpdateDate));

Collections.max(personList, UPDATE_DATE_COMPARATOR);

1 Ответ

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

Одним из способов сделать это может быть использование orElseGet для разделения обеих функций, таких как:

Supplier<Person> supplyMaxUpdateDatePerson = () -> personList.stream()
        .max(Comparator.comparing(Person::getUpdateDate))
        .orElse(null); // or an identity value equivalent for 'Person'

Person maxAccountUpdateDateOrElseUpdateDate = personList.stream()
        .flatMap(person -> person.getAccounts().stream()
                .map(account -> new AbstractMap.SimpleEntry<>(person, account.getAccountUpdateDate())))
        .filter(entry -> entry.getValue() != null) // otherwise you would always have a result in max
        .max(Comparator.comparing(AbstractMap.SimpleEntry::getValue))
        .map(AbstractMap.SimpleEntry::getKey)
        .orElseGet(supplyMaxUpdateDatePerson); // invoked only when all 'accountUpdateDate' are 'null'
...