Java 通过从具有不同对象的重复元素的列表中删除对象来创建新的独特列表

Java 通过从具有不同对象的重复元素的列表中删除对象来创建新的独特列表,java,lambda,filter,java-8,java-stream,Java,Lambda,Filter,Java 8,Java Stream,如果列表中有具有相同元素的唯一对象,如何从列表中删除这些对象 static class UserDTO { private String name; private String email; public String getName() { return name; } public void setName(String name) { this.name

如果列表中有具有相同元素的唯一对象,如何从列表中删除这些对象

static class UserDTO {

        private String name;
        private String email;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getEmail() {
            return email;
        }

        public void setEmail(String email) {
            this.email = email;
        }

    }

        UserDTO u1 = new UserDTO();
        u1.setEmail("alex@gmail.com");
        u1.setName("one");

        UserDTO u2 = new UserDTO();
        u2.setEmail("andy@gmail.com");
        u2.setName("two");

        UserDTO u3 = new UserDTO();
        u3.setEmail("andy@gmail.com");
        u3.setName("three");

        UserDTO u4 = new UserDTO();
        u4.setEmail("ankit@gmail.com");
        u4.setName("four");


        UserDTO u5 = new UserDTO();
        u5.setEmail("amar@gmail.com");
        u5.setName("five");

        List<UserDTO> users = new ArrayList<>(); 
        users.add(u1);
        users.add(u2);
        users.add(u3);
        users.add(u4);
        users.add(u5);

您可以使用
collectors.groupingBy
按电子邮件地址将
UserDTO
实例分组,然后获取每个组的第一个实例:

List<UserDTO> newUsersList =
    users.stream() // Stream<UserDTO>
         .collect(Collectors.groupingBy(UserDTO::getEmail)) // Map<String,List<UserDTO>>
         .values() // Collection<List<UserDTO>>
         .stream() // Stream<List<UserDTO>>
         .map(list -> list.get(0)) // Stream<UserDTO>
         .collect(Collectors.toList()); // List<UserDTO> that has one instance for each
                                        // unique email
列出新用户列表=
users.stream()//流
.collect(Collectors.groupingBy(UserDTO::getEmail))//映射
.values()//集合
.stream()//流
.map(list->list.get(0))//流
.collect(Collectors.toList());//列表,每个列表有一个实例
//独特的电子邮件

users.stream().distinct().collect(Collectors.toList())
尝试只有在实现
UserDTO的
equals
类只比较电子邮件地址(这意味着具有相同电子邮件的两个实例将被视为相等)时才会起作用。

如果可以覆盖
hashCode
equals
,按照Ravindra Ranwala的说明使用
集合

    Collection<UserDTO> unique = new HashSet<>(users);
虽然非常简单,但这些方法的缺点是会丢失元素的顺序。如果这很重要,请尝试从
列表中手动删除重复项:


正如您通过这种方法或Eran的答案所看到的,纯基于流的解决方案并不简单。它们必须依赖外部状态或创建临时集合/映射来实现过滤。当实现
hashCode
/
equals

时,它变得简单多了。我认为最后一种方法是最简单的,副作用最少(比如重写方法或丢失元素顺序)。
 List<UserDTO> newUsersList =  users2.stream().filter(o-> users2.stream().map(UserDTO::getEmail).anyMatch(p -> !p.equalsIgnoreCase(o.getEmail()))).collect(Collectors.toList());
Set<UserDTO> newUsersList = users2.stream().filter(o-> users2.stream().map(UserDTO::getEmail).anyMatch(p -> !p.equalsIgnoreCase(o.getEmail()))).collect(Collectors.toSet());
List<UserDTO> newUsersList = new ArrayList<>(); 

for(UserDTO u :newUsersList ) {
    System.out.println(u.getName() + "  "+u.getEmail());
}
one  alex@gmail.com
two  andy@gmail.com
four  ankit@gmail.com
five  amar@gmail.com
List<UserDTO> newUsersList =
    users.stream() // Stream<UserDTO>
         .collect(Collectors.groupingBy(UserDTO::getEmail)) // Map<String,List<UserDTO>>
         .values() // Collection<List<UserDTO>>
         .stream() // Stream<List<UserDTO>>
         .map(list -> list.get(0)) // Stream<UserDTO>
         .collect(Collectors.toList()); // List<UserDTO> that has one instance for each
                                        // unique email
    Collection<UserDTO> unique = new HashSet<>(users);
    Collection<UserDTO> unique = new TreeSet<>(Comparator.comparing(UserDTO::getEmail));
    unique.addAll(users);
    Collection<String> uniqueEmails = new HashSet<>();
    users.removeIf(user -> !uniqueEmails.add(user.getEmail()));
    users.stream()
         .filter(user -> uniqueEmails.add(user.getEmail()))
         ...