等价关系和等价类_确定Java等价性的新时代?

等价关系和等价类

几个月前,我读了一篇题为“确定Java等价性的新时代?”的博客文章。 这在某种程度上与我当时在我那令人沮丧的副项目Java :: Geci中开发的内容非常吻合 。 我建议您暂停阅读,阅读原始文章,然后再返回此处,即使您知道一定比例的读者也不会回来。 这篇文章是关于如何在Java中正确实现equals()hashCode() ,以及一些有关应该如何实现或应该如何实现的思想。 在本文中,我将为那些不阅读原始文章的人详细介绍这些内容,并补充我的想法。 部分使用Java :: Geci的方式解决了这些问题,并且在本文结尾处,应如何在equals()hashCode()处理递归数据结构。 (请注意,就在我阅读文章的那一天,我也在完善mapper生成器以处理递归数据结构。这与我实际上正在解决的问题非常共鸣。)

如果您回来甚至没有读完原始文章,甚至连Liam Miller-Cushon所引用的JDK信函中标题为“ 等价 ”的内容,在这里,您都可以从我的角度总结一下最重要的陈述/从中学习文章:

  • 手动生成equals()hashCode()很麻烦。
  • 自Java 7以来,JDK就已经提供了支持,但是仍然存在方法的代码,并且必须对其进行维护。
  • IDE可以为这些方法生成代码,但是重新生成它们仍然不是自动化过程,而手动执行重新生成是容易出错的维护过程。 (又名您忘记了运行发电机)

来自Liam Miller-Cushon的JDK信(标题为“ Equivalence ”)列出了equals()hashCode()实现中的典型错误。 值得在更多细节中重申这些内容。 (某些文字被逐字引用。)

  • “覆盖Object.equals(),但不覆盖hashCode()。 (Object.hashCode的合同规定,如果两个对象相等,则在两个对象中的每个对象上调用hashCode()方法必须产生相同的结果。实现equals()而不是hashCode()使得情况不太可能。)”,这是一个菜鸟错误,您可能会说您永远不会犯错。 是的,如果您是一名高级程序员,但尚未具备较高的智力水平,例如:忘记了牙齿修复的位置,那么您永远不会忘记在创建hashCode()时创建hashCode() equals() 。 但是请注意,这是生命中非常短暂的时间。 许多初级人员也构成了代码库,缺少的hashCode()可能总是潜伏在Java代码的干草堆深处,我们必须使用所有经济可行的措施来避免它们的不存在。
  • “等于无条件递归的实现。” 这是一个常见的错误,甚至老年人也多次忽略此可能的错误。 因为我们使用的数据结构通常不是递归的,所以这几乎不是问题。 当它们是递归的时, equals()hashCode()方法的粗心的递归实现可能会导致无限循环,堆栈溢出和其他不便之处。 我将在文章结尾讨论这个话题。
  • “比较不匹配的字段或吸气剂对,例如a == that.a && b == that.a. 这是一个主题输入错误,很容易像主题->典型那样被忽略。
  • 等于在给定null参数时抛出NullPointerException的实现。 (它们应该返回false。)
  • 等于在给定类型错误的参数时抛出ClassCastException的实现。 (它们应该返回false。)
  • 通过委派给hashCode()来实现equals() hashCode() 。 (哈希经常发生冲突,因此将导致误报。)
  • 考虑未在相应的equals()方法中测试的hashCode()中的状态。 (相等的对象必须具有相同的hashCode() 。)
  • 将引用相等或hashCode()用于数组成员的equals()hashCode()实现。 (他们可能打算使用值相等和hashCode() 。)
  • 其他错误(不在建议的范围之内):使用错误,例如比较两个静态不同的类型,或带有定义的非本地错误(例如,覆盖等号和更改语义,破坏可替换性)

我们如何避免这些错误? 一种可能性是增强语言,如所提到的建议所建议的那样,以便可以以声明的方式描述方法hashCode()equals() ,而实际的实现是常规且麻烦的,由编译器完成。 这是光明的未来,但我们必须等待。 Java因Swift整合思想而闻名。 当实现某些功能时,它将以向后兼容的方式永久保存。 因此,选择是快速实施(可能以错误的方式实施)并永远使用下去。 或等到业界完全确定必须以哪种语言实施它,然后只有那时才能实施它。 Java正在遵循第二种开发方式。

正如我在《 您的代码是多余的... 》一文中所描述的那样,这是语言发展引起的语言短缺。 暂时的短缺问题将在以后解决,但就目前而言,我们必须解决这一短缺问题。

解决这种短缺的方法之一就是代码生成,这就是Java :: Geci出现的地方。

