为什么(而不是如何)一个对象必须符合equals()的javadoc?

为什么(而不是如何)一个对象必须符合equals()的javadoc?,java,equals,Java,Equals,解释正确重写方法所需遵循的规则。它说: 它是自反的:对于任何非空参考值x,x.equals(x)应该返回true 它是对称的:对于任何非空的引用值x和y,当且仅当y.equals(x)返回true时,x.equals(y)才应返回true 它是可传递的:对于任何非空引用值x、y和z,如果x.equals(y)返回true,y.equals(z)返回true,那么x.equals(z)应该返回true 它是一致的:对于任何非空的引用值x和y,x.equals(y)的多次调用始终返回true或fal

解释正确重写方法所需遵循的规则。它说:

  • 它是自反的:对于任何非空参考值x,x.equals(x)应该返回true
  • 它是对称的:对于任何非空的引用值x和y,当且仅当y.equals(x)返回true时,x.equals(y)才应返回true
  • 它是可传递的:对于任何非空引用值x、y和z,如果x.equals(y)返回true,y.equals(z)返回true,那么x.equals(z)应该返回true
  • 它是一致的:对于任何非空的引用值x和y,x.equals(y)的多次调用始终返回true或false,前提是没有修改对象上equals比较中使用的信息
  • 对于任何非空引用值x,x.equals(null)应返回false

  • 如果有人问我为什么
    equals()。我对此不满意。我想更深入地了解这些规则存在的原因。有人能通过这些规则中的每一条,举例说明,如果违反了这些规则,会出现什么问题吗?

    这些是平等如何运作的数学定义。我认为数学是更深层次的原因

    CollectionsAPI的设计师JoshuaBloch在他的“高效Java”中详细阐述了这些。我建议你读那一章和所有其他章节


    您可以找到第3章。

    主要原因是有许多类和API依赖于
    equals
    的正确功能才能正常工作。最常用的是
    java.util
    包、
    List
    s和
    Set
    s和
    Map
    s等等,但是还有很多其他的

    通过对
    equals
    有一个健壮的定义,您可以启用排序等功能。而不是给您一个“理由”,这有点困难,我将为每个方面提供一个示例

    • 自反性:如果您尝试在
      集合中放置同一元素两次,它将在集合中出现两次,从而阻止“无重复项”功能工作
    • 对称:排序功能将非常不可预测
    • 可传递性:同样,排序功能
    • 始终如一:一切都将难以预料
    • Null:插入在
      Set
      s和
      Map
      s之类的事情中没有什么意义
    有关更多信息,我邀请您查看

    要求

    它是自反的:对于任何非空参考值x,x.equals(x)应该返回true

    解释

    这就是说,一个对象X在与自身比较时应该始终返回true。这是合乎逻辑的。考虑一下“=”操作符

    int x = 1;
    int y = 1;
    if(x == x) { // We expect this to be true every time }
    

    要求

    它是对称的:对于任何非空的引用值x和y,当且仅当y.equals(x)返回true时,x.equals(y)才应返回true

    解释

    这是数学中
    =
    的一个性质。请这样看:

    int x = 1;
    int y = 1;
    if(x == y) { // This should return true }
    if(y == x) { // We expect this to have the same output as the first if }
    

    要求

    它是可传递的:对于任何非空引用值x、y和z,如果x.equals(y)返回true,y.equals(z)返回true,那么x.equals(z)应该返回true

    解释

    同样,一些代码可以解释原因

    int x = 1;
    int y = 1;
    int z = 1;
    
    if(y == x && x == z)
    {
       // It only logically follows that y == z.
    }
    

    要求

    它是一致的:对于任何非空的引用值x和y,x.equals(y)的多次调用始终返回true或false,前提是没有修改对象上equals比较中使用的信息

    解释

    这一点是不言自明的。它所说的是,它的行为就像一个数学函数。也就是说,对于相同的输入,每次都会产生相同的输出。
    要求

    对于任何非空引用值x,x.equals(null)应返回false

    解释


    这只是一个商定的标准。而且,逻辑上也成立。要成功调用对象的
    equals
    方法,它必须是
    非null
    。如果它是
    非空的
    ,并且您正在测试与
    的相等性,那么它必须是不相等的,因此

    ,如果您从哲学上问我们为什么要对API的给定虚拟方法遵循任何规则,答案是,每一个软件都注定存在于一个巨大的生态系统中,如果为该生态系统中的交互定义了一些指导原则,那么就更加实用了。如果不是这样,我们将面临兼容性、维护和进步的噩梦

    如果你的问题真的是针对
    equals()
    方法而不是别的,那么。。。此方法的重写所需的大多数属性源自我们如何在数学和逻辑中使用等式。在这些属性不适用的情况下,我无法一下子说出一个有用的系统。因此,原因在于熟悉度和可预测性

    它是自反的:对于任何非空参考值x,x等于(x) 应该返回true

    这就是
    equals()
    方法的本质。如果这不适用,该方法就没有用途——或者至少应该有另一个名称

    它是对称的:对于任何非空的引用值x和y,当且仅当y.equals(x)返回true时,x.equals(y)才应返回true

    如果
    x=y
    不是与
    y=x
    等价的语句,我们就必须从一种非常熟悉且根深蒂固的思维方式出发,用Java编程无论顺序如何,这两个表达式都应该执行相同的检查,否则它们并不表示真正的相等,而是s