jdk源码分析(Map篇)

1:map提供了三种视图形式:key的set,key-value的set,value的Collection,
2:map中有有排序接口,如sortMap的实现类,实现了这个接口的有排序功能,如treeMap,而HashMap则没有。
3:具有破坏性的操作/不支持的操作会抛出UnsupportedOperationException
4:影响hashMap的两个因素是initial Capacity和Load factor;
5:the default load factor (.75)
6:Note that this implementation is not synchronized.这个实现类是不加锁的。

 * If no such object exists, the map should be "wrapped" using the
 * {@link Collections#synchronizedMap Collections.synchronizedMap}
 * method.  This is best done at creation time, to prevent accidental
 * unsynchronized access to the map:<pre>
 *   Map m = Collections.synchronizedMap(new HashMap(...));</pre>
 *

官方说其中一种加锁方式是上面的代码。打开这个方法会看到传入的是一个final的Map
7:hashtable是公有方法上synchronised的,包括JDK1.8中map新增加的几个方法都有重写并加锁,如果你不涉及到线程安全使用HashMap,因为性能高,如果涉及到线程安全,使用concurrentHashMap;
在这里插入图片描述
8:hashmap中的hash(key)

static final int hash(Object key) {
        int h;
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    }

获取了key的哈希码,进行了高位与低位的异或运算。
而hashtable中的hash(key)是直接获取了hashcode作为哈希码的。
9:动态扩容,当容量达到了load factor时,则进行扩容,这不会修改对象。
扩容是通过左移操作完成的。每当达到阈值时,判断capacity是否是Integer最大值,如果是则返回Oldvalue,如果不是,则左移一位,作为新的capacity。然后重新计算hash值。重新存储。
10:每一个键值对存放在Node<K,V>中,其中有一个hash值就是hash(key)获取的。
11:在HashMap中,当我们putval时会在最后调用afterNodeInsertion方法,而这个方法最典型的就是在LinkedHashmap中的重写,用来删除最早放入Map的对象

void afterNodeInsertion(boolean evict) { // possibly remove eldest
        LinkedHashMap.Entry<K,V> first;
        if (evict && (first = head) != null && removeEldestEntry(first)) {
            K key = first.key;
            removeNode(hash(key), key, null, false, true);
        }
    }

12:hashtable不接收null的key和null的value,而hashmap接收。
13:hashtable继承Dictionary,而hashMap继承AbstractMap,
14:hashtable的最小单元是一个Entry,而hashmap最小单元是一个Node

猜你喜欢

转载自blog.csdn.net/weixin_39781526/article/details/85134388