Stream distinct根据list某个字段去重的解决方案

 更新时间:2023年05月06日 10:36:52   作者:@大吉  
这篇文章主要介绍了Stream distinct根据list某个字段去重,stream的distinct去重方法,是根据 Object.equals,和 Object.hashCode这两个方法来判断是否重复的,本文给大家介绍的非常详细,需要的朋友可以参考下

需求:

List<UserPojo> users = new ArrayList<>();
//第一个user和第4个user应该是相等的,因为它们的name和address相等
					//id   name     address    age
users.add(new UserPojo(1, "daji", "山东省青岛市", 19));
users.add(new UserPojo(2, "daji2", "山东省济南市", 20));
users.add(new UserPojo(3, "daji3", "北京市", 22));
users.add(new UserPojo(4, "daji, "山东省青岛市", 23));

上面有4个user,对其进行去重,去重逻辑是根据name字段和address字段来决定(name和address字段相等 ,即可判定这两个对象相等,不必关心其他字段是否相等)

因此:第一个user和第4个user应该是相等的,因为它们的name和address相等

解决方案

stream的distinct去重方法,是根据 Object.equals,和 Object.hashCode这两个方法来判断是否重复的。

所以我们可以利用这个特性 ,重写pojo的 Object.equals,和 Object.hashCode这两个方法,来实现。

1、重写Object.equals方法

@Override
    public boolean equals(Object o) {
        UserPojo thisPojo = (UserPojo) o;
        //只有name 和 address 相等,也算相等
        if (this.getName().equals(thisPojo.getName()) && this.getAddress().equals(thisPojo.getAddress())){
            return true;
        }else {
            return false;
        }
    }

2、重写Object.hashCode方法

重写hashCode需要根据你选择的字段重新计算。

本例就是根据name和address重新计算hashcode。规则如下图:

最终方法:

@Override
    public int hashCode() {
        //根据name和address重新计算hashcode
        int result = getName().hashCode();
        //17是死值, jdk建议用17
        result = 17 * result + getAddress().hashCode();
        return result;
    }

3、使用distinct去重:

users = users.stream().distinct().collect(Collectors.toList());

结果(去重成功,去掉了一个重复值):

问题到此成功解决

4、[可选方案] 继承pojo重写equals和hashcode

如果我们不想动原有的pojo,我们可以新建一个新的pojo,来继承原有的pojo。

1、 新建一个子类,继承UserPojo
2、 重写该子类的 equals方法和hashcode 方法
3、 将父类的全部数据灌入子类,对子类 使用stream的distinct去重

代码如下:

@Test
    void test15() {
        List<UserPojo> users = new ArrayList<>();
        //第一个user和第4个user应该是相等的,因为它们的name和address相等
        users.add(new UserPojo(1, "daji", "山东省青岛市", 19));
        users.add(new UserPojo(2, "daji2", "山东省济南市", 20));
        users.add(new UserPojo(3, "daji3", "北京市", 22));
        users.add(new UserPojo(4, "daji", "山东省青岛市", 23));
        /*
            解决方案:使用stream的distinct去重
            1、 新建一个子类,继承UserPojo
            2、 重写该子类的 equals方法和hashcode 方法
            3、 将父类的全部数据灌入子类,对子类 使用stream的distinct去重
         */
        List<OverrideEqualsPojo> overrideEqualsPojos = new ArrayList<>();
        for (UserPojo user : users) {
            OverrideEqualsPojo overrideEqualsPojo = new OverrideEqualsPojo();
            BeanUtils.copyProperties(user,overrideEqualsPojo);
            overrideEqualsPojos.add(overrideEqualsPojo);
        }
        overrideEqualsPojos = overrideEqualsPojos.stream().distinct().collect(Collectors.toList());
        System.out.println(overrideEqualsPojos);
    }

子类pojo代码:

package com.daji.stream;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.util.Objects;
public class OverrideEqualsPojo extends UserPojo{
    public OverrideEqualsPojo(int id, String name, String address, int age) {
        super(id, name, address, age);
    }
    public OverrideEqualsPojo() {
    }
    @Override
    public boolean equals(Object o) {
        OverrideEqualsPojo thisPojo = (OverrideEqualsPojo) o;
        //只有name 和 address 相等,也算相等
        if (this.getName().equals(thisPojo.getName()) && this.getAddress().equals(thisPojo.getAddress())){
            return true;
        }else {
            return false;
        }
    }
    @Override
    public int hashCode() {
        //根据name和address重新计算hashcode
        int result = getName().hashCode();
        //17是死值, jdk建议用17
        result = 17 * result + getAddress().hashCode();
        return result;
    }
}

到此这篇关于Stream distinct根据list某个字段去重的文章就介绍到这了,更多相关Stream distinct 去重内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • java如何从地址串中解析提取省市区(完美匹配中国所有地址)

    java如何从地址串中解析提取省市区(完美匹配中国所有地址)

    这篇文章主要给大家介绍了关于java如何从地址串中解析提取省市区的相关资料,通过这个方法可以完美匹配中国所有地址,文中通过示例代码介绍的非常详细,需要的朋友可以参考下
    2022-07-07
  • idea提交文件时如何忽略某些文件的提交

    idea提交文件时如何忽略某些文件的提交

    这篇文章主要介绍了idea提交文件时如何忽略某些文件的提交问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-02-02
  • 详解在Java中如何优雅的停止线程

    详解在Java中如何优雅的停止线程

    线程,作为并发编程的基础单元,允许程序同时执行多个任务,在Java中,线程可以理解为程序中的独立执行路径,通过使用线程,开发者可以创建更加响应灵敏、效率更高的应用程序,本文小编将给大家介绍一下Java中如何优雅的停止线程,需要的朋友可以参考下
    2023-11-11
  • 使用自定义注解实现加解密及脱敏方式

    使用自定义注解实现加解密及脱敏方式

    这篇文章主要介绍了使用自定义注解实现加解密及脱敏方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12
  • Java中的事件处理机制详解

    Java中的事件处理机制详解

    这篇文章主要介绍了Java中的事件处理机制详解,Java事件处理是采取"委派事件模型",当事件发生时,产生事件的对象,会把此"信息"传递给"事件的监听者"处理,这里所说的"信息"实际上就是java.awt.event事件类库里某个类创建对象,把它称为"事件的对象",需要的朋友可以参考下
    2023-10-10
  • HashMap vs TreeMap vs Hashtable vs LinkedHashMap

    HashMap vs TreeMap vs Hashtable vs LinkedHashMap

    这篇文章主要介绍了HashMap vs TreeMap vs Hashtable vs LinkedHashMap的相关知识,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-07-07
  • 利用POI读取word、Excel文件的最佳实践教程

    利用POI读取word、Excel文件的最佳实践教程

    Apache POI 是用Java编写的免费开源的跨平台的 Java API,Apache POI提供API给Java程式对Microsoft Office格式档案读和写的功能。 下面这篇文章主要给大家介绍了关于利用POI读取word、Excel文件的最佳实践的相关资料,需要的朋友可以参考下。
    2017-11-11
  • Java 仿天猫服装商城系统的实现流程

    Java 仿天猫服装商城系统的实现流程

    读万卷书不如行万里路,只学书上的理论是远远不够的,只有在实战中才能获得能力的提升,本篇文章手把手带你用java+SSM+jsp+mysql+maven实现一个仿天猫服装商城系统,大家可以在过程中查缺补漏,提升水平
    2021-11-11
  • Java与Mysql锁相关知识总结

    Java与Mysql锁相关知识总结

    这篇文章主要介绍了Java与Mysql锁相关知识总结的相关资料,需要的朋友可以参考下
    2023-04-04
  • Java的JDBC编程使用之连接Mysql数据库

    Java的JDBC编程使用之连接Mysql数据库

    这篇文章主要给大家介绍了关于Java的JDBC编程使用之连接Mysql数据库的相关资料,JDBC是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,需要的朋友可以参考下
    2023-12-12

最新评论