集合的 hashCode 方法的最佳实现

发布于 2024-07-06 00:31:34 字数 69 浏览 3 评论 0原文

我们如何决定集合的 hashCode() 方法的最佳实现(假设 equals 方法已被正确重写)?

How do we decide on the best implementation of hashCode() method for a collection (assuming that equals method has been overridden correctly) ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(20

不再见 2024-07-13 00:31:34

标准实现很弱,使用它会导致不必要的冲突。 想象一下

class ListPair {
    List<Integer> first;
    List<Integer> second;

    ListPair(List<Integer> first, List<Integer> second) {
        this.first = first;
        this.second = second;
    }

    public int hashCode() {
        return Objects.hashCode(first, second);
    }

    ...
}

现在,

new ListPair(List.of(a), List.of(b, c))

new ListPair(List.of(b), List.of(a, c))

具有相同的 hashCode,即 31*(a+b) + c 作为用于 List.hashCode 的乘数在这里重复使用。 显然,碰撞是不可避免的,但产生不必要的碰撞却是……不必要的。

使用 31 并没有什么本质上的聪明之处。 乘法器必须是奇数,以避免丢失信息(任何偶数乘法器至少会丢失最高有效位,四的倍数会丢失两个,等等)。 任何奇数乘数都可以使用。 小乘法器可能会导致更快的计算(JIT 可以使用移位和加法),但考虑到乘法在现代 Intel/AMD 上只有三个周期的延迟,这并不重要。 小乘数还会导致小输入产生更多冲突,这有时可能是一个问题。

使用素数是没有意义的,因为素数在环 Z/(2**32) 中没有任何意义。

因此,我建议使用随机选择的大奇数(随意取素数)。 由于 i86/amd64 CPU 可以使用更短的指令来容纳单个有符号字节的操作数,因此像 109 这样的乘法器具有微小的速度优势。为了最大限度地减少冲突,请采用 0x58a54cf5 之类的值。

在不同的地方使用不同的乘数是有帮助的,但可能不足以证明额外工作的合理性。

The standard implementation is weak and using it leads to unnecessary collisions. Imagine a

class ListPair {
    List<Integer> first;
    List<Integer> second;

    ListPair(List<Integer> first, List<Integer> second) {
        this.first = first;
        this.second = second;
    }

    public int hashCode() {
        return Objects.hashCode(first, second);
    }

    ...
}

Now,

new ListPair(List.of(a), List.of(b, c))

and

new ListPair(List.of(b), List.of(a, c))

have the same hashCode, namely 31*(a+b) + c as the multiplier used for List.hashCode gets reused here. Obviously, collisions are unavoidable, but producing needless collisions is just... needless.

There's nothing substantially smart about using 31. The multiplier must be odd in order to avoid losing information (any even multiplier loses at least the most significant bit, multiples of four lose two, etc.). Any odd multiplier is usable. Small multipliers may lead to faster computation (the JIT can use shifts and additions), but given that multiplication has latency of only three cycles on modern Intel/AMD, this hardly matters. Small multipliers also leads to more collision for small inputs, which may be a problem sometimes.

Using a prime is pointless as primes have no meaning in the ring Z/(2**32).

So, I'd recommend using a randomly chosen big odd number (feel free to take a prime). As i86/amd64 CPUs can use a shorter instruction for operands fitting in a single signed byte, there is a tiny speed advantage for multipliers like 109. For minimizing collisions, take something like 0x58a54cf5.

Using different multipliers in different places is helpful, but probably not enough to justify the additional work.

高冷爸爸 2024-07-13 00:31:34

对于简单的类,基于 equals() 实现检查的类字段来实现 hashCode() 通常是最简单的。

public class Zam {
    private String foo;
    private String bar;
    private String somethingElse;

    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }

        if (obj == null) {
            return false;
        }

        if (getClass() != obj.getClass()) {
            return false;
        }

        Zam otherObj = (Zam)obj;

        if ((getFoo() == null && otherObj.getFoo() == null) || (getFoo() != null && getFoo().equals(otherObj.getFoo()))) {
            if ((getBar() == null && otherObj. getBar() == null) || (getBar() != null && getBar().equals(otherObj. getBar()))) {
                return true;
            }
        }

        return false;
    }

    public int hashCode() {
        return (getFoo() + getBar()).hashCode();
    }

    public String getFoo() {
        return foo;
    }

    public String getBar() {
        return bar;
    }
}

