等价关系和等价类

几个月前,我读了一篇题为“确定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

等价关系和等价类

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

  1. 确定Java等价性的新时代?

    几个月前,我读了一篇题为"确定Java等价性的新时代?"的博客文章. 这在某种程度上与我当时在我那令人脚的副项目Java :: Geci中开发的内容非常吻合 . 我建议您暂停阅读, ...

  2. java 多线程 临界区_【Java并发性和多线程】竞态条件与临界区

    本文为转载学习 在同一程序中运行多个线程本身不会导致问题,问题在于多个线程访问了相同的资源.如,同一内存区(变量,数组,或对象).系统(数据库,web services等)或文件.实际上,这些问题只有 ...

  3. java 10新_【Java基础】Java10 新特性

    Java10 新特性 局部变量类型推断 局部变量的显示类型声明,常常被认为是不必须的. 场景一:类实例化时.在声明一个变量时,总是习惯了敲打两次变量类型,第一次用于声明变量类型,第二次用于构造器. 场 ...

  4. OpenTelemetry-可观察性的新时代

    有幸在2019KubeCon上海站听到Steve Flanders关于OpenTelemetry的演讲,之前Ops领域两个网红项目OpenTracing和OpenCensus终于走到了一起,可观察性统 ...

  5. unity3d技术摄像头跟随_堪比灯厂,新时代智能安全灯光技术,体验大众迈腾GTE IQ.LIGHT...

    在新能源当道的年代,GTE这三个字母的热度已经超过了纯性能的GTI,作为大众高性能插电式混合动力家族,GTE车型不仅仅在动力总成的科技方面更加先进,在车型配置科技上也非常突出,尤其在灯光方面,这次就来 ...

  6. python123测验答案数值运算程序_优学院《筑梦新时代》章节测试答案高校邦《Python程序设计基础(中国石油大学定制班次)》考试期末答案...

    优学院筑油下列影响消费者购买行为的因素中哪一项不属于社会因素( ) 参考答案如下 下列各组化合物中,梦新末答均难溶于水的是单打比赛中,时代试期甲10:5领先乙,甲应在( )发球,乙应在( )接发球. ...

  7. 案例研究:设计与方法_案例研究:未来主义与新时代数字艺术作品

    我们前代见证了社会的巨大变化. 与历史上的前世一样,人类的社会和文化常常反映在艺术品中. 例如,现代技术可以优雅地描绘我们的未来生活方式. 未来主义是用来描绘理想的未来地球社会的一种风格. 来自世界各 ...

  8. java工程师_南通JAVA软件工程师暑假强化实训学校

    如果想快速学习Java的话,建议参加Java培训.特别是自学时意志力不够强,惰性大的同学,很需要Java培训机构的助力.参加Java培训机构的好处就在于,当你想要入门Java时,可以知道如何打好学习基 ...

  9. java 实现nfa的化简_DFA与NFA的等价性,DFA化简

    等价性 对于每个NFA M存在一个DFA M',使得L(M)=L(M')--------等价性证明,NFA的确定化 假定NFA M=,我们对M的状态转换图进行以下改造: 解决初始状态唯一性:引进新的初 ...

最新文章

  1. 访谈Brad Fitzpatrick——《编程人生》精彩样章,抢先看
  2. php支付宝h5 app,H5网站接入支付宝的支付接口
  3. 洛谷 P1340 兽径管理
  4. 对公平席位分配问题的探讨:最大余数法、Q值法和D’Hondt方法及其特例|公平分配原则等
  5. java中泛型学习总结
  6. 高阶函数-参数与返回值
  7. 阿里云Link Security为企业级区块链提供易用性安全解决方案
  8. java uploadify 3.2_jquery文件批量上传控件Uploadify3.2(java springMVC)
  9. 微型计算机外观分为,2015计算机应用基础单选练习题1.1
  10. 从App直接打开小程序
  11. 微信戴圣诞帽的一个简易实现程序
  12. 最后半天时间,支付宝等第三方支付机构备付金必须100%上交
  13. SSR门户项目爬坑之路(一)
  14. aws saa是什么缩写?aws saa认证考察什么?
  15. ssh localhost失败:Permission denied (publickey).
  16. ZUCC_操作系统_Lab4线程的创建与管理
  17. matlab 复矩阵共轭
  18. 数据结构与算法之Python实现——单链表
  19. github多星java项目_可以吹爆的GitHub高星数的干货项目!!
  20. layui 多图片上传

热门文章

  1. Acwing 1085. 不要62
  2. 牛客题霸 [没有重复项数字的所有排列] C++题解/答案
  3. 牛客题霸 [ 在二叉树中找到两个节点的最近公共祖先] C++题解/答案
  4. 模板:Prufer序列
  5. jzoj2941-贿赂【数学期望,dfs】
  6. jzoj5354-导弹拦截【dp,最大匹配,最少路径覆盖】
  7. JoyOI(TYVJ)1071-LCIS【线性dp,LIS,LCS】
  8. 2018/7/8-纪中某C组题【jzoj1619,jzoj1620,jzoj1621,jzoj1622】
  9. 2018/7/6-纪中某C组题【jzoj1192,jzoj1397,jzoj1736】
  10. Codeforces Round #656 (Div. 3)