我发现在JDK 1.6或更高版本的HashMap类中,与之前的JDK版本(如1.5)相比,一些代码被更改为null.
在JDK1.5中,定义了一个名为NULL_KEY的静态最终Object :static final Object NULL_KEY = new Object();
方法,其中包括maskNull,unmaskNull,get和put等,将使用该对象.
看到
static final Object NULL_KEY = new Object();
static <T> T maskNull(T key) {
return key == null ? (T)NULL_KEY : key;
}
static <T> T unmaskNull(T key) {
return (key == NULL_KEY ? null : key);
}
public V get(Object key) {
Object k = maskNull(key);
int hash = hash(k);
int i = indexFor(hash, table.length);
Entry<K,V> e = table[i];
while (true) {
if (e == null)
return null;
if (e.hash == hash && eq(k, e.key))
return e.value;
e = e.next;
}
}
public V put(K key, V value) {
K k = maskNull(key);
int hash = hash(k);
int i = indexFor(hash, table.length);
for (Entry<K,V> e = table[i]; e != null; e = e.next) {
if (e.hash == hash && eq(k, e.key)) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}
modCount++;
addEntry(hash, k, value, i);
return null;
}
Run Code Online (Sandbox Code Playgroud)
但是,在JDK 1.6或更高版本中不使用此类Object(NULL_KEY).
取而代之的是,两个新的方法命名getForNullKey()和putForNullKey(value)添加,这是在应用get和put方法为好.
请参阅以下源代码:
public V get(Object key) {
if (key == null)
return getForNullKey();
Entry<K,V> entry = getEntry(key);
return null == entry ? null : entry.getValue();
}
private V getForNullKey() {
for (Entry<K,V> e = table[0]; e != null; e = e.next) {
if (e.key == null)
return e.value;
}
return null;
}
public V put(K key, V value) {
if (key == null)
return putForNullKey(value);
int hash = hash(key);
int i = indexFor(hash, table.length);
for (Entry<K,V> 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;
e.recordAccess(this);
return oldValue;
}
}
modCount++;
addEntry(hash, key, value, i);
return null;
}
/**
* Offloaded version of put for null keys
*/
private V putForNullKey(V value) {
for (Entry<K,V> e = table[0]; e != null; e = e.next) {
if (e.key == null) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}
modCount++;
addEntry(0, null, value, 0);
return null;
}
Run Code Online (Sandbox Code Playgroud)
变化总是有变化的原因,如improving the performance等.请帮我解决以下2个问题
Q#1 ==> 为什么要进行此更改,是否存在在JDK 1.5中实现HashMap的null键的问题?
Q#2 ==> 在JDK 1.6或更高版本中,HashMap的null键机制改变有什么优势?
用于查找空键的 get() 卸载版本。空键映射到索引 0。为了提高两个最常用操作(get 和 put)的性能,这种空情况被分成单独的方法,但在其他操作中与条件合并在一起。
| 归档时间: |
|
| 查看次数: |
364 次 |
| 最近记录: |