简体   繁体   English

Java中的hashCode有什么用?

[英]What is the use of hashCode in Java?

In Java, obj.hashCode() returns some value.在 Java 中, obj.hashCode()返回一些值。 What is the use of this hash code in programming?这个哈希码在编程中有什么用?

hashCode() is used for bucketing in Hash implementations like HashMap , HashTable , HashSet , etc. hashCode()用于在HashMapHashTableHashSetHash实现中进行分

The value received from hashCode() is used as the bucket number for storing elements of the set/map.hashCode()接收到的值用作存储集合/映射元素的桶号 This bucket number is the address of the element inside the set/map.这个桶号是集合/映射中元素的地址

When you do contains() it will take the hash code of the element, then look for the bucket where hash code points to.当您执行contains()时,它将获取元素的哈希码,然后查找哈希码指向的存储桶。 If more than 1 element is found in the same bucket (multiple objects can have the same hash code), then it uses the equals() method to evaluate if the objects are equal, and then decide if contains() is true or false, or decide if element could be added in the set or not.如果在同一个bucket中发现超过1个元素(多个对象可以有相同的hash码),那么它使用equals()方法判断对象是否相等,然后判断contains()是真还是假,或决定是否可以在集合中添加元素。

From the Javadoc :Javadoc

Returns a hash code value for the object.返回对象的哈希码值。 This method is supported for the benefit of hashtables such as those provided by java.util.Hashtable .支持这种方法是为了便于哈希表,例如java.util.Hashtable提供的哈希表。

The general contract of hashCode is: hashCode的一般合约是:

  • Whenever it is invoked on the same object more than once during an execution of a Java application, the hashCode method must consistently return the same integer , provided no information used in equals comparisons on the object is modified.每当在 Java 应用程序执行期间对同一个对象多次调用它时, hashCode方法必须始终返回相同的 integer ,前提是没有修改对象上的 equals 比较中使用的信息。 This integer need not remain consistent from one execution of an application to another execution of the same application.该整数不需要从应用程序的一次执行到同一应用程序的另一次执行保持一致。

  • If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result.如果两个对象根据equals(Object)方法相等,则对两个对象中的每一个调用hashCode方法必须产生相同的整数结果。

  • It is not required that if two objects are unequal according to the equals(java.lang.Object) method, then calling the hashCode method on each of the two objects must produce distinct integer results.如果根据equals(java.lang.Object)方法,如果两个对象不相等,则不需要对两个对象中的每一个调用hashCode方法都必须产生不同的整数结果。 However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hashtables.但是,程序员应该意识到,为不相等的对象生成不同的整数结果可能会提高哈希表的性能。

As much as is reasonably practical, the hashCode method defined by class Object does return distinct integers for distinct objects.在合理可行的情况下,由 Object 类定义的 hashCode 方法确实为不同的对象返回不同的整数。 (This is typically implemented by converting the internal address of the object into an integer , but this implementation technique is not required by the Java programming language.) (这通常通过将对象的内部地址转换为整数来实现,但 Java 编程语言不需要这种实现技术。)

hashCode() is a function that takes an object and outputs a numeric value. hashCode()是一个接受对象并输出数值的函数。 The hashcode for an object is always the same if the object doesn't change.如果对象不变,则对象的哈希码始终相同。

Functions like HashMap , HashTable , HashSet , etc. that need to store objects will use a hashCode modulo the size of their internal array to choose in what "memory position" (ie array position) to store the object.HashMapHashTableHashSet等需要存储对象的函数将使用hashCode对其内部数组的大小取模来选择存储对象的“内存位置”(即数组位置)。

There are some cases where collisions may occur (two objects end up with the same hashcode), and that, of course, needs to be solved carefully.在某些情况下可能会发生冲突(两个对象最终具有相同的哈希码),当然,这需要仔细解决。

