1

我试图了解linkedhashmap的内部工作。

所以当我们调用linkedhashmap的put(map,key)时。它在内部调用[createEntry][1].

 void createEntry(int hash, K key, V value, int bucketIndex) {
440        HashMap.Entry<K,V> old = table[bucketIndex];
441        Entry<K,V> e = new Entry<K,V>(hash, key, value, old);
442        table[bucketIndex] = e;
443        e.addBefore(header);
444        size++;
445    }

在这里我无法理解旧变量的使用。

为什么在标题之前添加新条目。它应该添加到linkedhashmap 的末尾。

有人可以解释这段代码。

4

2 回答 2

2

为什么在标题之前添加新条目。

这种方式实现起来更简单。HashMap 也是如此。这是冲突链表,而不是迭代器使用的链表。

它应该添加到linkedhashmap 的末尾。

它在哪里说呢?

于 2013-09-09T11:13:30.913 回答
1

首先了解 HashMap put() 方法的工作原理:

使用 put 方法将键值对添加到地图中:

public V put(K var1, V var2) {  
    return this.putVal(hash(var1), var1, var2, false, true);  
}

在这里,我们传递 key - K var1和 value - V var2

该方法在内部put()调用该方法并采用以下参数。putVal()putVal()

  • hash(var1)- 键的hashCode
  • var1 – 键
  • var2 – 值
  • 布尔假值
  • 布尔真值

putVal()首先检查 HashMap 表,如果表为空或为空,则调用该resize()方法。该resize()方法为 HashMap 创建了一个新表。

Resize() 方法调用——最初该表为空。所以第一次使用默认大小创建一个新表。如果在阈值字段中使用HashMap(int initialCapacity)HashMap(int initialCapacity, float loadFactor)构造函数设置了初始容量,则根据阈值设置初始容量。

否则,它将选择表大小的默认初始容量。HashMap 的默认初始容量是 16,这是使用下面的 HashMap 字段定义的。

static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16  

如果定义了初始容量:

int oldThr = threshold; //Threshold is being set in oldThr local field  

然后根据以下条件,如果阈值大于 0,则将其设置为newCap(new capacity for the table)

else if (oldThr > 0) // initial capacity was placed in threshold  
    newCap = oldThr;

否则使用默认值:

newCap = DEFAULT_INITIAL_CAPACITY;  
newThr = (int)(DEFAULT_LOAD_FACTOR * DEFAULT_INITIAL_CAPACITY);  

使用新容量创建新表:

Node<K,V>[] newTab = (Node<K,V>[])new Node[newCap];  

在其他情况下,它会检查MAXIMUM_CAPACITY,如果当前容量大于MAXIMUM_CAPACITY则它会调整表的大小。

返回 putVal 后:

然后如果索引值[(n - 1) & hash],表bucket为空,newNode()则调用该方法,并在HashMap表中计算出的索引处放置一个新创建的入口节点。

if ((p = tab[i = (n - 1) & hash]) == null)  
    tab[i] = newNode(hash, key, value, null);  

然后检查哈希表中的哈希值索引,如果没有已经存在的节点,则它创建一个新节点,其中包含哈希表存储桶中的 hashCode、Key、Value 和下一个节点引用。最初为空,当一个新节点被添加到相同的哈希索引时,将形成一个 LinkedList,因为具有相同哈希码索引的新节点将使用链表的方式以链表的方式附加到先前添加的节点旁边下一个字段参考。

要了解有关 HashMap 的更多信息,请访问: http ://techmastertutorial.in/java-collection-internal-hashmap.html

LinkedHashMap put() 方法:

添加键值对与 HashMap 相同,在 LinkedHash 映射的情况下,我们在前后引用的帮助下保留更多细节。由于我们为每个键值对添加了一个条目,因此在添加条目时,也会更新之前和之后的引用。一个双向链表是由之前和之后的引用组成的。使用 before 和 after 指针,我们可以按插入顺序遍历条目。

我们可以从添加到 LinkedHashMap 的头节点(第一个节点)开始,使用 after 指针遍历,直到 after 为空。

LinkedHashMap 内部工作: http ://techmastertutorial.in/java-collection-internal-linked-hashmap.html

于 2019-06-04T16:54:46.480 回答