• Java根据一个List内Object的两个字段去重


    背景

    Java开发过程中,我们经常会遇到需要对List进行去重的需求。
    其中常见的情况是,将数组去重,或者将对象依据某个字段去重。这两种方式均可用set属性进行处理。
    今天讨论,有一个List,且其中的元素是自定义的对象,我们需要根据对象的某两个字段的值来进行去重,并得到去重后的结果。

    整理过程如下:
    在这里插入图片描述

    方案一

    1、基础准备

    假设需要对人员(User)去重,依据编号(code)和名称(name)去重

    2、原始LIst
    List<User> userList = Arrays.asList(new User("1","张三"), new User("2","李四"), new User("2","李四"), new User("2","李四"));
    
    • 1
    3、去重

    使用Java 8的Stream API来实现去重

    1、使用stream()方法将List转换成Stream。
    2、使用distinct()方法去除重复的元素。
    3、使用collect(Collectors.toList())将去重后的Stream转换成List。
    
    • 1
    • 2
    • 3
    List<User> distinctList = userList.stream().distinct().collect(Collectors.toList());
    
    • 1
    4、查看去重后的数据
    for (User user : distinctList) {
        System.out.println("编号:" + user.getCode() + ",名称:" + user.getName());
    }
    
    • 1
    • 2
    • 3
    5、代码如下

    人员(User.java)

    package com;
    
    public class User {
    
        private String code;
        
        private String name;
    
        public String getCode() {
            return code;
        }
    
        public void setCode(String code) {
            this.code = code;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
        
        public User() {
            
        }
        
        public User(String code, String name) {
            this.code = code;
            this.name = name;
        }
        
        @Override
        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }
            if (obj == null || getClass() != obj.getClass()) {
                return false;
            }
            User other = (User) obj;
            return code.equals(other.code) && name.equals(other.name);
        }
    
        @Override
        public int hashCode() {
            return Objects.hash(code, name);
        }
        
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51

    测试类(Test .java)

    package com;
    
    import java.util.Arrays;
    import java.util.List;
    import java.util.stream.Collectors;
    
    public class Test {
        public static void main(String[] args) {
            List<User> userList = Arrays.asList(new User("1","张三"), new User("2","李四"), new User("2","李四"), new User("2","李四"));
            List<User> distinctList = userList.stream().distinct().collect(Collectors.toList());
            for (User user : distinctList) {
                System.out.println("编号:" + user.getCode() + ",名称:" + user.getName());
            }
    
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    6、打印结果

    在这里插入图片描述

    方案二

    1、使用工具类处理:

    人员(User.java)

    package com;
    
    import java.util.Objects;
    
    public class User {
        private String code;
    
        private String name;
    
        public String getCode() {
            return code;
        }
    
        public void setCode(String code) {
            this.code = code;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public User() {
    
        }
    
        public User(String code, String name) {
            this.code = code;
            this.name = name;
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    测试类(Test.java)

    package com;
    
    import org.apache.commons.lang.StringUtils;
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.Comparator;
    import java.util.List;
    import java.util.Set;
    import java.util.TreeSet;
    
    public class Test {
        
        public static void main(String[] args) {
            List<User> userList = Arrays.asList(new User("1","张三"), new User("2","李四"), new User("2","李四"), new User("2","李四"));
            List<User> distinctList = removeDuplicateField(userList);
            for (User user : distinctList) {
                System.out.println("编号:" + user.getCode() + ",名称:" + user.getName());
            }
        }
    
        private static List<User> removeDuplicateField(List<User> list) {
            Set<User> set = new TreeSet<>(new Comparator<User>() {
                @Override
                public int compare(User o1, User o2) {
                    int compareToResult = 1;
                    if(StringUtils.equals(o1.getCode(), o2.getCode()) && StringUtils.equals(o1.getName(), o2.getName())) {
                        compareToResult = 0; // 0:重复
                    }
                    return compareToResult;
                }
            });
            set.addAll(list);
            return new ArrayList<>(set);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    关键代码:removeDuplicateField

    2、结果

    在这里插入图片描述

    3、拓展

    如上removeDuplicateField方法,可将该方法通过反射,修改成动态通用方法。
    JAVA通过反射获取和设置Bean属性(总结):https://blog.csdn.net/qq_38254635/article/details/115520411

    Java通过反射机制,动态设置对象属性值:https://blog.csdn.net/qq_38254635/article/details/115765808
    也就说说,可将compare中的比较方法,通过注解及反射的方式处理,获取Field的注解,根据固定注解进行比较处理,这样可将removeDuplicateField完善成可配置方法。

    弊端:如果使用场景较多,可采用配置的方式,如情况单一,从性能方面考虑,建议单独建立比较方法。

    参考链接:

    1、https://blog.51cto.com/u_16175434/7631997
    2、https://code84.com/850204.html

    如有不正确之处,还望指正!书写不易,觉得有帮助就点个赞吧!☺☺☺

  • 相关阅读:
    第5篇 熊猫烧香逆向分析(下)
    MoneyPrinterPlus:AI自动短视频生成工具-微软云配置详解
    Nautilus无法创建下列所需的文件夹:/home/user/Desktop 报错解决
    数据库实验:SQL的数据视图
    如何防止企业代码被抄袭?源代码加密软件来救援!
    遨博机械臂——末端工具ROS驱动
    使用Spring Boot和MyBatis访问数据库
    大集合里查询数据-布隆过滤器
    CCF CSP认证 历年题目自练Day30
    c/c++里 对 共用体 union 的内存分配
  • 原文地址:https://blog.csdn.net/qq_38254635/article/details/134035979