The value returned by hashCode() is the object's hash code, which is the object's memory address in hexadecimal. hashCode()返回的值是对象的哈希码,即对象的十六进制内存地址。

By definition, if two objects are equal, their hash code must also be equal.根据定义,如果两个对象相等,则它们的哈希码也必须相等。 If you override the equals() method, you change the way two objects are equated and Object's implementation of hashCode() is no longer valid.如果重写equals()方法,就会改变两个对象相等的方式,并且 Object 的hashCode()实现不再有效。 Therefore, if you override the equals() method, you must also override the hashCode() method as well.因此,如果你重写 equals() 方法,你也必须重写hashCode()方法。

This answer is from the java SE 8 official tutorial documentation 这个答案来自java SE 8官方教程文档

A hashcode is a number generated from any object.哈希码是从任何对象生成的数字。

This is what allows objects to be stored/retrieved quickly in a Hashtable.这就是允许在哈希表中快速存储/检索对象的原因。

Imagine the following simple example :想象一下以下简单示例

On the table in front of you.在你面前的桌子上。 you have nine boxes, each marked with a number 1 to 9. You also have a pile of wildly different objects to store in these boxes, but once they are in there you need to be able to find them as quickly as possible.你有九个盒子,每个盒子都标有数字 1 到 9。你还有一堆完全不同的物品要存放在这些盒子里,但是一旦它们在那里,你需要能够尽快找到它们。

What you need is a way of instantly deciding which box you have put each object in. It works like an index.您需要的是一种立即决定将每个对象放入哪个盒子的方法。它就像一个索引。 you decide to find the cabbage so you look up which box the cabbage is in, then go straight to that box to get it.你决定找到卷心菜,所以你查找卷心菜在哪个盒子里,然后直接去那个盒子拿。

Now imagine that you don't want to bother with the index, you want to be able to find out immediately from the object which box it lives in.现在假设您不想打扰索引,您希望能够立即从对象中找出它所在的盒子。

In the example, let's use a really simple way of doing this - the number of letters in the name of the object.在示例中,让我们使用一种非常简单的方法来执行此操作 - 对象名称中的字母数。 So the cabbage goes in box 7, the pea goes in box 3, the rocket in box 6, the banjo in box 5 and so on.所以卷心菜放在第 7 盒,豌豆放在第 3 盒,火箭放在第 6 盒,班卓琴放在第 5 盒,依此类推。

What about the rhinoceros, though?不过,犀牛呢? It has 10 characters, so we'll change our algorithm a little and "wrap around" so that 10-letter objects go in box 1, 11 letters in box 2 and so on.它有 10 个字符,所以我们将稍微改变我们的算法并“环绕”,以便 10 个字母的对象进入框 1,11 个字母进入框 2,依此类推。 That should cover any object.这应该涵盖任何对象。

Sometimes a box will have more than one object in it, but if you are looking for a rocket, it's still much quicker to compare a peanut and a rocket, than to check a whole pile of cabbages, peas, banjos, and rhinoceroses.有时一个盒子里会有多个物品,但如果你在寻找火箭,比较花生和火箭仍然比检查一整堆卷心菜、豌豆、班卓琴和犀牛要快得多。

That's a hash code.那是一个哈希码。 A way of getting a number from an object so it can be stored in a Hashtable.一种从对象中获取数字以便将其存储在哈希表中的方法。 In Java, a hash code can be any integer, and each object type is responsible for generating its own.在 Java 中,哈希码可以是任何整数,并且每个对象类型负责生成自己的。 Lookup the "hashCode" method of Object.查找 Object 的“hashCode”方法。

Source - here来源 -这里

Although hashcode does nothing with your business logic, we have to take care of it in most cases.尽管哈希码对您的业务逻辑没有任何作用,但在大多数情况下我们必须处理它。 Because when your object is put into a hash based container( HashSet , HashMap ...), the container puts/gets the element's hashcode.因为当您的对象被放入基于哈希的容器( HashSetHashMap ...)时,容器会放入/获取元素的哈希码。

