Create a sorted Set while using streams

后端 未结 4 854
佛祖请我去吃肉
佛祖请我去吃肉 2021-01-12 04:06

I have a User class with name, type and age and then a long list of these users are my input List users = db.getUsers();<

相关标签:
4条回答
  • 2021-01-12 04:44

    It doesn't make sense to speak of order within a non sorted set. You should be using something like TreeSet if you want a set ordered by age.

    Comparator<User> byAge = Comparator.comparingInt(User::getAge);
    
    Supplier<TreeSet<User>> user = () -> new TreeSet<User>(byAge);
    
    TreeSet<User> userSet = users.stream().collect(Collectors.toCollection(user));
    

    If the above code be ugly to you, you could also just add your current set of users to a TreeSet, but there would be one more copy step.

    The main difference between using a TreeSet and a LinkedHashSet has to do with maintaining sorting order. With a TreeSet, when adding new users, the sorting would be maintained. With a LinkedHashSet, adding new users might break the sort order by age, because LinkedHashSet only maintains insertion order.

    Edit:

    Based on the comments by @Federico below, a TreeSet actual would use its comparator to determine equality of User objects. If you wanted to first remove all duplicate users by means of the equals() method, then we can first add all users to a HashSet, and then use the above approach to add them to a TreeSet.

    Set<User> set = new HashSet<>(users);   // remove duplicates via equals
    TreeSet<User> userSet = set.stream().collect(Collectors.toCollection(user));
    
    0 讨论(0)
  • 2021-01-12 04:46

    Here's one way of doing it assuming you have equals and hashcode methods implemented in the User class properly.

    Set<User> uniqueUsers = new HashSet<>(users);
    Set<User> sortedUniqueUsers = uniqueUsers.stream()
        .sorted(Comparator.comparingInt(User::getAge))
        .collect(Collectors.toSet());
    
    0 讨论(0)
  • 2021-01-12 05:05

    You can possibly sort while streaming and collect to a Set.

    Something like:

    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
    

    Do note, that your object User should be comparable for that. i.e. has overriden equals and hashCode.

    Side note: Your existing code could be simplified as:

    Set<User> users = new HashSet<>(users);
    
    0 讨论(0)
  • 2021-01-12 05:05

    Use Comparator on stream().sorted() method

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

    And implement Comparable in User class

    class User implements Comparable<User>{ 
    

    and add compareTo method

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

    As @nullpointer and @Ravindra pointed, I have missed adding Collection( like TreeSet or LinkedHashSet)

    0 讨论(0)
提交回复
热议问题