Java :: Geci是一个代码生成框架,非常适合创建代码生成器,以帮助减少针对特定领域问题的代码冗余。 代码生成器在单元测试执行期间运行,这似乎有点晚了,因为代码已经被编译。 但是,此问题已通过以下方式解决:如果“测试”的代码生成了任何代码并执行了编译,则生成“测试”的代码将失败,并且第二次测试也将不再失败。

旁注:这种工作方式也可能是任何软件开发人员都非常熟悉的:让我们再次运行它,可能会起作用!

从技术的角度来看,在编程语言发展不足的情况下,Java :: Geci也是一样。 出于特定领域的原因,代码生成与出于语言发展不足的原因而生成代码之间没有技术上的区别。 但是,在语言演变问题的情况下,您可能会找到其他也可以解决该问题的代码生成工具。 要生成equals()hashCode() ,可以使用集成开发环境。 没有什么比从IDE中选择菜单并单击以下命令更简单了:“ generate equals and hashCode”。

假设生成的代码运行良好,这可以解决以上所有问题之一。 唯一的问题是,无论何时更新代码,它都不会再次运行代码生成器来更新生成的代码。 IDE很难与Java :: Geci竞争。 设置Java :: Geci框架的步骤比单击几个菜单项要多。 您需要测试依赖项,必须创建一个单元测试方法,并且必须注释需要生成器的类,或者作为替代,您必须在包含生成的代码的代码中插入一个编辑器折叠块。 但是,在那之后,您可以忘记生成器,而无需担心团队中的任何开发人员都忘记了重新生成equals()hashCode()方法。

带走

  • 为一个类拥有适当的equals()hashCode()方法并不像看起来那样简单。 手动编写它们几乎不是最好的方法。
  • 使用生成工具来生成它们,并确保生成的代码和代码生成不会出现上述任何常见错误。
  • 如果只需要Q&D,则使用IDE菜单并生成方法。 另一方面,如果您有一个较大的代码库,并且有许多开发人员在其中工作,并且代码生成可能需要重新执行,则可以使用自动执行代码生成的工具。 示例:Java :: Geci。
  • 使用最新版本的工具(例如Java),以免落后于可用技术。

翻译自: https://www.javacodegeeks.com/2019/10/a-new-era-for-determining-equivalence-in-java.html

等价关系和等价类

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据结构(一)之链表

一、链表链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。 链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分&#xff…

高级数据结构实现——自顶向下伸展树

【0】README 1) 本文部分内容转自 数据结构与算法分析,旨在理解 高级数据结构实现——自顶向下伸展树 的基础知识; 2) 源代码部分思想借鉴了数据结构与算法分析,有一点干货原创代码,for original source …

测试框架 如何测试私有方法_高效的企业测试–测试框架(5/6)

测试框架 如何测试私有方法本系列文章的这一部分将介绍测试框架以及我在何时以及是否应用它们方面的想法和经验。 关于测试框架的想法 我对大多数测试框架不太满意的原因是,按照我的观点,它们大多增加了语法上的便利性和便利性,但是本质上并…

数据结构(二)之链表反转

一、链表反转 1、反转非递归算法 2、反转递归算法 链表结点&#xff1a; package cn.edu.scau.mk;/**** author MK* param <T>*/ public class Node<T> {private T data;private Node<T> next null;public Node(T data) {this.data data;}public T getD…

web安全测试视频课程专题_有关有效企业测试的视频课程

web安全测试视频课程专题我已经制作了一些有关有效企业测试的视频。 在实际项目中&#xff0c;我仍然认为该主题非常重要。 这是我在测试Enterprise Java项目中的经验以及一些示例。 1.介绍和有效的Maven使用 在此视频中&#xff0c;我将介绍测试过程&#xff0c;并演示如何使…

网络——获取Web数

【0】README 0.1&#xff09; 本文描述转自 core java volume 2&#xff0c; 旨在理解 “网络——获取Web数” 的基础知识&#xff1b; 0.2&#xff09; for source code , please visit https://github.com/pacosonTang/core-java-volume/blob/master/coreJavaAdvanced/chap…

数据结构(三)之单链表反向查找

一、反向查找单链表 1、简单查找 先遍历获取单链表单长度n&#xff0c;然后通过计算得到倒数第k个元素的下标为n-k&#xff0c;然后查找下标为n-k的元素。 2、优化查找 先找到下标为k的元素为记录点p1&#xff0c;然后设置新的记录点p2的下标从0开始&#xff0c;同时遍历两个…

java使用:: 表达式_Java 13:切换表达式的增强功能

java使用:: 表达式您可能还记得我以前的文章&#xff0c;在Java 12中&#xff0c;传统的switch语句得到了增强&#xff0c;因此可以用作表达式。 在Java 13中&#xff0c;对该功能进行了进一步的更改 。 break语句不能再返回值。 相反&#xff0c;您必须使用新的yield语句&…

