
public class HashMap<K,V>
extends AbstractMap<K,V>
implements Map<K,V>, Cloneable, Serializable
{
static final int DEFAULT_INITIAL_CAPACITY = 16
static final int MAXIMUM_CAPACITY = 1 <<30
static final float DEFAULT_LOAD_FACTOR = 0.75f
transient Entry[] table
transient int size
int threshold
final float loadFactor
transient volatile int modCount
public HashMap(int initialCapacity, float loadFactor) {
if (initialCapacity <0)
throw new IllegalArgumentException("Illegal initial capacity: "
initialCapacity)
if (initialCapacity >MAXIMUM_CAPACITY)
initialCapacity = MAXIMUM_CAPACITY
if (loadFactor <= 0 || Float.isNaN(loadFactor))
throw new IllegalArgumentException("Illegal load factor: "
loadFactor)
int capacity = 1
while (capacity <initialCapacity)
capacity <<= 1
this.loadFactor = loadFactor
threshold = (int)(capacity * loadFactor)
table = new Entry[capacity]
init()
}
public HashMap(int initialCapacity) {
this(initialCapacity, DEFAULT_LOAD_FACTOR)
}
public HashMap() {
this.loadFactor = DEFAULT_LOAD_FACTOR
threshold = (int)(DEFAULT_INITIAL_CAPACITY * DEFAULT_LOAD_FACTOR)
table = new Entry[DEFAULT_INITIAL_CAPACITY]
init()
}
public HashMap(Map<? extends K, ? extends V>m) {
this(Math.max((int) (m.size() / DEFAULT_LOAD_FACTOR) 1,
DEFAULT_INITIAL_CAPACITY), DEFAULT_LOAD_FACTOR)
putAllForCreate(m)
}
....
一下省略 --~
HashMap 和 HashSet 是 Java Collection Framework 的两个重要成员,其中 HashMap 是 Map 接口的常用实现类,HashSet 是 Set 接口的常用实现类。虽然 HashMap 和 HashSet 实现的接口规范不同,但它们悄誉槐底层的 Hash 存储机制完全一样,甚至 HashSet 本身就采用 HashMap 来实现的。1. 程序试图将多个 key-value 放入 HashMap 中时,以如下代码片段为例:
Java代码
HashMap<String , Double>map = new HashMap<String , Double>()
map.put("语文" , 80.0)
map.put("数学" , 89.0)
map.put("英语" , 78.2)
2.HashMap 采用一种所谓的“Hash 算法”来决定每个元素的存储位置。
当程序执行 map.put("语文" , 80.0)时,系虚镇统将调用"语文"的 hashCode() 方法得到其 hashCode 值——每个 Java 对象都有 hashCode() 方法,都可通过该方法获得它的 hashCode 值。得到这个对象的 hashCode 值之后,系统会根据该 hashCode 值来决定该元素的存储位置。
3. HashMap 类的 put(K key , V value) 方法的源代码:
public V put(K key, V value)
{
// 如果 key 为 null,调用 putForNullKey 方法进行处理
if (key == null)
return putForNullKey(value)
// 根据 key 的 keyCode 计算 Hash 值
int hash = hash(key.hashCode())
// 搜索指定 hash 值在对应 table 中的索引
int i = indexFor(hash, table.length)
// 如果 i 索引处的 Entry 不为 null,通过循环不断遍历 e 元素的下一个元素
for (Entry<K,V>e = table[i]e != nulle = e.next)
{
Object k
// 找到指定启友 key 与需要放入的 key 相等(hash 值相同
// 通过 equals 比较放回 true)
if (e.hash == hash &&((k = e.key) == key
|| key.equals(k)))
{
V oldValue = e.value
e.value = value
e.recordAccess(this)
return oldValue
}
}
// 如果 i 索引处的 Entry 为 null,表明此处还没有 Entry
modCount++
// 将 key、value 添加到 i 索引处
addEntry(hash, key, value, i)
return null
}
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)