直接来自这 javadoc:
HashMap的实例有两个影响其性能的参数:初始容量和负载因子。容量是哈希表中的桶数,初始容量只是哈希表创建时的容量。负载因子是衡量允许哈希表在其容量自动增加之前得到多满的度量。当哈希表中的条目数超过负载因子和当前容量的乘积时,重新哈希表(即重新构建内部数据结构),使哈希表具有大约两倍的桶数。
假设哈希表中的条目数超过了负载因子和当前容量的乘积.数据结构被重新哈希,桶的数量大约是两倍..。好的..。如果hashcode()方法保持不变..。如何增加桶的数量可以减少查找等待时间?如果哈希代码是相同的,那么查找将在同一个桶中完成,即使在它旁边新建了另一个空桶。难到不是么?(当然不是它,但为什么?)提前谢谢。
发布于 2013-06-30 08:27:33
虽然hashCode()返回值将保持不变,但这些值并不直接用于查找桶。它们被转换成索引到桶数组中,通常是通过index = hashCode() % tableSize。考虑一个大小为10的表,其中两个键的哈希值分别为5和15,而在表大小为10时,它们在同一个桶中结束。将表的大小调整为20,最后它们会在不同的桶中结束。
发布于 2013-06-30 08:25:21
这是一个简化的版本,但假设您找到的桶有:
int bucket = hash % 8; //8 buckets重新散列后,它将变成:
int bucket = hash % 16;//16 buckets如果您的初始哈希是15,那么在重新散列之前它是在第7桶中,但是在重新散列之后是在第15桶中。
发布于 2013-06-30 08:41:07
这个问题已经得到正确的回答。为了更深入地理解,下面是来自java.util.HashMap的相关代码部分。
public class HashMap<K,V> extends AbstractMap<K,V>
implements Map<K,V>, Cloneable, Serializable
{
static class Entry<K,V> implements Map.Entry<K,V> {
final K key;
V value;
Entry<K,V> next;
int hash;
/**
* Creates new entry.
*/
Entry(int h, K k, V v, Entry<K,V> n) {
value = v;
next = n;
key = k;
hash = h;
}
... methods...
}
/**
* The table, resized as necessary. Length MUST Always be a power of two.
*/
transient Entry<K,V>[] table;
/**
* Returns index for hash code h.
*/
static int indexFor(int h, int length) {
return h & (length-1);
}
/**
* Adds a new entry with the specified key, value and hash code to
* the specified bucket. It is the responsibility of this
* method to resize the table if appropriate.
*/
void addEntry(int hash, K key, V value, int bucketIndex) {
if ((size >= threshold) && (null != table[bucketIndex])) {
resize(2 * table.length);
hash = (null != key) ? hash(key) : 0;
bucketIndex = indexFor(hash, table.length);
}
createEntry(hash, key, value, bucketIndex);
}
/**
* Like addEntry except that this version is used when creating entries
* as part of Map construction or "pseudo-construction" (cloning,
* deserialization). This version needn't worry about resizing the table.
*/
void createEntry(int hash, K key, V value, int bucketIndex) {
Entry<K,V> e = table[bucketIndex];
// *** you see how the next line builds a linked list of entries with the same hash code ***
table[bucketIndex] = new Entry<>(hash, key, value, e);
size++;
}
/**
* Associates the specified value with the specified key in this map.
* If the map previously contained a mapping for the key, the old
* value is replaced.
*/
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;
}
}https://stackoverflow.com/questions/17388506
复制相似问题