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

好的hashCode()实现

锺离明煦
2023-03-14
问题内容

hashCode方法的最佳实现中可接受的答案为查找哈希码提供了看似不错的方法。但是我是哈希代码的新手,所以我不太了解该怎么做。

对于1),选择哪个非零值有关系吗?是1一样好其他数字,如:黄金31

对于2),我是否将每个值添加到c?如果我有两个字段都是一个longintdouble,等?

我在这堂课上解释得对吗?

public MyClass{
    long a, b, c; // these are the only fields
    //some code and methods
    public int hashCode(){
        return 37 * (37 * ((int) (a ^ (a >>> 32))) + (int) (b ^ (b >>> 32))) 
                 + (int) (c ^ (c >>> 32));
    }
}

问题答案:
  1. 该值并不重要,它可以是您想要的任何值。质数将导致hashCode值的更好分布,因此首选。
  2. 您不必添加它们,只要满足hashCode 合同,您就可以随意实现所需的任何算法:

* 在Java应用程序执行期间,只要在同一对象上多次调用它,该hashCode方法就必须一致地返回相同的整数,前提是不修改该对象的equals比较中使用的信息。从一个应用程序的执行到同一应用程序的另一执行,此整数不必保持一致。
* 如果根据该equals(Object)方法两个对象相等,则hashCode在两个对象中的每个对象上调用该方法必须产生相同的整数结果。
* 如果两个对象根据该equals(java.lang.Object)方法不相等,则不需要在两个对象中的每个对象上调用hashCode方法都必须产生不同的整数结果。但是,程序员应该意识到,为不相等的对象生成不同的整数结果可能会提高哈希表的性能。



有一些算法被认为不是很好的hashCode实现,简单地添加属性值就是其中之一。这样做的原因是,如果您有一个包含两个字段Integer aInteger b_的类,而您hashCode()只是对这些值求和,那么这些值的分布hashCode高度取决于实例存储的值。例如,如果大部分的值的 _一个_是0-10之间 _b_是0-10之间,然后将该hashCode值是0-20之间。这意味着如果将此类的实例存储在例如HashMap多个实例中,则将多个实例存储在同一存储桶中(因为很多实例中_ab均 不同 __值但具有相同总和的值将放入同一存储桶中。
这将对地图上的操作性能产生不良影响,因为进行查找时,将使用来比较存储桶中的所有元素equals()

关于算法,它看起来不错,它与Eclipse生成的算法非常相似,但是它使用不同的质数,而不是31。

@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + (int) (a ^ (a >>> 32));
    result = prime * result + (int) (b ^ (b >>> 32));
    result = prime * result + (int) (c ^ (c >>> 32));
    return result;
}


 类似资料:
  • 我有一个hashmap有这样的键:'2+4+5','653+65+1324+75'。(整数值用+号分隔) 什么是一个好的hashcode和equals方法,使得像'2+4+5','5+4+2','4+5+2'...(所有2,4,5的排列)这样的键应该返回相同的hashcode值,而equals应该返回true。 我计划在键中取整数值,对它们进行排序,按升序将它们放入一个字符串中,并调用string

  • 问题内容: 对于仅字段为原始字段的类,例如: 这是一种合理的“足够好”的书写方式吗? 也就是说,我在使用的相同字段之外构造了一个,然后仅使用。 编辑: 我已经更新了我的问题,以包括一个字段。应该如何处理?只是让它溢出? 问题答案: 您的哈希码确实满足以下属性:如果两个对象相等,则它们的哈希码必须相等。因此,这样就足够了。但是,在哈希码中创建冲突非常简单,这会降低基于哈希的数据结构的性能。 但我会稍

  • 问题内容: 这很奇怪。一位同事询问了java中myArray.hashCode()的实现。我以为我知道,但是后来我进行了一些测试。检查下面的代码。我注意到的奇怪想法是,当我编写第一个系统时,结果是不同的。请注意,这几乎就像报告内存地址并修改类一样,将地址或其他内容移动了。只是想我会分享。 问题答案: 该方法继承自,这意味着哈希码取决于引用。要基于数组的内容获取哈希码,请使用。 请注意,尽管它是一个

  • 本文向大家介绍Java实现hashCode()方法,包括了Java实现hashCode()方法的使用技巧和注意事项,需要的朋友参考一下 示例 要轻松实现对象的hashCode方法,可以使用HashCodeBuilder类。 选择字段: 使用反射: 布尔参数指示是否应使用瞬态字段。 使用反射避免某些字段:            

  • 问题内容: Eclipse的源菜单有一个“ generate hashCode / equals方法”,它可以生成类似下面的函数。 如果在生成时选择多个字段,并且Eclipse使用上面显示的相同模式。 我不是哈希函数的专家,我想知道生成的哈希函数有多“好”吗?在哪些情况下会发生故障并导致过多的碰撞? 问题答案: 你可以看到的hashCode函数在执行的 这是一个这样的示例,您的Eclipse生成的

  • 问题内容: 如果没有覆盖该方法,默​​认的实现是什么? 问题答案: 然后,此类从其祖先之一继承。如果它们都不覆盖它,则使用Object.hashCode。 从文档: 在合理可行的范围内,由Object类定义的hashCode方法确实为不同的对象返回不同的整数。(通常通过将对象的内部地址转换为整数来实现,但是JavaTM编程语言不需要此实现技术。) 因此默认实现是特定于JVM的