LinkedHashMap

LinkedHashMap详解
LinkedHashMap是Map接口下的一个具体实现类,具有可预知的迭代顺序。该实现类具有同HashMap相似的特性,此实现与 HashMap 的不同之处在于,后者维护着一个运行于所有条目的双重链接列表。此链接列表定义了迭代顺序,该迭代顺序通常就是将键插入到映射中的顺序(插入顺序)。注意,如果在映射中重新插入 键,则插入顺序不受影响。(如果在调用 m.put(k, v) 前 m.containsKey(k) 返回了 true,则调用时会将键 k 重新插入到映射 m 中。)

链接的哈希映射具有两个影响其性能的参数:初始容量和加载因子。它们的定义与 HashMap 极其相似。要注意,为初始容量选择非常高的值对此类的影响比对 HashMap 要小,因为此类的迭代时间不受容量的影响。

该实现类提供了五个构造方法:
1.LinkedHashMap() 构造一个带默认初始容量 (16) 和加载因子 (0.75) 的空插入顺序 LinkedHashMap 实例。
2.LinkedHashMap(int initialCapacity) 构造一个带指定初始容量和默认加载因子 (0.75) 的空插入顺序 LinkedHashMap 实例。
3.LinkedHashMap(int initialCapacity, float loadFactor) 构造一个带指定初始容量和加载因子的空插入顺序 LinkedHashMap 实例。
4.LinkedHashMap(int initialCapacity, float loadFactor, boolean accessOrder) 构造一个带指定初始容量、加载因子和排序模式的空LinkedHashMap 实例。
5.LinkedHashMap(Map m) 构造一个映射关系与指定映射相同的插入顺序 LinkedHashMap 实例。
参考自(jdk中文文档):jdk1.7中文文档
-底层数据结构:数组加链表

put过程:

/*父类HashMap的实现*/
    public V put(K key, V value) {
        if (table == EMPTY_TABLE) {
            inflateTable(threshold);
        }
        if (key == null)                         //key为null特殊处理
            return putForNullKey(value);
        int hash = hash(key);               //对key进行hash
        int i = indexFor(hash, table.length);          //通过key的hash值找到table数组对应的下标
        for (Entry e = table[i]; e != null; e = e.next) {    //遍历table数组对应下标下的链表
            Object k;
            if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {     //判断key是否重复
                V oldValue = e.value;
                e.value = value;
                e.recordAccess(this);
                return oldValue;
            }
        }

        modCount++;   
        addEntry(hash, key, value, i);        //添加该数据
        return null;
    }
    
    /*LinkedHashMap的实现*/
    void addEntry(int hash, K key, V value, int bucketIndex) {
        super.addEntry(hash, key, value, bucketIndex);     //调用HashMap的添加方法
        Entry eldest = header.after;  //获取头结点的下一个元素
        if (removeEldestEntry(eldest)) {
            removeEntryForKey(eldest.key);
        }
    }
    
    /*父类HashMap的实现*/
    void addEntry(int hash, K key, V value, int bucketIndex) {        
        if ((size >= threshold) && (null != table[bucketIndex])) {        //判断是否需要给数组扩容
            resize(2 * table.length);
            hash = (null != key) ? hash(key) : 0;
            bucketIndex = indexFor(hash, table.length);
        }

        createEntry(hash, key, value, bucketIndex);       //调用createEntry()方法(实际上调用的是LinkedHashMap重写的方法)
    }


    /*LinkedHashMap的实现*/
    void createEntry(int hash, K key, V value, int bucketIndex) {       //头插法实现添加元素
        HashMap.Entry old = table[bucketIndex];              //获取对应下标数组的头结点
        Entry e = new Entry<>(hash, key, value, old);
        table[bucketIndex] = e;                 
        e.addBefore(header);  
        size++;
    }

    /*LinkedHashMap的实现*/
     private void addBefore(Entry existingEntry) { 
            after  = existingEntry;          //获取到链表的头
            before = existingEntry.before;         //获取头结点的上一个元素
            before.after = this;                   
            after.before = this;
        }

该集合在使用迭代器打印时accessOrder若为true则按照插入顺序打印,反之则为无需打印。

你可能感兴趣的:(集合,LinkedHashMap,集合,有序打印,Map,存储)