找回状态,找回激情

最近工作不在状态,不是很忙,自学的时间还是很多,时间没好好利用起来,决定动笔写写,持之以恒,希望自己一点点进步。
先插入一句题外话,火箭今天输了,有点桑心,下一场灭了勇士。


从一道面试题开始本篇,一道命中率极高的问题。
Hashtable & HashMap的区别。

1.我们先看两个类的定义(jdk1.6

public class HashMap<K,V> extends AbstractMap<K,V>
    implements Map<K,V>, Cloneable, Serializable{

public class Hashtable<K,V> extends Dictionary<K,V>
    implements Map<K,V>, Cloneable, java.io.Serializable {

可见Hashtable 继承自 Dictionary, 而HashMap继承自AbstractMap

2.HashMap允许将null作为一个entry的key或者value,而Hashtable不允许。为什么Hashtable不允许null?

public synchronized V put(K key, V value) {
    // Make sure the value is not null
    if (value == null) {
        throw new NullPointerException();
    }

    // Makes sure the key is not already in the hashtable.
    Entry tab[] = table;
    int hash = key.hashCode();
    .........
}

上面是Hashtable的源码,key或者value等于null,都会抛出空指针。
对比下HashMap的源码:

public V put(K key, V value) {
        if (key == null)
            return putForNullKey(value);
       ..........
}

3.HashMap把Hashtable的contains方法去掉了,因为contains方法容易让人引起误解,containsValue实现了contains的功能。
这里写图片描述
这里写图片描述
看下Hashtable 的containsValue方法:

public boolean containsValue(Object value) {
        return contains(value);
}

4.最大的不同是,Hashtable的方法是synchronized的,而HashMap不是,在多个线程访问Hashtable时,不需要自己为它的方法实现同步,而HashMap 就必须为之提供外同步(Collections.synchronizedMap)
5.Collections.synchronizedMap做了些什么?
源码很简答,创建了一个静态内部类,SynchronizedMap。
关键看下这个类里面的put,get,remove,containsKey等方法实现。

private static class SynchronizedMap<K,V>
    implements Map<K,V>, Serializable {

    private final Map<K,V> m;     // Backing Map
    final Object      mutex;    // Object on which to synchronize

    SynchronizedMap(Map<K,V> m) {
            if (m==null)
                throw new NullPointerException();
            this.m = m;
            mutex = this;
    }

    SynchronizedMap(Map<K,V> m, Object mutex) {
            this.m = m;
            this.mutex = mutex;
    }

    public int size() {
        synchronized(mutex) {return m.size();}
    }
    public boolean isEmpty(){
        synchronized(mutex) {return m.isEmpty();}
        }
    public boolean containsKey(Object key) {
        synchronized(mutex) {return m.containsKey(key);}
        }
    public boolean containsValue(Object value){
        synchronized(mutex) {return m.containsValue(value);}
    }
    public V get(Object key) {
        synchronized(mutex) {return m.get(key);}
        }

    public V put(K key, V value) {
        synchronized(mutex) {return m.put(key, value);}
    }
    public V remove(Object key) {
        synchronized(mutex) {return m.remove(key);}
    }
    public void putAll(Map<? extends K, ? extends V> map)     
    {
        synchronized(mutex) {m.putAll(map);}
    }
    public void clear() {
        synchronized(mutex) {m.clear();}
    }

    private transient Set<K> keySet = null;
    private transient Set<Map.Entry<K,V>> entrySet = null;
    private transient Collection<V> values = null;

    public Set<K> keySet() {
            synchronized(mutex) {
                if (keySet==null)
                    keySet = new SynchronizedSet<K>(m.keySet(), mutex);
                return keySet;
            }
    }

    public Set<Map.Entry<K,V>> entrySet() {
            synchronized(mutex) {
                if (entrySet==null)
                    entrySet = new SynchronizedSet<Map.Entry<K,V>>(m.entrySet(), mutex);
                return entrySet;
            }
    }

    public Collection<V> values() {
            synchronized(mutex) {
                if (values==null)
                    values = new SynchronizedCollection<V>(m.values(), mutex);
                return values;
            }
   }

    public boolean equals(Object o) {
            synchronized(mutex) {return m.equals(o);}
    }
    public int hashCode() {
            synchronized(mutex) {return m.hashCode();}
    }
    public String toString() {
        synchronized(mutex) {return m.toString();}
    }
    private void writeObject(ObjectOutputStream s) throws IOException {
        synchronized(mutex) {s.defaultWriteObject();}
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值