hashCode哈希码

Whenever you override equals(), you are also expected to override hashCode().每当您覆盖 equals() 时,您也应该覆盖 hashCode()。 The hash code is used when storing the object as a key in a map.将对象作为键存储在映射中时使用哈希码。

A hash code is a number that puts instances of a class into a finite number of categories.哈希码是将类的实例放入有限数量的类别中的数字。 Imagine that I gave you a deck of cards, and I told you that I was going to ask you for specific cards and I want to get the right card back quickly.想象一下,我给了你一副牌,我告诉你我要问你特定的牌,我想尽快拿回正确的牌。 You have as long as you want to prepare, but I'm in a big hurry when I start asking for cards.只要你想准备,你就可以准备,但是当我开始索要卡片时我很着急。 You might make 13 piles of cards: All of the aces in one pile, all the twos in another pile, and so forth.您可以制作 13 堆牌:所有 A 放在一堆,所有 2 放在另一堆,依此类推。 That way, when I ask for the five of hearts, you can just pull the right card out of the four cards in the pile with fives.这样,当我要求红心五时,您可以从五张牌堆中的四张牌中拉出正确的牌。 It is certainly faster than going through the whole deck of 52 cards!这肯定比遍历整副 52 张牌要快! You could even make 52 piles if you had enough space on the table.如果桌子上有足够的空间,您甚至可以堆成 52 堆。

reference : OCP Oracle Certified Professional Java SE 8 Programmer II参考:OCP Oracle Certified Professional Java SE 8 Programmer II

hashCode() is a unique code which is generated by the JVM for every object creation. hashCode()是 JVM 为每个对象创建生成的唯一代码。

We use hashCode() to perform some operation on hashing related algorithm like Hashtable, Hashmap etc..我们使用hashCode()对 Hashtable、Hashmap 等哈希相关算法执行一些操作。

The advantages of hashCode() make searching operation easy because when we search for an object that has unique code, it helps to find out that object. hashCode()的优点使搜索操作变得容易,因为当我们搜索具有唯一代码的对象时,它有助于找出该对象。

But we can't say hashCode() is the address of an object.但是我们不能说hashCode()是一个对象的地址。 It is a unique code generated by JVM for every object.它是 JVM 为每个对象生成的唯一代码。

That is why nowadays hashing algorithm is the most popular search algorithm.这就是为什么现在散列算法是最流行的搜索算法。

One of the uses of hashCode() is building a Catching mechanism . hashCode() 的用途之一是构建捕获机制 Look at this example:看这个例子:

        class Point
    {
      public int x, y;

      public Point(int x, int y)
      {
        this.x = x;
        this.y = y;
      }

      @Override
      public boolean equals(Object o)
      {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Point point = (Point) o;

        if (x != point.x) return false;
        return y == point.y;
      }

      @Override
      public int hashCode()
      {
        int result = x;
        result = 31 * result + y;
        return result;
      }

class Line
{
  public Point start, end;

  public Line(Point start, Point end)
  {
    this.start = start;
    this.end = end;
  }

  @Override
  public boolean equals(Object o)
  {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;

    Line line = (Line) o;

    if (!start.equals(line.start)) return false;
    return end.equals(line.end);
  }

  @Override
  public int hashCode()
  {
    int result = start.hashCode();
    result = 31 * result + end.hashCode();
    return result;
  }
}
class LineToPointAdapter implements Iterable<Point>
{
  private static int count = 0;
  private static Map<Integer, List<Point>> cache = new HashMap<>();
  private int hash;

  public LineToPointAdapter(Line line)
  {
    hash = line.hashCode();
    if (cache.get(hash) != null) return; // we already have it

    System.out.println(
      String.format("%d: Generating points for line [%d,%d]-[%d,%d] (no caching)",
        ++count, line.start.x, line.start.y, line.end.x, line.end.y));
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM