zoukankan      html  css  js  c++  java
  • Hashtable与HashMap区别(2)

    提到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...

  • 相关阅读:
    C#网页数据采集(三)HttpWebRequest
    C#获取局域网ip
    C#调用Mail发送QQ邮件
    C#操作Excel(NPOI)
    html文字两行后,就用省略号代替剩下的
    js的dom测试及实例代码
    js循环数组(总结)
    黑马vue---61、为什么vue组件的data要是一个函数
    黑马vue---59-60、组件中的data和methods
    黑马vue---31-32、vue过滤器实例
  • 原文地址:https://www.cnblogs.com/rosepotato/p/3383772.html
Copyright © 2011-2022 走看看