为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

qq_花开花谢_0 2021-06-09 17:14:57
如果该列表具有具有相同元素的唯一对象,如何从列表中删除这些对象?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);现在如何将此用户列表排序或过滤到只有 u1,u2,u4,u5 的新列表,因为 u2,u3 具有相同的电子邮件。我尝试使用所有这些选项 1)List<UserDTO> newUsersList =    uers.stream().distinct().collect(Collectors.toList());2)List<UserDTO> newUsersList =  users.stream().filter(o-> ! o.getEmail().equalsIgnoreCase(users.parallelStream().findAny().get().getEmail())).collect(Collectors.toList());3) List<UserDTO> newUsersList =  users2.stream().filter(o-> users2.stream().map(UserDTO::getEmail).anyMatch(p -> !p.equalsIgnoreCase(o.getEmail()))).collect(Collectors.toList());4)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.comtwo  andy@gmail.comfour  ankit@gmail.comfive  amar@gmail.com
查看完整描述

2 回答

?
斯蒂芬大帝

TA贡献1827条经验 获得超8个赞

如果您可以覆盖hashCodeand equals,请按照 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()));

您还可以将此方法用于 a 中的filter阶段Stream:


    users.stream()

         .filter(user -> uniqueEmails.add(user.getEmail()))

         ...

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


查看完整回答
反对 回复 2021-06-30
?
互换的青春

TA贡献1797条经验 获得超6个赞

您可以使用电子邮件地址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类只比较电子邮件地址(这是指含相同的电子邮件两种情况将被视为相等)。


查看完整回答
反对 回复 2021-06-30
  • 2 回答
  • 0 关注
  • 147 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信