Подтвердить что ты не робот

Почему initialCapacity Hashtable равно 11, а DEFAULT_INITIAL_CAPACITY в HashMap - 16 и требует мощности 2

Сравнение исходного кода HashMap и Hashtable в jdk 1.6, я видел ниже коды внутри HashMap

/**
 * The default initial capacity - MUST be a power of two.
 */
static final int DEFAULT_INITIAL_CAPACITY = 16;

    int capacity = 1;
    while (capacity < initialCapacity)
        capacity <<= 1;

однако, в Hashtable, я видел ниже коды?

table = new Entry[initialCapacity];

public Hashtable() {
    this(11, 0.75f);
}

поэтому мой вопрос: почему hashMap требует мощности 2 в качестве начальной емкости? и в то время как хэш-таблица выбирает 11 как начальную емкость по умолчанию? Я предполагаю, что это не имеет ничего общего с тем, что хеш-таблица является потокобезопасной и не допускает нулевой ключ или значения.

ТНХ.

4b9b3361

Ответ 1

В следующей статье мы подробно рассмотрим этот вопрос: HashMap требует лучшего hashCode() - JDK 1.4 Part II.

В соответствии с этой статьей основной причиной перехода к силе двух размеров было то, что бит-маскирование быстрее, чем целочисленное деление. Это не лишено негативных последствий, которые объясняются одним из авторов:

Джошуа Блох: Недостатком использования силы-двух является то, что результирующая хеш-таблица очень чувствительный к качеству хэш-функции (hashCode). Крайне важно, чтобы любое изменение входа должно влиять на младшие биты хеш-значения. (В идеале, он должен влиять на все биты хеш-значения с равным вероятностью.) Поскольку мы не имеем уверенности, что это правда, мы добавляем вторичную (или "защитную" ) хеш-функцию, когда мы переключаемся на power-of-two хеш-таблица. Эта хеш-функция применяется к результатам hashCode перед маскировкой бит младшего порядка. Его задача состоит в том, чтобы разбросать информацию по всем битам и, в частности, в биты младшего порядка. Конечно, он должен работать очень быстро, или вы теряете преимущество перехода на таблицу с двумя размерами. Исходная вторичная хеш-функция в 1.4 оказалась недостаточной. Мы знали, что это теоретическая возможность, но мы думали, что это не повлияло на какие-либо практические наборы данных. Мы были неправы. Вторичная вторичная хэш-функция (которую я разработал с помощью компьютера) имеет сильные статистические свойства, которые в значительной степени гарантируют хорошее распределение ковша.

Ответ 2

Hashtable использует размеры таблицы псевдопростых чисел и увеличивает размер таблицы относительно медленнее. HashMap использует мощность 2 в качестве бит и быстрее, чем использование модуля.

По иронии судьбы, модуль мощности 2 означает, что хороший хэш-код() необходим, поскольку верхние биты будут проигнорированы, поэтому у HashMap есть способ переупорядочить хэш-код, который вы получите, чтобы избежать этой проблемы, что означает, что на самом деле может быть медленнее.: Z

Ответ 3

Это может помочь:

http://www.concentric.net/~Ttwang/tech/primehash.htm

В основном, если я правильно помню, когда у вас есть хеш-таблица с размером, равным 2, легко получить хеш-функцию на основе менее значимых бит ключа.

Используя простое число (как в 11) в качестве размера таблицы, вероятность столкновения на строках таблицы менее вероятна, поэтому вставка "дешевле".

Ответ 4

Требование о том, чтобы размер таблицы был равен двум, представляет собой деталь реализации, не известную пользователям класса, поэтому c'tor автоматически корректирует значение следующей большей мощности двух вместо пометить ошибку.

В реализации Hashtable предполагается, что хэш не может быть равномерно распределен, поэтому он пытается использовать несколько ящиков, которые являются первичными в надежде избежать пиков в распределении частот хеша.

Комбинация этих двух деталей реализации приводит к плохой производительности.

(например, примитивная хэш-функция будет

int hash(String s, int nBins) {
    return s[0] % nBins;
}

Если nBins равно 32, e и e заканчиваются в одном и том же ящике, поэтому распределение хеш-значений коррелирует с распределением появления букв с четкими пиками - поэтому распределение частот будет иметь пик при 32.)