最重要的是保持 hashCode() 和 equals() 一致:如果两个对象的 equals() 返回 true,那么 hashCode() 应该返回相同的值。 如果 equals() 返回 false,则 hashCode() 应该返回不同的值。

For a simple class it is often easiest to implement hashCode() based on the class fields which are checked by the equals() implementation.

public class Zam {
    private String foo;
    private String bar;
    private String somethingElse;

    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }

        if (obj == null) {
            return false;
        }

        if (getClass() != obj.getClass()) {
            return false;
        }

        Zam otherObj = (Zam)obj;

        if ((getFoo() == null && otherObj.getFoo() == null) || (getFoo() != null && getFoo().equals(otherObj.getFoo()))) {
            if ((getBar() == null && otherObj. getBar() == null) || (getBar() != null && getBar().equals(otherObj. getBar()))) {
                return true;
            }
        }

        return false;
    }

    public int hashCode() {
        return (getFoo() + getBar()).hashCode();
    }

    public String getFoo() {
        return foo;
    }

    public String getBar() {
        return bar;
    }
}

The most important thing is to keep hashCode() and equals() consistent: if equals() returns true for two objects, then hashCode() should return the same value. If equals() returns false, then hashCode() should return different values.

笛声青案梦长安 2024-07-13 00:31:34

组合哈希值时,我通常使用 boost c++ 库中使用的组合方法,即:

seed ^= hasher(v) + 0x9e3779b9 + (seed<<6) + (seed>>2);

这在确保均匀分布方面做得相当好。 有关此公式如何工作的一些讨论,请参阅 StackOverflow 帖子:boost::hash_combine 中的幻数< /a>

对不同哈希函数有很好的讨论:http://burtleburtle.net/bob /hash/doobs.html

When combining hash values, I usually use the combining method that's used in the boost c++ library, namely:

seed ^= hasher(v) + 0x9e3779b9 + (seed<<6) + (seed>>2);

This does a fairly good job of ensuring an even distribution. For some discussion of how this formula works, see the StackOverflow post: Magic number in boost::hash_combine

There's a good discussion of different hash functions at: http://burtleburtle.net/bob/hash/doobs.html

山人契 2024-07-13 00:31:34

这是另一个 JDK 1.7+ 方法演示,其中包含超类逻辑。 我认为它对于对象类 hashCode() 来说非常方便,纯 JDK 依赖并且不需要额外的手动工作。 请注意 Objects.hash() 是容空的。

我没有包含任何 equals() 实现,但实际上您当然需要它。

import java.util.Objects;

public class Demo {

    public static class A {

        private final String param1;

        public A(final String param1) {
            this.param1 = param1;
        }

        @Override
        public int hashCode() {
            return Objects.hash(
                super.hashCode(),
                this.param1);
        }

    }

    public static class B extends A {

        private final String param2;
        private final String param3;

        public B(
            final String param1,
            final String param2,
            final String param3) {

            super(param1);
            this.param2 = param2;
            this.param3 = param3;
        }

        @Override
        public final int hashCode() {
            return Objects.hash(
                super.hashCode(),
                this.param2,
                this.param3);
        }
    }

    public static void main(String [] args) {

        A a = new A("A");
        B b = new B("A", "B", "C");

        System.out.println("A: " + a.hashCode());
        System.out.println("B: " + b.hashCode());
    }

}

Here is another JDK 1.7+ approach demonstration with superclass logics accounted. I see it as pretty convinient with Object class hashCode() accounted, pure JDK dependency and no extra manual work. Please note Objects.hash() is null tolerant.

I have not include any equals() implementation but in reality you will of course need it.

import java.util.Objects;

public class Demo {

    public static class A {

        private final String param1;

        public A(final String param1) {
            this.param1 = param1;
        }

        @Override
        public int hashCode() {
            return Objects.hash(
                super.hashCode(),
                this.param1);
        }

    }

    public static class B extends A {

        private final String param2;
        private final String param3;

        public B(
            final String param1,
            final String param2,
            final String param3) {

            super(param1);
            this.param2 = param2;
            this.param3 = param3;
        }

        @Override
        public final int hashCode() {
            return Objects.hash(
                super.hashCode(),
                this.param2,
                this.param3);
        }
    }

