简体   繁体   English

是否只在类对象的情况下需要hashcode()?

[英]is hashcode() required only in case of class objects?

I am trying to understand hashcode() . 我想了解hashcode() I have 2 scenarios 我有2个场景

1) implementing hashmap with employee2 class objects 1)使用employee2类对象实现hashmap

2) implementing hashMap with primitives(though they are not primitives) 2)用基元实现hashMap (虽然它们不是基元)

In case of class objects i understand that if i don't implement hashcode() it generates a random hashcode() every time , so when i retrieve the object , it looks into some different bucket each time and return NULL 在类对象的情况下我理解如果我没有实现hashcode()它每次都会生成一个随机的hashcode(),所以当我检索对象时, 它每次都会查看一些不同的桶并返回NULL

But why dosen't this happen in the 2nd case when i don't use class objects 但是,当我不使用类对象时,为什么不在第二种情况下发生这种情况

code is as follows: 代码如下:

package programs;
import java.util.*;

public class employee2
{
  private int empid;
  private String name;
  private String dept;
  public employee2(int empid,String name,String dept){
   this.empid=empid;
   this.name=name;
   this.dept=dept;
 }
 int getEmpid(){
    return this.empid;
 }
 @Override public boolean equals(Object o){
      employee2 e=(employee2)o;
     return getEmpid()==e.empid;
  } 

 @Override public int hashCode() {
    int hash = 7;
    hash = 83 * hash + this.empid;
    return hash;
 } 
  @Override public String toString(){
     return empid+", "+name; 
 }


 public static void main(String args[]){
    //HashMap with employee class objects  
       Map<employee2,String> emap=new HashMap<>();    
       emap.put(new employee2(98446,"Amol Singh","Science"),"good");
       emap.put(new employee2(98446,"Robin Singh","Math"),"very good");

   // I get null if i dont override hashcode()    
       System.out.println(emap.get(new employee2(98446,"Robin Singh","Math"))); 

   // New HashMap without Class objects   
       Map<Integer,String> emap2=new HashMap<>();
       emap2.put(23,"amol");
       emap2.put(2,"Robin");

   // I get correct answer without overriding hashcode()    
       System.out.println(emap2.get(23)); 
   }     
}

Hash-based collections require hashCode to be overriden. 基于散列的集合需要覆盖hashCode。

If you don't override it, they won't work fine. 如果你不覆盖它,它们将无法正常工作。

Integer has it's own hashCode implementation, so you don't have to do anything when working with it in collections. Integer拥有自己的hashCode实现,因此在集合中使用它时不必执行任何操作。

But you have to do this with the classes thay you create, if they are to be placed in hash-based collections 但是,如果要将它们放在基于散列的集合中,则必须使用您创建的类来执行此操作

If you for example look at the source code of String, there is also a very good algorithm for hashcode already implemented 例如,如果您查看String的源代码,那么已经实现的哈希码也有一个非常好的算法

So for the Wrapper classes and String there will never be need of writing the hashcode method by your own 因此对于Wrapper类和String,永远​​不需要自己编写hashcode方法

In your second scenario - when your are putting integer value in a map the primitive type converted to its corresponding object wrapper class. 在第二种情况下 - 当您将整数值放入映射时,原始类型转换为其对应的对象包装类。 This is called autoboxing . 这称为自动装箱 So your int converted to Integer class which already override the hashcode and equals method. 所以你的int转换为Integer类,它已经覆盖了hashcodeequals方法。 Take look at Integer class. 看看Integer类。

And in your first case you have defined your own class. 在你的第一个案例中,你已经定义了自己的类。 So you need to supply your own equals and hashcode method. 所以你需要提供自己的equalshashcode方法。

I found this post, which probably helps to explain it. 我发现这篇文章,这可能有助于解释它。

what-is-the-default-implementation-of-hashcode 什么-是最默认实现-OF-哈希码

From what I understand you are creating a new Object to key into your map, and the default implementation of hashCode provided by the JVM is treating that object as distinct from your existing object in the map. 根据我的理解,您正在创建一个新的Object来键入您的地图,JVM提供的hashCode的默认实现是将该对象视为与地图中的现有对象不同。

Here is the direct link to the java doc for hashcode. 这是hashcode的java doc的直接链接。 Object.hashCode() and the snippet that concerns this question. Object.hashCode()和涉及此问题的代码段。

As much as is reasonably practical, the hashCode method defined by class Object does return distinct integers for distinct objects 尽可能合理,Object类定义的hashCode方法确实为不同的对象返回不同的整数

The moral of the story is that if you are using HashSets with an object you should always define your own hashCode implementation. 故事的寓意是,如果您将HashSets与对象一起使用,则应始终定义自己的hashCode实现。 There are caveats though, for example if you are using singletons. 但是有一些警告,例如,如果你使用单身人士。

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

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