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

Eclipse生成的hashCode函数有什么好的吗?

何承
2023-03-14

Eclipse源菜单有一个“generate hashCode/equals method”,它生成如下函数。

String name; 
@Override
public int hashCode()
{
    final int prime = 31;
    int result = 1;
    result = prime * result + ((name == null) ? 0 : name.hashCode());
    return result;
}

@Override
public boolean equals(Object obj)
{
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    CompanyRole other = (CompanyRole) obj;
    if (name == null)
    {
        if (other.name != null)
            return false;
    } else if (!name.equals(other.name))
        return false;
    return true;
}

如果我在生成hashCode()equals()时选择多个字段,Eclipse使用上面显示的相同模式。

我不是散列函数的专家,我想知道生成的散列函数有多“好”?在什么情况下它会发生故障并导致太多碰撞?

共有3个答案

桂梓
2023-03-14

一般来说是好的,但是:

  1. 番石榴做得更好,我更喜欢。【编辑:似乎从JDK7开始,Java提供了类似的哈希函数】
  2. 有些框架在直接访问字段而不是使用setters/getter时可能会导致问题,例如Hibernate。对于Hibernate创建的一些惰性字段,它创建的是一个代理,而不是真正的对象。只有调用getter才能使Hibernate获得数据库中的实际值
娄嘉石
2023-03-14

由于Java 7,您可以使用Java.util。对象编写简洁优雅的方法:

class Foo {
  private String name;
  private String id;

  @Override
  public int hashCode() {
    return Objects.hash(name,id);
  }

  @Override
  public boolean equals(Object obj) {
    if (obj instanceof Foo) {
      Foo right = (Foo) obj;
      return Objects.equals(name,right.name) && Objects.equals(id,right.id);
    }
    return false;
  }
}
百里智勇
2023-03-14

您可以看到< code>java.util.ArrayList中hashCode函数的实现如下

public int hashCode() {
    int hashCode = 1;
    Iterator<E> i = iterator();
    while (i.hasNext()) {
        E obj = i.next();
        hashCode = 31*hashCode + (obj==null ? 0 : obj.hashCode());
    }
    return hashCode;
}

这是一个这样的例子,你的Eclipse生成的代码遵循类似的实现方式。但是如果你觉得你必须自己实现你的hashCode,约书亚·布洛赫在他著名的《有效Java》一书中给出了一些很好的指导方针。我将从那本书的第9项中发布那些要点。那些是,

>

  • 将一些常量非零值(例如17)存储在名为结果的int变量中。
  • 对于对象中的每个有效字段f(equals方法考虑的每个字段),执行以下操作:

    一个。计算字段的整型哈希代码 c:

    I .如果字段是布尔值,则计算(f?1 : 0).

    ii.如果字段是字节、字符、短或整数,则计算(整数)f。

    iii.如果字段很长,则计算(int)(f^(f

    四。如果字段是浮点数,则计算float . float pointbits(f)。

    五.如果字段是双精度的,计算Double.doubleToLongBits(f),然后哈希得到的long,如步骤2.a.iii.

    vi. 如果字段是对象引用,并且此类的 equals 方法通过递归调用等于来比较字段,则递归地调用字段上的哈希代码。如果需要更复杂的比较,请计算此字段的“规范表示形式”,并在规范表示形式上调用 hashCode。如果字段的值为 null,则返回 0(或其他一些常量,但 0 是传统值)

    七。如果该字段是一个数组,则将其视为每个元素都是一个单独的字段。也就是说,通过递归应用这些规则来计算每个重要元素的哈希代码,并按照步骤2.b组合这些值。如果数组字段中的每个元素都是重要的,则可以使用1.5版中添加的Arrays.hashCode方法之一。

    b、 将步骤2.a中计算的哈希代码c合并为以下结果:

       result = 31 * result + c;
    

    返回结果。

    编写完hashCode方法后,问问自己相等的实例是否具有相等的哈希代码。编写单元测试来验证您的直觉!如果相等的实例具有不相等的哈希代码,请找出原因并解决问题。

    我想Java语言设计者和Eclipse似乎遵循相似的指导方针。快乐编码。干杯。

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

    • 问题内容: 建议和有时是必要的,即表示值(类 值类 )来覆盖,[和任选]的方法。这些方法返回的值取决于类及其超类的成员变量的全部或子集。为了实现它们正常,你必须了解理论的一点点 散列 和代数和集理论的一点点(不要太多,几乎一切都在explaind 的javadoc 这些方法和有效的Java形式乔希布洛赫。) 在大多数情况下,此方法的实现遵循一个模板,并且IDE(如Eclipse JDT)包括生成它

    • 问题内容: 我有一些Java代码要翻译成Scala。 该代码由一些不可变的类组成,这些类适合Scala中的目的。 但我不希望引入错误,所以我想,以确保所生成的代码,并为/行为等同于目前的实现。 我已经看过“ Scala编程”,但只说 第三,编译器将方法的“自然”实现添加到String,hashCode,并等于您的类。 问题答案: Scala有一个编译器选项,您可以使用它来获取“内部使用的后键入源代

    • 问题内容: 根据文档,a 可以是一个带有两个参数的函数,分别为和,并返回表示模板的字符串值。它将当前元素替换为HTML的内容。替换过程将所有属性和类从旧元素迁移到新元素。 该函数处理转换模板DOM。它包含三个参数,和和函数。该参数已被弃用。它返回一个函数。 似乎a 和a 函数非常相似,可以实现相同的目标。该函数定义的模板和功能修改模板DOM。但是,它可以在函数本身中完成。我看不到为什么要在函数外部

    • 本文向大家介绍你有使用过render函数吗?有什么好处?相关面试题,主要包含被问及你有使用过render函数吗?有什么好处?时的应答技巧和注意事项,需要的朋友参考一下 template也会翻译成render,只有一点,template中元素的tag_name是静态的,不可变化,使用createEelment可以生成不同tag_name, 比如h1 ... h6, 可以通过一个number变量控制

    • 问题内容: hashCode方法的最佳实现中可接受的答案为查找哈希码提供了看似不错的方法。但是我是哈希代码的新手,所以我不太了解该怎么做。 对于1),选择哪个非零值有关系吗?是一样好其他数字,如:黄金? 对于2),我是否将每个值添加到c?如果我有两个字段都是一个,,,等? 我在这堂课上解释得对吗? 问题答案: 该值并不重要,它可以是您想要的任何值。质数将导致值的更好分布,因此首选。 您不必添加它们