    public static void main(String [] args) {

        A a = new A("A");
        B b = new B("A", "B", "C");

        System.out.println("A: " + a.hashCode());
        System.out.println("B: " + b.hashCode());
    }

}
南渊 2024-07-13 00:31:34

最好的实施? 这是一个很难的问题,因为它取决于使用模式。

Josh BlochEffective Java 第 8 条(第二版)中提出了几乎所有情况下合理的良好实现。 最好的办法是在那里查找它,因为作者在那里解释了为什么该方法很好。

简短版本

  1. 创建一个int结果并分配一个非零值。

  2. 对于在 equals() 方法中测试的每个字段 f,通过以下方式计算哈希码 c

    • 如果字段 f 是一个布尔值
      计算(f ? 0 : 1);
    • 如果字段 f 是 bytecharshortint:计算 ( int)f;
    • 如果字段 f 为 long:计算 (int)(f ^ (f >>> 32));
    • 如果字段 f 是 float:计算 Float.floatToIntBits(f);
    • 如果字段 f 是 double:计算 Double.doubleToLongBits(f) 并像处理每个 long 值一样处理返回值;
    • 如果字段 f 是一个对象:使用 hashCode() 方法的结果,或者如果 f == null 则为 0;< /里>
    • 如果字段 f 是一个数组:将每个字段视为单独的元素,并以递归方式计算哈希值,并按如下所述组合这些值。李>
  3. 将哈希值c结果相结合:

    结果 = 37 * 结果 + c 
      
  4. 返回结果

对于大多数使用情况,这应该会导致哈希值的正确分布。

The best implementation? That is a hard question because it depends on the usage pattern.

A for nearly all cases reasonable good implementation was proposed in Josh Bloch's Effective Java in Item 8 (second edition). The best thing is to look it up there because the author explains there why the approach is good.

A short version

  1. Create a int result and assign a non-zero value.

  2. For every field f tested in the equals() method, calculate a hash code c by:

    • If the field f is a boolean:
      calculate (f ? 0 : 1);
    • If the field f is a byte, char, short or int: calculate (int)f;
    • If the field f is a long: calculate (int)(f ^ (f >>> 32));
    • If the field f is a float: calculate Float.floatToIntBits(f);
    • If the field f is a double: calculate Double.doubleToLongBits(f) and handle the return value like every long value;
    • If the field f is an object: Use the result of the hashCode() method or 0 if f == null;
    • If the field f is an array: see every field as separate element and calculate the hash value in a recursive fashion and combine the values as described next.
  3. Combine the hash value c with result:

    result = 37 * result + c
    
  4. Return result

This should result in a proper distribution of hash values for most use situations.

〗斷ホ乔殘χμё〖 2024-07-13 00:31:34

如果您对 dmeister 推荐的有效 Java 实现感到满意,您可以使用库调用而不是自己调用:

@Override
public int hashCode() {
    return Objects.hash(this.firstName, this.lastName);
}

这需要 Guava (com.google.common.base.Objects.hashCode)或 Java 7 中的标准库 (java.util.Objects.hash),但工作方式相同。

If you're happy with the Effective Java implementation recommended by dmeister, you can use a library call instead of rolling your own:

@Override
public int hashCode() {
    return Objects.hash(this.firstName, this.lastName);
}

This requires either Guava (com.google.common.base.Objects.hashCode) or the standard library in Java 7 (java.util.Objects.hash) but works the same way.

谎言 2024-07-13 00:31:34

虽然这链接到 Android 文档(Wayback Machine)我在 Github 上的代码,它通常适用于 Java。 我的答案是 dmeister 的答案 的扩展,仅包含更易于阅读和理解的代码。

@Override 
public int hashCode() {

    // Start with a non-zero constant. Prime is preferred
    int result = 17;

    // Include a hash for each field.

    // Primatives

    result = 31 * result + (booleanField ? 1 : 0);                   // 1 bit   » 32-bit

    result = 31 * result + byteField;                                // 8 bits  » 32-bit 
    result = 31 * result + charField;                                // 16 bits » 32-bit
    result = 31 * result + shortField;                               // 16 bits » 32-bit
    result = 31 * result + intField;                                 // 32 bits » 32-bit

    result = 31 * result + (int)(longField ^ (longField >>> 32));    // 64 bits » 32-bit

    result = 31 * result + Float.floatToIntBits(floatField);         // 32 bits » 32-bit

    long doubleFieldBits = Double.doubleToLongBits(doubleField);     // 64 bits (double) » 64-bit (long) » 32-bit (int)
    result = 31 * result + (int)(doubleFieldBits ^ (doubleFieldBits >>> 32));

    // Objects

    result = 31 * result + Arrays.hashCode(arrayField);              // var bits » 32-bit

    result = 31 * result + referenceField.hashCode();                // var bits » 32-bit (non-nullable)   
    result = 31 * result +                                           // var bits » 32-bit (nullable)   
        (nullableReferenceField == null
            ? 0
            : nullableReferenceField.hashCode());

    return result;

}

