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

背景

在Java开发过程中,我们经常会遇到需要对List进行去重的需求。

其中常见的情况是,将数组去重,或者将对象依据某个字段去重。这两种方式均可用set属性进行处理。

今天讨论,有一个List,且其中的元素是自定义的对象,我们需要根据对象的某两个字段的值来进行去重,并得到去重后的结果。

整理过程如下:

方案一

1、基础准备

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

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

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

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

人员(User.java)

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

测试类(Test .java)

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

    }
}
6、打印结果

方案二

1、使用工具类处理:

人员(User.java)

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

}

测试类(Test.java)

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

关键代码: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

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

相关推荐
Jason-河山7 分钟前
利用 Python 爬虫采集 1688商品详情
java·http
计算机源码社8 分钟前
分享一个餐饮连锁店点餐系统 餐馆食材采购系统Java、python、php三个版本(源码、调试、LW、开题、PPT)
java·python·php·毕业设计项目·计算机课程设计·计算机毕业设计源码·计算机毕业设计选题
Zww089111 分钟前
idea插件市场安装没反应
java·ide·intellij-idea
夜雨翦春韭13 分钟前
【代码随想录Day31】贪心算法Part05
java·数据结构·算法·leetcode·贪心算法
汤兰月13 分钟前
Python中的观察者模式:从基础到实战
开发语言·python·观察者模式
计算机学姐13 分钟前
基于微信小程序的调查问卷管理系统
java·vue.js·spring boot·mysql·微信小程序·小程序·mybatis
problc24 分钟前
Android 组件化利器:WMRouter 与 DRouter 的选择与实践
android·java
西柚与蓝莓2 小时前
【开源开放体系总结】
python
程序员南飞2 小时前
ps aux | grep smart_webrtc这条指令代表什么意思
java·linux·ubuntu·webrtc
弥琉撒到我2 小时前
微服务swagger解析部署使用全流程
java·微服务·架构·swagger