来自一个字段的Java hashCode [英] Java hashCode from one field

查看:115
本文介绍了来自一个字段的Java hashCode的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

编辑:准备我的对象以便在HashMap中使用。

Prepare my objects for the use within a HashMap.

在阅读了一些关于如何生成哈希码的内容之后,我现在很困惑。我的(可能是微不足道的)问题是,当我有一个可以使用的字段时,我应该如何实现hashCode方法?我可以直接使用fiels吗?
如果我理解正确,hashCode的值在对象的生命周期内不得改变,而且我只有一个适合这个的ID,但我已经在其他地方读过,那个人不应该使用ID ... despide那个,基于这个(唯一且不变的)值的hashCode函数怎么样? equals方法也只基于id ..

after reading a bit about how to generate a hash code, im kind of confused now. My (probably trivial) question is, how should I implement a hashCode method when I have one field that I could use? Can I use the fiels directly? If I understand correctly, the values for hashCode must not change during the lifetime of an object, and I only have an ID filed that fits this, but I have read otherwhere, that one should not use ID...despide of that, how would a hashCode function based on this one (unique and not changing) value look like? The equals method is also based on the id only..

推荐答案

如果你的对象是可变的,那么它是可以接受的哈希码随时间而变化。当然,您应该更喜欢不可变对象( Effective Java 2nd Edition,Item 15:Minimize mutability )。

If your object is mutable, then it is acceptable to have its hash code change over time. Of course, you should prefer immutable objects (Effective Java 2nd Edition, Item 15: Minimize mutability).

这是来自Josh Bloch的哈​​希码配方,来自 Effective Java 2nd Edition,第9项:覆盖等于 时始终覆盖 hashCode

Here's the hashcode recipe from Josh Bloch, from Effective Java 2nd Edition, Item 9: Always override hashCode when you override equals:


  • 存储一些常量非零值比方说17,在一个名为 result int 变量中。

  • 计算一个每个字段的 int 哈希码 c


    • 如果该字段是 boolean ,则计算(f?1:0)

    • 如果字段是字节,char,short,int ,则计算(int)f

    • 如果字段为 long ,则计算(int)(f ^(f>>> 32) ))

    • 如果字段是 float ,请计算 Float.floatToIntBits (f)

    • 如果t他的字段是 double ,计算 Double.doubleToLongBits(f),然后散列生成的如上所述,长

    • 如果该字段是对象引用,并且此类的等于方法比较字段通过递归调用等于,在字段上递归调用 hashCode 。如果字段的值为 null ,则返回0.

    • 如果字段是数组,则将其视为每个元素都是一个单独的领域。如果数组字段中的每个元素都很重要,则可以使用版本1.5中添加的 Arrays.hashCode 方法之一。

    • Store some constant nonzero value, say 17, in an int variable called result.
    • Compute an int hashcode c for each field:
      • If the field is a boolean, compute (f ? 1 : 0)
      • If the field is a byte, char, short, int, compute (int) f
      • If the field is a long, compute (int) (f ^ (f >>> 32))
      • If the field is a float, compute Float.floatToIntBits(f)
      • If the field is a double, compute Double.doubleToLongBits(f), then hash the resulting long as in above.
      • If the field is an object reference and this class's equals method compares the field by recursively invoking equals, recursively invoke hashCode on the field. If the value of the field is null, return 0.
      • If the field is an array, treat it as if each element is a separate field. If every element in an array field is significant, you can use one of the Arrays.hashCode methods added in release 1.5.

      遵循食谱是正确的即使只有一个领域。只需根据字段的类型执行相应的操作。

      It would be correct to follow the recipe as is, even with just one field. Just do the appropriate action depending on the type of the field.

      请注意,有些库实际上可以为您简化此操作,例如: HashCodeBuilder Apache Commons Lang 的code> ,或只是来自的Arrays.hashCode / deepHashCode java.util.Arrays

      Note that there are libraries that actually simplify this for you, e.g. HashCodeBuilder from Apache Commons Lang, or just Arrays.hashCode/deepHashCode from java.util.Arrays.

      这些库允许您简单地编写如下内容:

      These libraries allows you to simply write something like this:

      @Override public int hashCode() {
          return Arrays.hashCode(new Object[] {
              field1, field2, field3, //...
          });
      }
      






      Apache Commons Lang示例



      这是一个更完整的例子,使用Apache Commons Lang的构建器来方便和可读等于 hashCode toString compareTo

      import org.apache.commons.lang.builder.*;
      
      public class CustomType implements Comparable<CustomType> {
          // constructors, etc
          // let's say that the "significant" fields are field1, field2, field3
          @Override public String toString() {
              return new ToStringBuilder(this)
                  .append("field1", field1)
                  .append("field2", field2)
                  .append("field3", field3)
                      .toString();
          }
          @Override public boolean equals(Object o) {
              if (o == this) { return true; }
              if (!(o instanceof CustomType)) { return false; }
              CustomType other = (CustomType) o;
              return new EqualsBuilder()
                  .append(this.field1, other.field1)
                  .append(this.field2, other.field2)
                  .append(this.field3, other.field3)
                      .isEquals();
          }
          @Override public int hashCode() {
              return new HashCodeBuilder(17, 37)
                  .append(field1)
                  .append(field2)
                  .append(field3)
                      .toHashCode();
          }
          @Override public int compareTo(CustomType other) {
              return new CompareToBuilder()
                  .append(this.field1, other.field1)
                  .append(this.field2, other.field2)
                  .append(this.field3, other.field3)
                      .toComparison();
          }
      }
      

      编写这四种方法非常繁琐,而且可能很难确保所有合同都得到遵守,但幸运的是,图书馆至少可以帮助您轻松完成工作。一些IDE(例如Eclipse)也可以自动生成其中一些方法。

      These four methods can be notoriously tedious to write, and it can be difficult to ensure that all of the contracts are adhered to, but fortunately libraries can at least help make the job easier. Some IDEs (e.g. Eclipse) can also automatically generate some of these methods for you.


      • Apache Commons Lang Builders

        • Apache Commons Lang Builders
          • EqualsBuilder
          • HashCodeBuilder
          • ToStringBuilder
          • CompareToBuilder

          • 第8项:服从将军覆盖时的合约等于

          • 项目9:覆盖时始终覆盖 hashCode 等于

          • 第10项:始终覆盖 toString

          • 第12项:考虑实施可比较

          • 第2项:面对许多构造函数参数时考虑构建器

          • Item 8: Obey the general contract when overriding equals
          • Item 9: Always override hashCode when you override equals
          • Item 10: Always override toString
          • Item 12: Consider implementing Comparable
          • Item 2: Consider a builder when faced with many constructor parameters

          这篇关于来自一个字段的Java hashCode的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