当前位置: 首页 > 面试题库 >

为equals()实现选择字段的最佳实践

魏元白
2023-03-14
问题内容

在编写单元测试时,我经常遇到这样的情况equals(),即测试中的某些对象的assertEquals工作方式与实际环境中的工作方式不同。以一些接口为例ReportConfig。它具有id和其他几个领域。逻辑上,一个配置等于ids匹配时的另一个配置。但是,当谈到测试某些特定的实现时,例如XmlReportConfig,显然我想匹配
所有 字段。一种解决方案是不要equals在测试中使用,而只是遍历对象的属性或字段并进行比较,但这似乎不是一个好的解决方案。

因此,除了这种特定类型的情况外,我想从语义上而非技术上梳理实现平等的最佳实践。


问题答案:

在语义上而非技术上,实现最佳实践的最佳方法是平等。

在Java中,由于该equals方法如何与实现集成在一起,因此实际上应将其视为“身份相等”。考虑以下:Collection``Map

 public class Foo() {
    int id;
    String stuff;
 }

 Foo foo1 = new Foo(10, "stuff"); 
 fooSet.add(foo1);
 ...
 Foo foo2 = new Foo(10, "other stuff"); 
 fooSet.add(foo2);

如果Foo身份是id字段,则第2次fooSet.add(...)应该 没有
其他元素添加到Set,但应该返回false,因为foo1foo2具有相同id。如果定义Foo.equals(和hashCode)方法包括
idstuff领域那么这可能会被打破,因为Set可能含有具有相同id字段2点的参考对象

如果您没有将对象存储Collection(或Map)中,则不必以equals这种方式定义方法,但是许多人认为它是错误的形式。如果将来您
确实 将其存储在a中,Collection那么事情将会崩溃。

如果我 需要 测试所有字段的相等性,则倾向于编写另一种方法。诸如此类的东西equalsAllFields(Object obj)

然后,您将执行以下操作:

assertTrue(obj1.equalsAllFields(obj2));

另外,一种适当的做法是 不要
定义equals考虑可变字段的方法。当我们开始谈论类层次结构时,这个问题也变得很困难。如果子对象定义equals为其本地字段
基类的组合,equals则违反了其对称性:

 Point p = new Point(1, 2);
 // ColoredPoint extends Point
 ColoredPoint c = new ColoredPoint(1, 2, Color.RED);
 // this is true because both points are at the location 1, 2
 assertTrue(p.equals(c));
 // however, this would return false because the Point p does not have a color
 assertFalse(c.equals(p));

我强烈建议您阅读以下内容中的“陷阱#3:根据可变字段定义相等项”部分:

如何用Java编写平等方法

一些其他链接:

  • 实现hashCode()和equals()
  • 优美的博客-值,等于和哈希码

哦,仅出于后代考虑,无论您选择比较哪些字段来确定相等性,都需要在hashCode计算中使用相同的字段。
equals并且hashCode必须是对称的。如果两个对象相等,则它们 必须 具有相同的哈希码。相反不一定是正确的。



 类似资料:
  • 问题内容: 我有大量的数据,用户必须从中选择一个。我正在考虑一种实现它的方法(当然,在GUI中)。我有一些想法。但只是想在这里发布,因为可能会有更好的选择。 说,用户必须从大量的用户群中选择一个名称。如果我只是为用户输入一个文本字段来输入名称,那么可能会出现诸如以不同格式输入相同名称,拼写错误等问题。 我在这里看到两个选择 使用组合框 使用列表(实际上,我在想类似的东西。由于空间问题,我无法始终显

  • 本文向大家介绍android实现年龄段选择器,包括了android实现年龄段选择器的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了android实现年龄段选择器的具体代码,供大家参考,具体内容如下 效果就是滑动圆形按钮选择时间,废话不多说,先上工具类 在xml中 最后在代码中调用 写完收工。 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持呐喊教程。

  • 问题内容: 我(使用Java)正在研究一种递归图像处理算法,该算法以递归方式从中心点向外遍历图像的像素。 不幸的是,这会导致堆栈溢出。因此,我决定切换到基于队列的算法。 现在,这一切都很好而且很花哨- 但考虑到以下事实:它的队列将在非常短的时间内分析成千上万个像素,同时不断弹出并推动,而不会保持可预测的状态(长度可能在100到100之间,和20000),则队列实现需要具有显着的快速弹出和推送功能。

  • 问题内容: 我正在尝试在PHP中创建类似CMS的系统。使它尽可能模块化和可扩展。 有人可以为我提供在PHP中创建事件侦听器系统(例如Drupal系统的非常简化的版本),创建钩子并在一个简短的示例中实现它们的最佳实践方案也很不错。 问题答案: 嗯,从实现角度看,确实有三种不同的方法可以做到这一点(请注意,这些是面向对象的设计模式,但是您可以根据需要在功能上或过程上实现它们)。 1.观察者模式 您可以

  • 我正在(用Java)研究递归图像处理算法,该算法从中心点向外递归遍历图像的像素。 不幸的是,这会导致堆栈溢出。所以我决定切换到基于队列的算法。 现在,这一切都很好,但是考虑到它的队列将在很短的时间内分析数千个像素,同时不断弹出和推送,而不保持可预测的状态(长度可能在100到20000之间),队列实现需要具有显著的快速弹出和推送能力。 链表似乎很有吸引力,因为它能够将元素推到自己身上,而无需重新排列

  • 这里有些给使用和编写 Ansible playbook 的贴士. 你能在我们的 ansible-example repository.找到展示这些最佳实践的 playbook 样例.(注意: 这些示例用的也许不是最新版的中所有特性,但它们仍旧是极佳的参考.) Topics 最佳实践 接下来的章节将向你展示一种组织 playbook 内容方式. 你对 Ansible 的使用应该符合你的需求而不是我们