编辑

通常,当您覆盖hashcode(...)时,您还需要覆盖equals(...)。 因此,对于那些将要或已经实现了 equals 的人来说,这里有一个很好的参考:来自我的 Github...

@Override
public boolean equals(Object o) {

    // Optimization (not required).
    if (this == o) {
        return true;
    }

    // Return false if the other object has the wrong type, interface, or is null.
    if (!(o instanceof MyType)) {
        return false;
    }

    MyType lhs = (MyType) o; // lhs means "left hand side"

            // Primitive fields
    return     booleanField == lhs.booleanField
            && byteField    == lhs.byteField
            && charField    == lhs.charField
            && shortField   == lhs.shortField
            && intField     == lhs.intField
            && longField    == lhs.longField
            && floatField   == lhs.floatField
            && doubleField  == lhs.doubleField

            // Arrays

            && Arrays.equals(arrayField, lhs.arrayField)

            // Objects

            && referenceField.equals(lhs.referenceField)
            && (nullableReferenceField == null
                        ? lhs.nullableReferenceField == null
                        : nullableReferenceField.equals(lhs.nullableReferenceField));
}

Although this is linked to Android documentation (Wayback Machine) and My own code on Github, it will work for Java in general. My answer is an extension of dmeister's Answer with just code that is much easier to read and understand.

@Override 
public int hashCode() {

    // Start with a non-zero constant. Prime is preferred
    int result = 17;

    // Include a hash for each field.

    // Primatives

    result = 31 * result + (booleanField ? 1 : 0);                   // 1 bit   » 32-bit

    result = 31 * result + byteField;                                // 8 bits  » 32-bit 
    result = 31 * result + charField;                                // 16 bits » 32-bit
    result = 31 * result + shortField;                               // 16 bits » 32-bit
    result = 31 * result + intField;                                 // 32 bits » 32-bit

    result = 31 * result + (int)(longField ^ (longField >>> 32));    // 64 bits » 32-bit

    result = 31 * result + Float.floatToIntBits(floatField);         // 32 bits » 32-bit

    long doubleFieldBits = Double.doubleToLongBits(doubleField);     // 64 bits (double) » 64-bit (long) » 32-bit (int)
    result = 31 * result + (int)(doubleFieldBits ^ (doubleFieldBits >>> 32));

    // Objects

    result = 31 * result + Arrays.hashCode(arrayField);              // var bits » 32-bit

    result = 31 * result + referenceField.hashCode();                // var bits » 32-bit (non-nullable)   
    result = 31 * result +                                           // var bits » 32-bit (nullable)   
        (nullableReferenceField == null
            ? 0
            : nullableReferenceField.hashCode());

    return result;

}

EDIT

Typically, when you override hashcode(...), you also want to override equals(...). So for those that will or has already implemented equals, here is a good reference from my Github...

@Override
public boolean equals(Object o) {

    // Optimization (not required).
    if (this == o) {
        return true;
    }

    // Return false if the other object has the wrong type, interface, or is null.
    if (!(o instanceof MyType)) {
        return false;
    }

    MyType lhs = (MyType) o; // lhs means "left hand side"

            // Primitive fields
    return     booleanField == lhs.booleanField
            && byteField    == lhs.byteField
            && charField    == lhs.charField
            && shortField   == lhs.shortField
            && intField     == lhs.intField
            && longField    == lhs.longField
            && floatField   == lhs.floatField
            && doubleField  == lhs.doubleField

            // Arrays

            && Arrays.equals(arrayField, lhs.arrayField)

            // Objects

            && referenceField.equals(lhs.referenceField)
            && (nullableReferenceField == null
                        ? lhs.nullableReferenceField == null
                        : nullableReferenceField.equals(lhs.nullableReferenceField));
}
许你一世情深 2024-07-13 00:31:34

