zoukankan      html  css  js  c++  java
  • 关于hashcode()

    1.hashcode是用来查找的,如果你学过数据结构就应该知道,在查找和排序这一章有 
    例如内存中有这样的位置 
    0     1     2     3     4     5     6     7     
    而我有个类,这个类有个字段叫ID,我要把这个类存放在以上8个位置之一,如果不用hashcode而任意存放,那么当查找时就需要到这八个位置里挨个去找,或者用二分法一类的算法。 
    但如果用hashcode那就会使效率提高很多。 
    我们这个类中有个字段叫ID,那么我们就定义我们的hashcode为ID%8,然后把我们的类存放在取得得余数那个位置。比如我们的ID为9,9除8的 余数为1,那么我们就把该类存在1这个位置,如果ID是13,求得的余数是5,那么我们就把该类放在5这个位置。这样,以后在查找该类时就可以通过ID除 8求余数直接找到存放的位置了。 

    2.但是如果两个类有相同的hashcode怎么办那(我们假设上面的类的ID不是唯一的),例如9除以8和17除以8的余数都是1,那么这是不是合法的,回答是:可以这样。那么如何判断呢?在这个时候就需要定义   equals了。 
    也就是说,我们先通过   hashcode来判断两个类是否存放某个桶里,但这个桶里可能有很多类,那么我们就需要再通过   equals   来在这个桶里找到我们要的类。 
    那么。重写了equals(),为什么还要重写hashCode()呢? 
    想想,你要在一个桶里找东西,你必须先要找到这个桶啊,你不通过重写hashcode()来找到桶,光重写equals()有什么用啊

    hashCode()是用来产生哈希玛的,而哈希玛是用来在散列存储结构中确定对象的存储地址的,(这一段在 Java编程思想 中讲的很清楚的)象util包中的 带 hash 的集合类都是用这种存储结构 :HashMap,HashSet, 他们在将对象存储时(严格说是对象引用),需要确定他们的地址吧, 而HashCode()就是这个用途的,一般都需要重新定义它的,因为默认情况下,由 Object 类定义的 hashCode 方法会针对不同的对象返回不同的整数,这一般是通过将该对象的内部地址转换成一个整数来实现的,现在举个例子来说, 就拿HashSet来说 ,在将对象存入其中时,通过被存入对象的 hashCode() 来确定对象在 HashSet 中的存储地址,通过equals()来确定存入的对象是否重复,hashCode() ,equals()都需要自己重新定义,因为hashCode()默认前面已经说啦,而equals() 默认是比较的对象引用,你现在想一下,如果你不定义equals()的话,那么同一个类产生的两个内容完全相同的对象都可以存入Set,因为他们是通过 equals()来确定的,这样就使得HashSet 失去了他的意义,看一下下面这个: 
    import java.util.*;
    /**
    *类说明
    * @author shellfeng E-mail:lsf830804@yahoo.com.cn
    * @version 1.0 
    *
    */
    public class Test {
    public static void main(String[] args) {
    HashSet set = new HashSet();
    for (int i = 0; i <= 3; i++){
    set.add(new Demo1(i,i)); 
    }
    System.out.println(set);
    set.add(new Demo1(1,1));
    System.out.println(set);
    System.out.println(set.contains(new Demo1(0,0)));
    System.out.println(set.add(new Demo1(1,1)));
    System.out.println(set.add(new Demo1(4,4)));
    System.out.println(set);
    }

    private static class Demo1 {
    private int value;

    private int id;

    public Demo1(int value,int id) {
    this.value = value;
    this.id=id;
    }

    public String toString() {
    return " value = " + value;
    }

    public boolean equals(Object o) {
    Demo1 a = (Demo1) o;
    return (a.value == value) ? true : false;
    }

    public int hashCode() {
    return id;
    }
    }
    }
    你分别注释掉hashCode()和 equals()来比较一下他们作用就可以拉,关键要自己动手看看比较的结果你就可以记得很清楚啦
    结果:
    [ value = 2,  value = 1,  value = 3,  value = 0]
    [ value = 2,  value = 1,  value = 3,  value = 0]
    true
    false
    true
    [ value = 2,  value = 4,  value = 1,  value = 3,  value = 0]

    注释掉hashCode()
    [ value = 1,  value = 0,  value = 2,  value = 3]
    [ value = 1,  value = 0,  value = 1,  value = 2,  value = 3]
    false
    true
    true
    [ value = 1,  value = 0,  value = 1,  value = 2,  value = 3,  value = 4,  value = 1]

    注释掉equals()
    [ value = 2,  value = 1,  value = 3,  value = 0]
    [ value = 2,  value = 1,  value = 1,  value = 3,  value = 0]
    false
    true
    true
    [ value = 2,  value = 4,  value = 1,  value = 1,  value = 1,  value = 3,  value = 0]

    hashCode()方法使用来提高Map里面的搜索效率的,Map会根据不同的hashCode()来放在不同的桶里面,Map在搜索一个对象的时候先 通过hashCode()找到相应的桶,然后再根据equals()方法找到相应的对象.要正确的实现Map里面查找元素必须满足一下两个条件: 
    (1)当obj1.equals(obj2)为true时obj1.hashCode() == obj2.hashCode()必须为true 

    (2)当obj1.hashCode() == obj2.hashCode()为false时obj.equals(obj2)必须为false 

     原文连接:http://www.blogjava.net/alinglau36/archive/2009/02/16/254847.html 
     

  • 相关阅读:
    (转)UIMenuController的使用,对UILabel拷贝以及定制菜单
    (转)ios多线程开发——NSOperation详解
    IOS custom statusBar 思路
    objectiveC的@property(atomic, retain)对引用计数的影响
    A Generic Particle IO Library
    RenderMan与CG生产流程简述
    Maya Mesh Relaxation Deformer
    个人黄金市场交易记录/Personal Gold Market Operation Record
    Implementation of TLRW ReadWrite Lock
    给想雇佣我的人说的话/Some words to somebody who want to hire me.
  • 原文地址:https://www.cnblogs.com/yimu/p/2782354.html
Copyright © 2011-2022 走看看