-
允许null作为key/value。
-
不保证按照插入的顺序输出。使用hash构造的映射一般来讲是无序的。
-
非线程安全。
-
内部原理与Hashtable类似。
源码简要分析
java;gutter:true;
public class HashMap
{
static final int DEFAULT_INITIAL_CAPACITY = 16 ; // 默认初始容量是16。(必须是2的次方)
static final int MAXIMUM_CAPACITY = 1 << 30 ; // 即2的30次方
static final float DEFAULT_LOAD_FACTOR = 0.75f; // 默认装载因子</p>
<pre><code> Entry[] table; // Entry表
int size; // Entry[]实际存储的Entry个数
int threshold; // reash的阈值,=capacity * load factor
final float loadFactor;
// 构造函数
public HashMap(int initialCapacity, float loadFactor) {
// 找到一个比initialCapacity大的最小的2的次方数
int capacity = 1;
while (capacity < initialCapacity)
capacity < e = table[bucketIndex];
table[bucketIndex] = new Entry<>(hash, key, value, e);
if (size++ >= threshold)
resize(2 * table.length);
}
// put():添加元素
public V put(K key, V value) {
int hash = hash(key.hashCode()); // key的hash值
int i = indexFor(hash,table.length); // 槽位
// 寻找是否已经有key存在,如果已经存在,使用新值覆盖旧值,返回旧值
for (Entry e = table[i]; e != null; e = e.next) {
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
V oldValue = e.value;
e.value = value;
return oldValue;
}
}
// 添加Entry
addEntry(hash,key,value,i);
return null;
}
// resize():重新哈希
void resize(int newCapacity) {
Entry[] oldTable = table;
int oldCapacity = oldTable.length;
Entry[] newTable = new Entry[newCapacity];
transfer(newTable);
table = newTable;
threshold = (int)(newCapacity * loadFactor);
}
/**
* Transfers all entries from current table to newTable.
*/
void transfer(Entry[] newTable) {
Entry[] src = table;
int newCapacity = newTable.length;
for (int j = 0; j < src.length; j++) {
Entry e = src[j];
if (e != null) {
src[j] = null;
do {
Entry next = e.next;
int i = indexFor(e.hash, newCapacity);
e.next = newTable[i];
newTable[i] = e;
e = next;
} while (e != null);
}
}
}
</code></pre>
<p>}</p>
<pre><code>
遍历方式
* 低效遍历:按照Key进行遍历,则每次都需要按Key查找槽位(不同的Key有重复查找),且可能需要遍历槽位上所在Entry链表(不同的Key有重复遍历)。
* 高效遍历:HashMap的entrySet()返回自定义的EntryIterator,是先按照槽位遍历一次,再遍历一次槽位上Entry链表。
;gutter:true;
Map paraMap = new HashMap();
for( Map.Entry entry : paraMap.entrySet() )
{
String appFieldDefId = entry.getKey();
String[] values = entry.getValue();
}
Original: https://www.cnblogs.com/caca/p/java_hashmap.html
Author: cacard
Title: [Java] HashMap 源码简要分析
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/536645/
转载文章受原作者版权保护。转载请注明原作者出处!