Создать отсортированный набор при использовании потоков - PullRequest
0 голосов
/ 19 декабря 2018

У меня есть Пользователь класс с именем, типом и возрастом , а затем длинный список этих пользователей - мой ввод List<User> users = db.getUsers();.

Я пытаюсь создать набор всех уникальных пользователей из этого, но проблема в том, что я ищу сортировку их на основе age .В настоящее время я использовал -

Set<User> set = users.stream().collect(Collectors.toSet());

Как сортировать этот набор в то же время, любая идея?

Ответы [ 4 ]

0 голосов
/ 19 декабря 2018

Нет смысла говорить о порядке в несортированном множестве.Вы должны использовать что-то вроде TreeSet, если хотите, чтобы набор упорядочивался по возрасту.

Comparator<User> byAge = Comparator.comparingInt(User::getAge);

Supplier<TreeSet<User>> user = () -> new TreeSet<User>(byAge);

TreeSet<User> userSet = users.stream().collect(Collectors.toCollection(user));

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

Основное различие между использованием TreeSet и LinkedHashSet связано с поддержанием порядка сортировки.При TreeSet при добавлении новых пользователей сортировка будет поддерживаться.При LinkedHashSet добавление новых пользователей может нарушить порядок сортировки по возрасту, поскольку LinkedHashSet поддерживает только порядок вставки.

Редактировать:

На основе комментариевсогласно @Federico ниже, фактический TreeSet будет использовать свой компаратор для определения равенства User объектов.Если вы хотите сначала удалить всех дублирующихся пользователей с помощью метода equals(), то мы можем сначала добавить всех пользователей в HashSet, а затем использовать описанный выше подход для добавления их в TreeSet.

Set<User> set = new HashSet<>(users);   // remove duplicates via equals
TreeSet<User> userSet = set.stream().collect(Collectors.toCollection(user));
0 голосов
/ 19 декабря 2018

Вы можете sort во время потоковой передачи и собирать в Set.

Что-то вроде:

Set<User> finalList = users.stream()
        .sorted(Comparator.comparing(User::getAge)) // sort while streaming
        .collect(Collectors.toCollection(LinkedHashSet::new)); 
        // note collecting to a set that maintains the order

Обратите внимание, что ваш объект User должен быть сопоставим длятот.т.е. переопределил equals и hashCode.

Примечание : Ваш существующий код может быть упрощен как:

Set<User> users = new HashSet<>(users);
0 голосов
/ 19 декабря 2018

Вот один из способов сделать это при условии, что у вас правильно реализованы методы equals и hashcode в классе User.

HashSet<User> uniqueUsers = new HashSet<>(users);
List<User> sortedUniqueUsers = uniqueUsers.stream()
    .sorted(Comparator.comparingInt(User::getAge))
    .collect(Collectors.toList());
0 голосов
/ 19 декабря 2018

Используйте Comparator для stream (). Sorted () метод

Set<User> set = users.stream().sorted(Comparator.comparing(User::getAge)).collect(Collectors.toCollection(LinkedHashSet::new));

И реализуйте Comparable в классе пользователя

class User implements Comparable<User>{ 

и добавьте метод CompareTo

@Override
public int compareTo(User ob) {
    return age-ob.getAge();
}

Как указали @nullpointer и @Ravindra, я пропустил добавление Collection (например, TreeSet или LinkedHashSet)

...