当前位置: 首页 > 知识库问答 >
问题:

是否保证==返回正确的结果?[副本]

贺正祥
2023-03-14

据我所知,Java中的==运算符比较对象的引用(int)。
此值是Objecthashcode方法的默认实现返回的值。

hashcode方法有一个实现说明:

public class Test {
    public static void main(String[] args) {
        var t1 = new Test();
        var t2 = new Test();

        System.out.println(t1.hashCode() + ":" + t2.hashCode()); // 2055281021:1554547125 (Could've been 1554547125:1554547125 ?)
        System.out.println(t1 == t2); // false (Could've been true ?)
        System.out.println(t1.equals(t2)); // false (Could've been true ?)
    }
}

为什么equalshashcode

而且,一个极度厌恶风险的人如何确保上面的假阳性永远不会发生?如果类至少有一个非静态字段,则可以重写hashcodeequals。但是,如果不是这样(就像上面的test类一样)呢?

你能解释一下我在这里漏掉了什么吗?

hashcode添加API注释(取自Silvio的答案):

这通常是通过将对象的内部地址转换为整数来实现的,但JavaTM编程语言不需要这种实现技术

共有1个答案

赵夕
2023-03-14

好吧,这里有很多问题,所以我们试着分解一下。

据我所知,Java中的==运算符比较对象的引用(int)。此值是Objecthashcode方法的默认实现返回的值。

Java中的==比较引用,是的。这些引用不一定与int兼容。在许多常见的体系结构中,int可能与引用可以占用的大部分可观察空间相一致,但通常情况下并非如此。

尤其是。

  • int是有符号类型。这意味着它一半的值是负值。指针通常是无符号的。
  • 即使忽略符号问题,int也是32位类型。大多数现代计算机都是64位的,这意味着地址空间更适合64位整数(即Java)。因此,只有一小部分地址可以存储在int.

你在这里对“正确”的定义是什么?Java规范所要求的保证可以从文档中总结出来

equals方法在非空对象引用上实现等效关系:

  • 它是自反的:对于任何非空引用值x,x.equals(x)应该返回true。
  • 它是对称的:对于任何非空引用值x和y,x.equals(y)应返回true当且仅当y.equals(x)返回true。
  • 它是传递的:对于任何非空引用值x、y和z,如果x.equals(y)返回true,而y.equals(z)返回true,那么x.equals(z)应该返回true。
  • 它是一致的:对于任何非空引用值x和y,只要不修改对象上的equals比较中使用的信息,x.equals(y)的多次调用将一致地返回true或一致地返回false。
  • 对于任何非空引用值x,x.equals(null)应返回false。
    null

默认的equals实现显然满足了上面的基本要求,标准保证默认的hashcode对于两个相等的对象是相同的。

当我们有更好的相等概念时,我们重写equals。例如,如果两个字符串具有相同的字符,即使它们在内存中是不同的对象,也应该认为它们是相等的;如果两个数组列表的元素在点方向上相等,则应该认为它们是相等的。但是对于thread,这意味着什么呢?两个任意线程什么时候应该相等?默认值已经足够了,因为无论如何我们都不会从覆盖它中获得任何好处。

如果类至少有一个非静态字段,则可以重写hashcodeequals

public final class MySimpleClass {

  public boolean equals(Object other) {
    return (other != null) && (other instanceof MySimpleClass);
  }

  public int hashCode() {
    return 42;
  }

}

对于MySimpleClass来说,这是一个完全有效、符合要求的相等性和哈希实现。特别是,因为这个类只有一个有意义的不同值,所以我认为这是两个方法的好实现。不需要非静态字段。

 类似资料:
  • 我正在使用postgis计算两个地理坐标之间的距离。 它返回给我53536.743496517米,大约等于54公里,但实际距离是103公里,我通过http://boulter.com/gps/distance/ 我在询问中是否做错了什么?

  • 我正在尝试在代码中使用NSPredicate搜索名称。搜索工作正常,但不会返回适当的结果。当我搜索一个名称(例如“Colin”)时,它会返回表中的所有其他名称或另一个名称(例如“Mike”),但如果我输入一个不存在的随机字符串,它会返回:“找不到结果”。当我在搜索栏中键入一个名字(例如Lisa)时,我希望它能找到这个名字(Lisa)并返回它,但它没有这样做 这是我的代码: 自己name返回表中的所

  • 问题内容: 如果我运行查询,例如: 即使查询与任何记录都不匹配,它也会始终返回结果吗?还是我需要验证并确保结果返回一行? 问题答案: 是的,因为它是一个聚合并且返回零。除非您添加GROUP BY,否则由于没有组,因此没有结果… 除非您添加GROUP BY,然后没有任何行,否则MAX / SUM等将返回NULL。只有COUNT传回没有结果的数字 编辑,有点晚:SUM会像MAX一样返回NULL 编辑,

  • 以下是我的疑问.... 我没有结果。 另外,我正在使用这个插件来生成请求正文。 我的查询如下所示.. null 感谢您到目前为止的阅读,如果有人能帮助我找出如何使这一工作,我将非常感谢。

  • 我们计划在客户机-服务器模式下使用Infinispan。该架构有许多客户端(客户端1、客户端2等)和分布式infinispan网络。 我们需要定期更新缓存中的数据,比如每5小时更新一次。所有客户端都可以更新数据。如果其中一个(比如客户端1)正在更新,我们需要防止其他人做同样的工作。更新完成后,所有客户端再等待5个小时,其中任何一个客户端都将再次进行更新。 Infinispan为此提供了版本化操作,

  • 问题内容: 我有一个存储过程,它检查用户是否已经存在,无论用于电子邮件的输入是什么,它随数据库的第一行一起返回。如果我手动运行select语句,我将得到正确的结果。有什么建议吗? 问题答案: 您的问题无疑在这里: 白衣 您的参数名称与列名称相同。这 可 实际工作,但规则使它这样做可能是怪异。(我认为,如果您更改引号,它可能会起作用)。 但是实际上,您应该做的是将参数重命名为其他名称: