提到hashtable,先要澄清两个问题hashCode与equals().Hashtable有容量和加载因子,容量相当于桶,因子相当于桶里的对象.而hashCode我们可以把它理解为桶的序号,所以HashCode相同的,即它们在同一个桶里,这两上对象就在同一个桶里,这时候如果他们还equals()的话,那么这两个对象就是一样的.而如果他们的hashCode不一样,即他们不在同一个桶里,那么这两个对象肯定是不一样的.

     所以我们在用hashtable进行存储对象时要重写他们的hashCode与equals(),否则会出现很多重复的对象.

 

    hashtable与hashMap最大的区别是,hashtable是方法同步的,而后者是异步的.

先来看看下面的例子吧:

 

Java代码  收藏代码
  1. public class Ball {  
  2.   
  3.     private int size;  
  4.     private String name;  
  5.   
  6.     public Ball(int size, String name) {  
  7.         this.size = size;  
  8.         this.name = name;  
  9.     }  
  10.   
  11.     public void setSize(int size) {  
  12.         this.size = size;  
  13.     }  
  14.   
  15.     public int getSize() {  
  16.         return size;  
  17.     }  
  18.   
  19.     public void setName(String name) {  
  20.         this.name = name;  
  21.     }  
  22.   
  23.     public String getName() {  
  24.         return name;  
  25.     }  
  26.   
  27.     public static void main(String[] args) {  
  28.         Hashtable<Ball, String> hash = new Hashtable<Ball, String>();  
  29.         hash.put(new Ball(1"one"), "1");  
  30.         hash.put(new Ball(2"two"), "2");  
  31.         hash.put(new Ball(1"one"), "1");  
  32.         System.out.println(hash.size());  
  33.     }  
  34. }  

 

可能有的人会认为打印出出来的结果当然是2,有一个是重复的

但结果是3.

因为默认它们都是用Object对象来实现比较的,所以它们的hashCode当然是不一样的

我们可以加以下代码检查是否是这样

Java代码  收藏代码
  1. @Override  
  2.    public int hashCode() {  
  3.        System.out.println(super.hashCode());  
  4.        return super.hashCode();  
  5.    }  

那么,如何才能去掉重复的对象的

这里我们必须重写hashCode,如下,我们可以把size相同的对象放入同一个桶里,再比较他们的name

把hashCode方法改为

Java代码  收藏代码
  1. @Override  
  2.   public int hashCode() {  
  3.       System.out.println(size);  
  4.       return size;  
  5.   }  
  6. 写equals();  
Java代码  收藏代码
  1. <pre class="java" name="code">    @Override  
  2.     public boolean equals(Object obj) {  
  3.         if (obj instanceof Ball) {  
  4.             Ball ball = (Ball) obj;  
  5.             return name.equals(ball.getName());  
  6.         }  
  7.         return false;  
  8.     }</pre>  
  9.    

再试试,结果就是为2.

  hashtable再每添加一个对象的都会先判断他们的hashCode是否一样,如果一样再判断他们是否equals(),如果返回为true的话,那么这个对象将不添加

我们也可以看一下源代码实现

 

Java代码  收藏代码
  1. /** 
  2.     * Maps the specified <code>key</code> to the specified 
  3.     * <code>value</code> in this hashtable. Neither the key nor the 
  4.     * value can be <code>null</code>. <p> 
  5.     * 
  6.     * The value can be retrieved by calling the <code>get</code> method 
  7.     * with a key that is equal to the original key. 
  8.     * 
  9.     * @param      key     the hashtable key 
  10.     * @param      value   the value 
  11.     * @return     the previous value of the specified key in this hashtable, 
  12.     *             or <code>null</code> if it did not have one 
  13.     * @exception  NullPointerException  if the key or value is 
  14.     *               <code>null</code> 
  15.     * @see     Object#equals(Object) 
  16.     * @see     #get(Object) 
  17.     */  
  18.    public synchronized V put(K key, V value) {  
  19. // Make sure the value is not null  
  20. if (value == null) {  
  21.     throw new NullPointerException();  
  22. }  
  23.   
  24. // Makes sure the key is not already in the hashtable.  
  25. Entry tab[] = table;  
  26. int hash = key.hashCode();  
  27. int index = (hash & 0x7FFFFFFF) % tab.length;  
  28. for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) {  
  29.     if ((e.hash == hash) && e.key.equals(key)) {  
  30.     V old = e.value;  
  31.     e.value = value;  
  32.     return old;//这里如果比较结果相同时就返回原来的值  
  33.     }  
  34. }  
  35.   
  36. modCount++;  
  37. if (count >= threshold) {  
  38.     // Rehash the table if the threshold is exceeded  
  39.     rehash();  
  40.   
  41.            tab = table;  
  42.            index = (hash & 0x7FFFFFFF) % tab.length;  
  43. }  
  44.   
  45. // Creates the new entry.  
  46. Entry<K,V> e = tab[index];  
  47. tab[index] = new Entry<K,V>(hash, key, value, e);  
  48. count++;  
  49. return null;  
  50.    }  

 

 

hashMap允许键与值为空.其他的和hashtable是一样的.

具体可再参考API...

posted on 2013-10-23 10:51  Rosepotato  阅读(233)  评论(0编辑  收藏  举报