网络——Base64Encode(转:自定义Base64编码器——Base64Encode)

【0】README 0.1&#xff09; 本文source code 转自 core java volume 2 &#xff0c; 旨在了解 如何定义一个 编码器&#xff0c; 如Base64Encode &#xff1b; 0.2&#xff09;注意&#xff1a; 区别自定义的 Base64Encode 和 java.util.Base64 编码器 0.3&#xff09;fo…

数据结构(四)之单链表查找中间结点

一、查找单链表中间结点 1、简单查找 先遍历获取单链表单长度n&#xff0c;然后通过计算得到中间结点为n/2&#xff0c;然后查找下标为n/2的元素。 2、优化查找 先设置记录点fast、slow&#xff0c;下标均从0开始&#xff0c;fast走两步&#xff0c;slow走一步&#xff0c;同…

java面试常见面试问题_Java面试准备:15个Java面试问题

java面试常见面试问题并非所有的访谈都将重点放在算法和数据结构上—通常&#xff0c;访谈通常只侧重于您声称是专家的语言或技术。在此类访谈中&#xff0c;通常没有任何“陷阱”问题&#xff0c;而是它们要求您利用内存和使用该语言的经验–换句话说&#xff0c;它们测试您对…

网络——提交表单数据(post方式)

【0】README 1&#xff09; 本文文字描述 转自 core java volume 2 &#xff0c; 旨在理解 网络——提交表单数据 的基础知识 &#xff1b; 2&#xff09; for source code, please visit https://github.com/pacosonTang/core-java-volume/tree/master/coreJavaAdvanced/cha…

html5实现最智能大气的公司年会抽奖(源码)

文章目录 1.设计来源1.1 主界面1.3 数据配置1.4 抽奖效果1.5 中奖效果 2.效果和源码配置2.1 动态效果2.2 员工信息配置2.3 奖品信息配置2.4 抽奖音效配置2.5 源代码2.6 项目结构 源码下载 作者&#xff1a;xcLeigh 文章地址&#xff1a;https://blog.csdn.net/weixin_43151418/…

Linux入门(一)之权限指令系统管理

一、权限指令 普通用户需要使用sudo或者root超级管理员可以执行权限指令。 二、linux系统init程序 &#xff08;1&#xff09;运行init程序&#xff08;引用runoob.com&#xff09; init 进程是系统所有进程的起点&#xff0c;你可以把它比拟成系统所有进程的老祖宗&#xf…

java jsf_使用Java和JSF构建一个简单的CRUD应用

java jsf使用Okta的身份管理平台轻松部署您的应用程序 使用Okta的API在几分钟之内即可对任何应用程序中的用户进行身份验证&#xff0c;管理和保护。 今天尝试Okta。 JavaServer Faces&#xff08;JSF&#xff09;是用于构建Web应用程序的Java框架&#xff0c;其中心是作为用户…

网络——发送email(一个简单荔枝)

【0】README 1&#xff09; 本文文字描述 转自 core java volume 2 &#xff0c; 旨在理解 网络——发送email 的基础知识 &#xff1b; 2&#xff09; for souce code , please visit https://github.com/pacosonTang/core-java-volume/tree/master/coreJavaAdvanced/chapte…

算法七之希尔排序

一、希尔排序 &#xff08;1&#xff09;简介 希尔排序(Shell Sort)是插入排序的一种。也称缩小增量排序&#xff0c;是直接插入排序算法的一种更高效的改进版本。希尔排序是非稳定排序算法。该方法因DL&#xff0e;Shell于1959年提出而得名。希尔排序是把记录按下标的一定增量…

cuba 平台_CUBA平台:TypeScript SDK和REST API

cuba 平台在本文中&#xff0c;我们将讨论已存在很长时间但尚未广为人知的CUBA平台的功能- 前端SDK生成器 &#xff0c;并了解它如何与CUBA的REST API插件一起使用 。 Java JavaScript –网络婚姻 仅八年前&#xff0c;我们Java开发人员在我们的Web应用程序中使用JavaScript作…

算法八之归并排序

一、归并排序原理 归并排序&#xff08;MERGE-SORT&#xff09;是建立在归并操作上的一种有效的排序算法,该算法是采用分治法&#xff08;Divide and Conquer&#xff09;的一个非常典型的应用。将已有序的子序列合并&#xff0c;得到完全有序的序列&#xff1b;即先使每个子序…

数据库编程——intro to JDBC

【0】README 1&#xff09; 本文文字描述 转自 core java volume 2 &#xff0c; 旨在理解 数据库编程——JDBC 的基础知识 &#xff1b; 2&#xff09;JDBC起源&#xff1a; 96年&#xff0c; Sun公司发布了 第一版的java 数据库连接&#xff08;JDBC&#xff09;API&#…