在 Java 7 中 HashMap
实现,在 resize
方法,它调用 transfer
将旧元素移动到新表。为什么他们写了一个新方法而不是调用 put
所有旧元素?由于 threshold,不会再次触发调整大小.调用 put
使代码更清晰。
/**
* 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<K,V> e = src[j];
if (e != null) {
src[j] = null;
do {
Entry<K,V> next = e.next;
int i = indexFor(e.hash, newCapacity);
e.next = newTable[i];
newTable[i] = e;
e = next;
} while (e != null);
}
}
}
最佳答案
一个重要的区别是 transfer
可以利用 Entry
的事实每个条目的对象已经以两种方式存在:
Entry
对象本身以避免分配新对象(从而避免内存分配,从而减少 GC 压力)。 hash
存储在 Entry
中的值对象从而避免必须调用 Object.hashValue
在 map 中已经存在的每个键上(理论上这可能是一项昂贵的操作)。 基本上:如果
resize
只是在 put
方面实现的它必须重新做很多很容易避免的工作。JDK 的更高版本明显更加复杂
HashMap
更复杂的实现 transfer
方法(或等价物)被实现。还值得指出的是,在 JDK 本身中完成时,即使以不那么“简单”的代码为代价的微小性能提升通常也是值得的:因为
HashMap
基本上每个 Java 程序都使用它,让它尽可能地提高性能,但以稍微降低可读性为代价通常是值得的权衡。同样的道理也适用于 不是 同样适用于我们“凡人”编写的大多数其他软件。
关于java - 为什么 Java HashMap 实现在调整大小时使用 transfer() 而不是 put()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68010999/