广告
返回顶部
首页 > 资讯 > 前端开发 > html >怎么解决使用Hashcode中distinct()方法没有起效问题
  • 749
分享到

怎么解决使用Hashcode中distinct()方法没有起效问题

2024-04-02 19:04:59 749人浏览 独家记忆
摘要

本篇内容介绍了“怎么解决使用Hashcode中distinct()方法没有起效问题”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔

本篇内容介绍了“怎么解决使用Hashcode中distinct()方法没有起效问题”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

大佬的疑惑

大佬在项目中写了类似这样的一段代码:

List<ProjectId> list = new ArrayList<>(); // 省略add数据操作 List<DeviceModel> models =  list.stream().map(ProjectId::getDeviceModel).distinct().collect(Collectors.toList()); System.out.println(models);

结果呢,这段代码中的distinct()方法并没有起效,并没有达到去重的预期。

通过api文档来看并没有问题,进而大佬开启了debug模式,发现奇怪的是实体类的equals方法都没进。

解决思路

根据大佬发的部分代码和实现思路,把整个模拟的测试程序补充完整,创建了两个实体类ProjectId和DeviceModel,并重写了equals方法(跟大佬沟通,他重写了equals方法,并且单独使用是生效的)。

DeviceModel实体类,简单重写了equals方法,只比较字段no是否相等。

@Data public class DeviceModel {      private String no;      @Override     public String toString(){         return no;     }      @Override     public boolean equals(Object other) {          if (this == other) {             return true;         }         if (other == null || getClass() != other.getClass()) {             return false;         }          return this.toString().equals(other.toString());     } }

ProjectId实体类,重写了equals方法,

@Data public class ProjectId {      private int id;      private DeviceModel deviceModel; }

然后,构建了测试类:

public class Test {      public static void main(String[] args) {          List<ProjectId> list = new ArrayList<>();          DeviceModel device1 = new DeviceModel();         device1.setNo("1");         ProjectId projectId1 = new ProjectId();         projectId1.setDeviceModel(device1);         projectId1.setId(1);         list.add(projectId1);          DeviceModel device2 = new DeviceModel();         device2.setNo("1");         ProjectId projectId2 = new ProjectId();         projectId2.setDeviceModel(device2);         projectId2.setId(1);         list.add(projectId2);          DeviceModel device3 = new DeviceModel();         device3.setNo("2");         ProjectId projectId3 = new ProjectId();         projectId3.setDeviceModel(device3);         projectId3.setId(2);         list.add(projectId3);                 List<DeviceModel> models =  list.stream().map(ProjectId::getDeviceModel).distinct().collect(Collectors.toList());        System.out.println(models);      } }

先构建了一组数据,然后让device1与device2的no属性一样,重写了equals方法,理论上它们应该是相等的,device3对象用来做对照。

执行上面的程序,控制台打印如下:

[1, 1, 2]

的确还原了大佬的bug,也奇怪为什么会这样。但既然bug已重现,解决就是比较简单的事了。

此时,大佬又发来另外一个线索,说通过for循环形式没事:

List<DeviceModel> results = new ArrayList<>(); for (DeviceModel deviceModel : list.stream().map(ProjectId::getDeviceModel).collect(Collectors.toList())) {     if (!results.contains(deviceModel)) {         results.add(deviceModel);     } } System.out.println(results);

这种实现形式恰好又可以用来做对照。

问题排查

进行问题排查时首先也想到了debug,但是同样出现并未走equals方法的情况。

仔细看了一下代码,发现在Stream处理的过程中用到了map操作。而在之前的文章中也提到,Map中判断一个对象是否已经存在是先通过key的hash值定位到对应的数组下标,如果该位置上的Entry没有值,则直接保存;如果已经有存在的值,再通过equals方法比较值是否一样。

那么,是不是因为重写了equals方法,而没有重写hashcode方法导致的呢?于是,在DeviceModel类中新增了hashcode方法:

