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

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


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.com

two  andy@gmail.com

four  ankit@gmail.com

five  amar@gmail.com


qq_花开花谢_0
浏览 148回答 2
2回答

斯蒂芬大帝

如果您可以覆盖hashCodeand equals,请按照 Ravindra Ranwala 的说明操作并使用Set:&nbsp; &nbsp; Collection<UserDTO> unique = new HashSet<>(users);如果您无法覆盖它们,您可以使用TreeSet并为其提供自定义Comparator:&nbsp; &nbsp; Collection<UserDTO> unique = new TreeSet<>(Comparator.comparing(UserDTO::getEmail));&nbsp; &nbsp; unique.addAll(users);虽然非常简单,但这些方法的缺点是会丢失元素的顺序。如果这很重要,请尝试从List“手动”中删除重复项:&nbsp; &nbsp; Collection<String> uniqueEmails = new HashSet<>();&nbsp; &nbsp; users.removeIf(user -> !uniqueEmails.add(user.getEmail()));您还可以将此方法用于 a 中的filter阶段Stream:&nbsp; &nbsp; users.stream()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.filter(user -> uniqueEmails.add(user.getEmail()))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;...正如您通过这种方法或 Eran 的回答所看到的,纯基于流的解决方案并不简单。他们要么依赖外部状态,要么创建临时集合/映射来实现过滤。实现hashCode/时它变得简单得多equals。

互换的青春

您可以使用电子邮件地址collectors.groupingBy对UserDTO实例进行分组,然后获取每个组的第一个实例:List<UserDTO> newUsersList =&nbsp; &nbsp; users.stream() // Stream<UserDTO>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.collect(Collectors.groupingBy(UserDTO::getEmail)) // Map<String,List<UserDTO>>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.values() // Collection<List<UserDTO>>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.stream() // Stream<List<UserDTO>>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.map(list -> list.get(0)) // Stream<UserDTO>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.collect(Collectors.toList()); // List<UserDTO> that has one instance for each&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // unique email该users.stream().distinct().collect(Collectors.toList())如果实现尝试只会工作equals的UserDTO类只比较电子邮件地址(这是指含相同的电子邮件两种情况将被视为相等)。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java