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","李四"));
3、去重

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

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

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

    }
}

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

}

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

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/119761.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

vscode git提交

<template><view><cu-custom bgColor"bg-gradual-blue" :isBack"true"><block slot"content">额外加工</block></cu-custom><uni-section title" "><view style"margin: 0 20px;&q…

AI:66-基于机器学习房价预测

🚀 本文选自专栏:AI领域专栏 从基础到实践,深入了解算法、案例和最新趋势。无论你是初学者还是经验丰富的数据科学家,通过案例和项目实践,掌握核心概念和实用技能。每篇案例都包含代码实例,详细讲解供大家学习。 📌📌📌在这个漫长的过程,中途遇到了不少问题,但是…

pytest 的使用===谨记

发现用例的规则 a) 文件test_.py开头和_test.py结尾 b) Test开头的类中test开头的方法&#xff08;测试类不能带有__init__方法&#xff09; c) 模块中test开头的函数&#xff08;可以不在class中&#xff09; 注意点&#xff1a; pytest是以方法为单位发现用例的&#xff0c;你…

三国志14信息查询小程序(历史武将信息一览)制作更新过程03-主要页面的设计

1&#xff0c;小程序的默认显示 分为三部分&#xff0c;头部的标题、中间的内容区和底部的标签栏。点击标签可以切换不同页面&#xff0c;这是在app.json文件中配置的。代码如下&#xff1a; //所有用到的页面都需要在 pages 数组中列出&#xff0c;否则小程序可能会出现错误或…

Wnmp服务安装并结合内网穿透实现公网远程访问——“cpolar内网穿透”

文章目录 前言1.Wnmp下载安装2.Wnmp设置3.安装cpolar内网穿透3.1 注册账号3.2 下载cpolar客户端3.3 登录cpolar web ui管理界面3.4 创建公网地址 4.固定公网地址访问 前言 WNMP是Windows系统下的绿色NginxMysqlPHP环境集成套件包&#xff0c;安装完成后即可得到一个Nginx MyS…

【神经网络】【GoogleNet】

1、引言 卷积神经网络是当前最热门的技术&#xff0c;我想深入地学习这门技术&#xff0c;从他的发展历史开始&#xff0c;了解神经网络算法的兴衰起伏&#xff1b;同时了解他在发展过程中的**里程碑式算法**&#xff0c;能更好的把握神经网络发展的未来趋势&#xff0c;了解神…

技术分享 | web自动化测试-PageObject 设计模式

为 UI 页面写测试用例时&#xff08;比如 web 页面&#xff0c;移动端页面&#xff09;&#xff0c;测试用例会存在大量元素和操作细节。当 UI 变化时&#xff0c;测试用例也要跟着变化&#xff0c; PageObject 很好的解决了这个问题。 使用 UI 自动化测试工具时&#xff08;包…

Microsoft Edge浏览器不兼容解决办法

找到 Edge 的安装位置&#xff0c;一般在 C:\Program Files (x86)Microsoft Edge\Application\ 这个目录&#xff0c;把 edge.exe 或msedge.exe 修改为 chrome.exe 再重启电脑。

Rust核心功能之一(所有权)

目录 1、什么是所有权&#xff1f; 1.1 所有权规则 1.2 变量作用域 1.3 String 类型 1.4 内存与分配 变量与数据交互的方式&#xff08;一&#xff09;&#xff1a;移动 变量与数据交互的方式&#xff08;二&#xff09;&#xff1a;克隆 只在栈上的数据&#xff1a;拷贝…

Verilog使用vscode

使用vscode打开.v文件 Tools setting texteditor vscode文件路径 [line number]:[file name] &#xff08;可能会出错&#xff0c;可以去vscode确认打开的文件路径&#xff0c;后经调整后改为 vscode文件路径 [file name]&#xff09; 安装插件 搜索Verilog 添加使用最多的 …

