【问题标题】:is hashcode() required only in case of class objects?仅在类对象的情况下才需要 hashcode() 吗?
【发布时间】:2016-06-13 04:38:28
【问题描述】:

我想了解hashcode()。我有两个场景

1) 使用employee2 类对象实现hashmap

2) 使用原语实现hashMap(尽管它们不是原语)

如果是类对象,我知道如果我不实现hashcode(),它每次都会生成一个随机哈希码(),所以当我检索对象时,它每次都会查看一些不同的存储桶并返回空

但是当我不使用类对象时,为什么在第二种情况下不会发生这种情况

代码如下:

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)); 
   }     
}

【问题讨论】:

  • Integer 使用原语int 的值作为哈希码。
  • 如果你看一下 Integer 类的源代码,它也实现了自己的 hashcode 方法。
  • @zombie 所以 Integer 的hashcode 值是 int 的值,对吗?
  • @Amol 查看 Integer 类 grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/… 的源代码,并寻找 hashcode 实现以便更好地理解。
  • @zombie ... 是的,它返回哈希码作为 int 的值 ..但是由于哈希码是指条目对象的表数组的索引,所以如果 int 更大,那不会是性能问题说1000

标签: java hashmap hashcode


【解决方案1】:

基于哈希的集合需要覆盖 hashCode。

如果你不覆盖它,它们将无法正常工作。

Integer 拥有自己的 hashCode 实现,因此在集合中使用它时您无需执行任何操作。

但是如果要将它们放置在基于哈希的集合中,则必须对创建的类执行此操作

【讨论】:

    【解决方案2】:

    如果你例如看一下String的源代码,还有一个很好的hashcode算法已经实现了

    所以对于 Wrapper 类和 String 来说,永远不需要自己编写 hashcode 方法

    【讨论】:

      【解决方案3】:

      在您的第二种情况下 - 当您将整数值放入映射时,原始类型转换为其相应的对象包装类。这称为autoboxing。因此,您的 int 转换为已经覆盖 hashcodeequals 方法的 Integer 类。看看Integer类。

      在您的第一种情况下,您已经定义了自己的类。所以你需要提供你自己的equalshashcode 方法。

      【讨论】:

        【解决方案4】:

        我找到了这篇文章,这可能有助于解释它。

        what-is-the-default-implementation-of-hashcode

        据我了解,您正在创建一个新对象来键入您的地图,而 JVM 提供的 hashCode 的默认实现将该对象与地图中的现有对象区别开来。

        这里是哈希码的 java 文档的直接链接。 Object.hashCode() 和涉及这个问题的 sn-p。

        在合理可行的情况下,由 Object 类定义的 hashCode 方法确实为不同的对象返回不同的整数

        这个故事的寓意是,如果您将 HashSets 与对象一起使用,您应该始终定义自己的 hashCode 实现。但是有一些注意事项,例如,如果您使用的是单例。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-02-10
          • 1970-01-01
          • 2014-11-06
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多