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

时间:2018-08-06 06:43:05

标签: java lambda filter java-8 java-stream

如果该列表包含具有相同元素的唯一对象,如何从列表中删除对象?

    RewriteEngine On
    RewriteCond %{QUERY_STRING} ID=(\w+)$
    RewriteRule ^actualites/details.php(.*) /actualite.php?id=%1 [L]

现在如何将用户列表排序或过滤到仅包含u1,u2,u4,u5的新列表,因为u2,u3具有相同的电子邮件。

我尝试使用所有这些选项 1)

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);

2)

List<UserDTO> newUsersList =    uers.stream().distinct().collect(Collectors.toList());

3)

List<UserDTO> newUsersList =  users.stream().filter(o-> ! o.getEmail().equalsIgnoreCase(users.parallelStream().findAny().get().getEmail())).collect(Collectors.toList());

4)

 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());
}

2 个答案:

答案 0 :(得分:1)

如果您可以覆盖hashCodeequals,请遵循Ravindra Ranwala的说明并使用Set

    Collection<UserDTO> unique = new HashSet<>(users);

如果无法覆盖它们,则可以使用TreeSet并为其提供自定义Comparator

    Collection<UserDTO> unique = new TreeSet<>(Comparator.comparing(UserDTO::getEmail));
    unique.addAll(users);

尽管非常简单,但是这些方法的缺点是失去了元素的顺序。如果这很重要,请尝试“手动”从List删除重复项:

    Collection<String> uniqueEmails = new HashSet<>();
    users.removeIf(user -> !uniqueEmails.add(user.getEmail()));

您还可以在filter的{​​{1}}阶段中使用此方法:

Stream

您可以使用这种方法或Eran的答案看到,基于纯流的解决方案并不简单。他们必须依靠外部状态或创建临时集合/映射来实现过滤。实现 users.stream() .filter(user -> uniqueEmails.add(user.getEmail())) ... / hashCode时,它变得更加简单。

答案 1 :(得分:0)

您可以使用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().distinct().collect(Collectors.toList())类的equals只比较电子邮件地址的情况下,UserDTO尝试才有效(这意味着具有相同电子邮件的两个实例将被视为相等)。 / p>