3D视觉引导纸箱拆码垛,助力物流行业转型升级

近年来&#xff0c;自动化和智能化技术在各行业的应用越来越广泛&#xff0c;特别是在物流和仓储领域。纸箱拆码垛是物流仓储中的一个重要环节。 人工分拣效率低、错误率高、成本高&#xff0c;传统的拆码垛设备存在兼容性差&#xff0c;对纸箱的识别率不高、操作不灵活等问题…

Centos7下搭建H3C log服务器

一、rsyslogH3C 安装rsyslog服务器 关闭防火墙 systemctl stop firewalld && systemctl disable firewalld关闭selinux sed -i s/enforcing/disabled/ /etc/selinux/config && setenforce 0centos7服务器&#xff0c;通过yum安装rsyslog yum -y install r…

vr地铁消防虚拟逃生自救系统降低财产及人员伤害

无论是在公共场所还是在家中&#xff0c;火灾都是一种常见的突发事件。这往往会严重影响到人们的财产和生命安全。因此&#xff0c;如何预防火灾和安全逃生就成为了非常重要的话题。这款VR模拟火灾疏散逃生系统&#xff0c;帮助人们了解火灾逃生的技巧以及正确的应对方法。 以传…

Leetcode刷题详解——子集

1. 题目链接&#xff1a;78. 子集 2. 题目描述&#xff1a; 给你一个整数数组 nums &#xff0c;数组中的元素 互不相同 。返回该数组所有可能的子集&#xff08;幂集&#xff09;。 解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。 示例 1&#xff1a; 输入&#xf…

day05_Java中的运算符

在Java中提供了丰富的运算符 其按照功能分&#xff1a;算术运算符、赋值运算符、比较运算符、逻辑运算、条件运算符按照操作数个数分&#xff1a;一元运算符&#xff08;单目运算符&#xff09;、二元运算符&#xff08;双目运算符&#xff09;、三元运算符 &#xff08;三目…

zabbix监控安装-linux

zabbix6.4中文文档1. 简介 (zabbix.com) Zabbix 是一个企业级的开源分布式监控解决方案。 1.zabbix结构体系 Server&#xff1a; server 是存储所有配置、统计和操作数据的中央存储库。 Proxy&#xff1a; zabbix proxy可以代替 Zabbix server 收集性能和可用性数据。p…

AI芯片架构体系综述:芯片类型CPU\GPU\FPGA\ASIC以及指令集CSIS\RISC介绍

大模型的发展意味着算力变的越发重要&#xff0c;因为大国间科技竞争的关系&#xff0c;国内AI从业方在未来的一段时间存在着算力不确定性的问题&#xff0c;与之而来的是许多新型算力替代方案的产生。如何从架构关系上很好的理解计算芯片的种类&#xff0c;并且从计算类型、生…

Java附件和base64相互转换

1 文件转base64 声明&#xff1a;我用的是Hutool的Base64下的api package cn.hutool.core.codec; 首先找一张图片 很简单&#xff0c;直接使用Base64的encode方法就可以拿到文件的base64码&#xff1a; File file new File("D:\\Tools\\Images\\北极熊.jpg");String…

Feign服务调用

Feign服务调用 使用Feign&#xff0c;在服务消费者中&#xff0c;调用服务提供者的接口。 注册中心 此处使用 Nacos&#xff0c;详情见&#xff1a; https://www.cnblogs.com/expiator/p/17392549.html Feign依赖 <properties><java.version>1.8</java.vers…

OJ中常用平衡树,Treap树堆详解

文章目录 Treap定义Treap的可行性Treap的构建节点定义旋转左单旋右单旋旋转的代码实现 插入插入的代码实现 删除遍历查找Treap对权值的扩展Treap对size的扩展扩展size域后的节点定义和旋转&#xff0c;插入&#xff0c;删除操作查询第k小的元素求元素的排名 查询后继、前驱Trea…