最好使用Eclipse提供的功能,它做得很好,你可以把精力和精力放在开发业务逻辑上。

It is better to use the functionality provided by Eclipse which does a pretty good job and you can put your efforts and energy in developing the business logic.

于我来说 2024-07-13 00:31:34

首先确保 equals 正确实现。 来自IBM DeveloperWorks 文章

  • 对称性:对于两个引用,a 和 b,a.equals(b) 当且仅当 b.equals(a)
  • 自反性:对于所有非空引用,a.equals(a)
  • 传递性:如果 a.equals(b) 和 b.equals(c),则 a.equals(c)

然后确保它们与 hashCode 的关系尊重联系(来自同一篇文章):

  • 与 hashCode() 的一致性:两个相等的对象必须具有相同的 hashCode() 值

最后,一个好的哈希函数应该努力接近 理想的哈希函数

First make sure that equals is implemented correctly. From an IBM DeveloperWorks article:

  • Symmetry: For two references, a and b, a.equals(b) if and only if b.equals(a)
  • Reflexivity: For all non-null references, a.equals(a)
  • Transitivity: If a.equals(b) and b.equals(c), then a.equals(c)

Then make sure that their relation with hashCode respects the contact (from the same article):

  • Consistency with hashCode(): Two equal objects must have the same hashCode() value

Finally a good hash function should strive to approach the ideal hash function.

聆听风音 2024-07-13 00:31:34

about8.blogspot.com,你说

如果两个对象的 equals() 返回 true,则 hashCode() 应该返回相同的值。 如果 equals() 返回 false,则 hashCode() 应该返回不同的值

我不同意你的观点。 如果两个对象具有相同的哈希码,并不一定意味着它们相等。

如果 A 等于 B,则 A.hashcode 必须等于 B.hascode

,但

如果 A.hashcode 等于 B.hascode,并不意味着 A 必须等于 B

about8.blogspot.com, you said

if equals() returns true for two objects, then hashCode() should return the same value. If equals() returns false, then hashCode() should return different values

I cannot agree with you. If two objects have the same hashcode it doesn't have to mean that they are equal.

If A equals B then A.hashcode must be equal to B.hascode

but

if A.hashcode equals B.hascode it does not mean that A must equals B

温折酒 2024-07-13 00:31:34

如果您使用 eclipse,则可以使用以下命令生成 equals()hashCode()

来源-> 生成 hashCode() 和 equals()。

使用此函数,您可以决定要使用哪些字段来进行相等和哈希码计算,Eclipse 会生成相应的方法。

If you use eclipse, you can generate equals() and hashCode() using:

Source -> Generate hashCode() and equals().

Using this function you can decide which fields you want to use for equality and hash code calculation, and Eclipse generates the corresponding methods.

乜一 2024-07-13 00:31:34

Effective Javahashcode()equals() 逻辑在 Apache Commons Lang。 查看 HashCodeBuilderEqualsBuilder

There's a good implementation of the Effective Java's hashcode() and equals() logic in Apache Commons Lang. Checkout HashCodeBuilder and EqualsBuilder.

蓝海似她心 2024-07-13 00:31:34

如果我正确理解您的问题,您有一个自定义集合类(即从 Collection 接口扩展的新类)并且您想要实现 hashCode() 方法。

如果您的集合类扩展了 AbstractList,那么您不必担心它,已经有 equals() 和 hashCode() 的实现,它们通过迭代所有对象并将它们的 hashCodes() 添加在一起来工作。

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

现在,如果您想要的是计算特定类的哈希码的最佳方法,我通常使用 ^(按位异或)运算符来处理我在 equals 方法中使用的所有字段:

public int hashCode(){
   return intMember ^ (stringField != null ? stringField.hashCode() : 0);
}

If I understand your question correctly, you have a custom collection class (i.e. a new class that extends from the Collection interface) and you want to implement the hashCode() method.

If your collection class extends AbstractList, then you don't have to worry about it, there is already an implementation of equals() and hashCode() that works by iterating through all the objects and adding their hashCodes() together.

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

Now if what you want is the best way to calculate the hash code for a specific class, I normally use the ^ (bitwise exclusive or) operator to process all fields that I use in the equals method:

public int hashCode(){
   return intMember ^ (stringField != null ? stringField.hashCode() : 0);
}
っ〆星空下的拥抱 2024-07-13 00:31:34

只是完成其他更详细的答案(就代码而言)的快速说明:

如果我考虑问题 how-do-i-create-a-hash-table-in-java 尤其是 jGuru FAQ 条目,我相信判断哈希码的其他一些标准是:

  • 同步(算法是否支持并发访问)?
  • 失败安全迭代(算法是否检测到在迭代期间发生变化的集合)
  • 空值(哈希码是否支持集合中的空值)

Just a quick note for completing other more detailed answer (in term of code):

If I consider the question how-do-i-create-a-hash-table-in-java and especially the jGuru FAQ entry, I believe some other criteria upon which a hash code could be judged are:

  • synchronization (does the algo support concurrent access or not) ?
  • fail safe iteration (does the algo detect a collection which changes during iteration)
  • null value (does the hash code support null value in the collection)
◇流星雨 2024-07-13 00:31:34

我在 Arrays.deepHashCode(...) 因为它正确处理作为参数提供的数组

public static int hash(final Object... objects) {
    return Arrays.deepHashCode(objects);
}

I use a tiny wrapper around Arrays.deepHashCode(...) because it handles arrays supplied as parameters correctly

public static int hash(final Object... objects) {
    return Arrays.deepHashCode(objects);
}
留一抹残留的笑 2024-07-13 00:31:34

@about8:那里有一个非常严重的错误。

Zam obj1 = new Zam("foo", "bar", "baz");
Zam obj2 = new Zam("fo", "obar", "baz");

相同的 hashcode,

你可能想要类似的东西

public int hashCode() {
    return (getFoo().hashCode() + getBar().hashCode()).toString().hashCode();

(现在你能直接从 Java 中的 int 获取 hashCode 吗?我认为它会进行一些自动转换。如果是这样的话,请跳过 toString,它很难看。)

@about8 : there is a pretty serious bug there.

Zam obj1 = new Zam("foo", "bar", "baz");
Zam obj2 = new Zam("fo", "obar", "baz");

same hashcode

you probably want something like

public int hashCode() {
    return (getFoo().hashCode() + getBar().hashCode()).toString().hashCode();

(can you get hashCode directly from int in Java these days? I think it does some autocasting.. if that's the case, skip the toString, it's ugly.)

太傻旳人生 2024-07-13 00:31:34

使用 Apache Commons 上的反射方法 EqualsBuilderHashCodeBuilder.

Use the reflection methods on Apache Commons EqualsBuilder and HashCodeBuilder.

剑心龙吟 2024-07-13 00:31:34

当您特别要求集合时,我想添加其他答案尚未提到的一个方面:HashMap 不希望它们的键在添加到集合中后更改其哈希码。 会破坏整个目的......

As you specifically asked for collections, I'd like to add an aspect that the other answers haven't mentioned yet: A HashMap doesn't expect their keys to change their hashcode once they are added to the collection. Would defeat the whole purpose...

哀由 2024-07-13 00:31:34

任何将哈希值均匀分布在可能范围内的哈希方法都是一个很好的实现。 查看有效的 java (http://books.google.com.au/books?id=ZZOiqZQIbRMC&dq= effective+java&pg= PP1&ots=UZMZ2siN25&sig=kR0n73DHJOn-D77qGj0wOxAxiZw&hl=en&sa=X&oi=book_result&resnum=1&ct=result ),其中有一个关于哈希码实现的很好的提示(第 9 项)我认为...)。

any hashing method that evenly distributes the hash value over the possible range is a good implementation. See effective java ( http://books.google.com.au/books?id=ZZOiqZQIbRMC&dq=effective+java&pg=PP1&ots=UZMZ2siN25&sig=kR0n73DHJOn-D77qGj0wOxAxiZw&hl=en&sa=X&oi=book_result&resnum=1&ct=result ) , there is a good tip in there for hashcode implementation (item 9 i think...).

木森分化 2024-07-13 00:31:34

我更喜欢使用 Objects 类中的 Google Collections lib 中的实用方法来帮助我保持代码整洁。 通常,equalshashcode 方法是根据 IDE 的模板创建的,因此它们读起来并不清晰。

I prefer using utility methods fromm Google Collections lib from class Objects that helps me to keep my code clean. Very often equals and hashcode methods are made from IDE's template, so their are not clean to read.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文