Подтвердить что ты не робот

Сортировка по свойствам в потоке Java 8

О, эти хитрые потоки Java 8 с лямбдами. Они очень мощные, но тонкости немного затягивают вокруг одного заголовка.

Скажем, у меня есть тип User со свойством User.getName(). Скажем, у меня есть карта этих пользователей Map<String, User>, связанных с именами (например, имена пользователей входа). Позвольте еще сказать, что у меня есть экземпляр компаратора UserNameComparator.INSTANCE для сортировки имен пользователей (возможно, с фантастическими коллабораторами и т.д.).

Итак, как мне получить список пользователей на карте, отсортированный по имени пользователя? Я могу игнорировать ключи карты и делать это:

return userMap.values()
    .stream()
    .sorted((u1, u2) -> {
      return UserNameComparator.INSTANCE.compare(u1.getName(), u2.getName());
    })
    .collect(Collectors.toList());

Но эта строка, где мне нужно извлечь имя для использования UserNameComparator.INSTANCE, кажется слишком большой ручной работой. Есть ли способ, который я могу просто предоставить User::getName как некоторую функцию сопоставления, только для сортировки, и все еще получить экземпляры User в собранном списке?

Бонус: что, если вещь, которую я хотел сортировать, была на два уровня глубокой, например User.getProfile().getUsername()?

4b9b3361

Ответ 1

Вы хотите Comparator#comparing:

userMap.values().stream()
    .sorted(Comparator.comparing(User::getName, UserNameComparator.INSTANCE))
    .collect(Collectors.toList());

Во второй части вашего вопроса вы просто используете

Comparator.comparing(
    u->u.getProfile().getUsername(), 
    UserNameComparator.INSTANCE
)