源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

详解Java中用于查找对象哈希码值的hashCode()函数

  • 时间:2022-04-13 13:52 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:详解Java中用于查找对象哈希码值的hashCode()函数
[b]理解 [/b]hashCode() 的作用是获取哈希码,也称为散列码;它实际上是返回一个int整数。这个哈希码的作用是确定该对象在哈希表中的索引位置。 hashCode() 定义在JDK的Object.java中,这就意味着Java中的任何类都包含有hashCode() 函数。 虽然,每个Java类都包含hashCode() 函数。但是,仅仅当创建并某个“类的散列表”(关于“散列表”见下面说明)时,该类的hashCode() 才有用(作用是:确定该类的每一个对象在散列表中的位置;其它情况下(例如,创建类的单个对象,或者创建类的对象数组等等),类的hashCode() 没有作用。 上面的散列表,指的是:Java集合中本质是散列表的类,如HashMap,Hashtable,HashSet。 也就是说:hashCode() 在散列表中才有用,在其它情况下没用。在散列表中hashCode() 的作用是获取对象的散列码,进而确定该对象在散列表中的位置。 我们都知道,散列表存储的是键值对(key-value),它的特点是:能根据“键”快速的检索出对应的“值”。这其中就利用到了散列码! 散列表的本质是通过数组实现的。当我们要获取散列表中的某个“值”时,实际上是要获取数组中的某个位置的元素。而数组的位置,就是通过“键”来获取的;更进一步说,数组的位置,是通过“键”对应的散列码计算得到的。 下面,我们以HashSet为例,来深入说明hashCode()的作用。 假设,HashSet中已经有1000个元素。当插入第1001个元素时,需要怎么处理?因为HashSet是Set集合,它允许有重复元素。 “将第1001个元素逐个的和前面1000个元素进行比较”?显然,这个效率是相等低下的。散列表很好的解决了这个问题,它根据元素的散列码计算出元素在散列表中的位置,然后将元素插入该位置即可。对于相同的元素,自然是只保存了一个。 由此可知,若两个元素相等,它们的散列码一定相等;但反过来确不一定。在散列表中, 1、如果两个对象相等,那么它们的hashCode()值一定要相同; 2、如果两个对象hashCode()相等,它们并不一定相等。 注意:这是在散列表中的情况。在非散列表中一定如此! [b]示例 [/b]我们来看一个具体的示例吧,
public class HashTest { 
  private int i; 
 
  public int getI() { 
    return i; 
  } 
 
  public void setI(int i) { 
    this.i = i; 
  } 
 
  public int hashCode() { 
    return i % 10; 
  } 
 
  public final static void main(String[] args) { 
    HashTest a = new HashTest(); 
    HashTest b = new HashTest(); 
    a.setI(1); 
    b.setI(1); 
    Set<HashTest> set = new HashSet<HashTest>(); 
    set.add(a); 
    set.add(b); 
    System.out.println(a.hashCode() == b.hashCode()); 
    System.out.println(a.equals(b)); 
    System.out.println(set); 
  } 
} 

这个输出的结果:
true 
false 
[com.ubs.sae.test.HashTest@1, com.ubs.sae.test.HashTest@1] 

以上这个示例,我们只是重写了hashCode方法,从上面的结果可以看出,虽然两个对象的hashCode相等,但是实际上两个对象并不是相等;,我们没有重写equals方法,那么就会调用object默认的equals方法,是比较两个对象的引用是不是相同,显示这是两个不同的对象,两个对象的引用肯定是不定的。这里我们将生成的对象放到了HashSet中,而HashSet中只能够存放唯一的对象,也就是相同的(适用于equals方法)的对象只会存放一个,但是这里实际上是两个对象a,b都被放到了HashSet中,这样HashSet就失去了他本身的意义了。 此时我们把equals方法给加上:
public class HashTest { 
  private int i; 
 
  public int getI() { 
    return i; 
  } 
 
  public void setI(int i) { 
    this.i = i; 
  } 
 
  <span style="color:#3366FF;"><strong>public boolean equals(Object object) { 
    if (object == null) { 
      return false; 
    } 
    if (object == this) { 
      return true; 
    } 
    if (!(object instanceof HashTest)) { 
      return false; 
    } 
    HashTest other = (HashTest) object; 
    if (other.getI() == this.getI()) { 
      return true; 
    } 
    return false; 
  }</strong></span> 
 
  public int hashCode() { 
    return i % 10; 
  } 
 
  public final static void main(String[] args) { 
    HashTest a = new HashTest(); 
    HashTest b = new HashTest(); 
    a.setI(1); 
    b.setI(1); 
    Set<HashTest> set = new HashSet<HashTest>(); 
    set.add(a); 
    set.add(b); 
    System.out.println(a.hashCode() == b.hashCode()); 
    System.out.println(a.equals(b)); 
    System.out.println(set); 
  } 
} 
此时得到的结果就会如下:
true 
true 
[com.ubs.sae.test.HashTest@1] 

从结果我们可以看出,现在两个对象就完全相等了,HashSet中也只存放了一份对象。 [b]总结 [/b]1、hashCode的存在主要是用于查找的快捷性,如Hashtable,HashMap等,hashCode是用来在散列存储结构中确定对象的存储地址的; 2、如果两个对象相同,就是适用于equals(java.lang.Object) 方法,那么这两个对象的hashCode一定要相同; 3、如果对象的equals方法被重写,那么对象的hashCode也尽量重写,并且产生hashCode使用的对象,一定要和equals方法中使用的一致,否则就会违反上面提到的第2点; 4、两个对象的hashCode相同,并不一定表示两个对象就相同,也就是不一定适用于equals(java.lang.Object) 方法,只能够说明这两个对象在散列存储结构中,如Hashtable,他们“存放在同一个篮子里”。
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部