@Override public int hashCode() {     // jdk7新增的Objects工具类     return Objects.hash(no); }

再次执行,测试方法,发现可以成功去重了。很显然,大佬的失误是在重写equals方法时违背了一条原则:如果一个类的equals方法相等,那么它们的hashcode方法必须相等。由于没有重写hashcode方法导致违背这一原则。因此,在隐式使用Map时就出现了莫名其妙的问题。

后续

经过这一番周折,问题终于解决。想必大家更也更加明白了为什么重写equals方法一定要重写hashcode方法了。后面大佬又考问我一个问题:为什么list.contains方法不会出现这个问题呢?

因为List的底层结构是数组,不像Map那样为了提升效率先对Key进行hash处理比较。简单看一下ArrayList中contains方法的核心实现:

public int indexOf(Object o) {     if (o == null) {         for (int i = 0; i < size; i++)             if (elementData[i]==null)                 return i;     } else {         for (int i = 0; i < size; i++)             if (o.equals(elementData[i]))                 return i;     }     return -1; }

可以看出如果对象不为null时,还是循环调用的equals方法来处理的。

“怎么解决使用Hashcode中distinct()方法没有起效问题”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

--结束END--

本文标题: 怎么解决使用Hashcode中distinct()方法没有起效问题

本文链接: https://www.lsjlt.com/news/83218.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 怎么解决使用Hashcode中distinct()方法没有起效问题
    本篇内容介绍了“怎么解决使用Hashcode中distinct()方法没有起效问题”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔...
    99+
    2022-10-19
  • 解决springboot的findOne方法没有合适的参数使用问题
    目录springboot的findOne方法没有合适的参数使用找了半天没找到是什么原因这里改为1.5.10之后SpringBoot踩过的坑之findOne()简而言之经过多次百度,我...
    99+
    2022-11-12
  • 怎么解决引用slf4j中Logger.info没有数据的问题
    这篇文章主要介绍“怎么解决引用slf4j中Logger.info没有数据的问题”,在日常操作中,相信很多人在怎么解决引用slf4j中Logger.info没有数据的问题问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家...
    99+
    2023-06-22
  • Vue+tsx使用slot没有被替换的问题怎么解决
    本篇内容介绍了“Vue+tsx使用slot没有被替换的问题怎么解决”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!目录前言发现问题解决后记前言...
    99+
    2023-06-20
  • 怎么在python中使用os.listdir()方法解决乱码问题
    本篇文章给大家分享的是有关怎么在python中使用os.listdir()方法解决乱码问题,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。Python的优点有哪些1、简单易用,与...
    99+
    2023-06-14
  • 怎么解决Spring AOP拦截抽象类父类中方法失效问题
    这篇文章主要介绍怎么解决Spring AOP拦截抽象类父类中方法失效问题,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!背景最近工作中需要对组内各个系统依赖的第三方接口进行监控报警,对于下游出现问题的接口能够...
    99+
    2023-06-21
  • 在xp系统中插入U盘没有显示盘符问题的解决方法是怎样的
    这篇文章给大家介绍在xp系统中插入U盘没有显示盘符问题的解决方法是怎样的,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。首先鼠标右键点击 "我的电脑",然后选择"管理"进入计算机管...
    99+
    2023-06-14
  • 轻量应用服务器ipv6错误怎么办解决方法有哪些问题
    轻量应用服务器ipv6错误一般可以按照以下步骤进行解决: 检查网络连接:查看网络连接状态是否正常,例如是否出现了连接故障或断线的情况。 检查应用程序:如果应用程序出现IPV6错误,可以尝试检查应用程序的IP地址、端口和协议等相关信息,以...
    99+
    2023-10-26
    解决方法 错误 服务器
  • 阿里云服务器CPU使用率0怎么办?有效解决方法详解
    在使用阿里云服务器的过程中,可能会遇到CPU使用率0的情况,这可能会导致服务器无法正常运行。那么,如何解决这个问题呢?本篇文章将详细介绍阿里云服务器CPU使用率0的解决方法。 一、问题原因阿里云服务器CPU使用率0的原因主要有以下几点:资源...
    99+
    2023-11-14
    阿里 使用率 解决方法
  • 怎么解决html5中的video标签ios系统中无法播放使用的问题
    这篇文章主要介绍怎么解决html5中的video标签ios系统中无法播放使用的问题,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!先是从前端的角度去考虑,如何让safari浏览器兼容video,并支持播放(未找到解决的...
    99+
    2023-06-09
  • 如何使用jQuery中load方法设计动态加载及解决被加载页面js失效的问题
    这篇文章主要介绍了如何使用jQuery中load方法设计动态加载及解决被加载页面js失效的问题,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。...
    99+
    2022-10-19
  • LeetCode索引中的重定向问题:使用Go语言进行快速解决的方法是什么?
    LeetCode是一个非常流行的算法题库,它提供了大量的算法题目供程序员们练习和提高自己的算法能力。然而,有时候我们会遇到LeetCode索引中的重定向问题,这个问题会影响我们的学习进程,因此我们需要一种快速解决的方法。在这篇文章中,我们将...
    99+
    2023-09-23
    重定向 leetcode 索引
软考高级职称资格查询
推荐阅读
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作