1. Hashtable — это подкласс Dictionary.
Скопируйте код кода следующим образом:
общедоступный класс Hashtable<K,V>
расширяет словарь<K,V>
реализует Map<K,V>, Cloneable, java.io.Serializable
ХэшМап:
Скопируйте код кода следующим образом:
общедоступный класс HashMap<K,V>
расширяет AbstractMap<K,V>
реализует Map<K,V>, Cloneable, Serializable
HashMap и Hashtable являются классами реализации интерфейса Map;
2. Методы в Hashtable являются синхронными(), но методы в HashMap по умолчанию не синхронны. То есть в многопоточных приложениях Hashtable можно безопасно использовать без специальных операций, для HashMap требуется дополнительный механизм синхронизации; Но проблему синхронизации HashMap можно решить с помощью статического метода Collections:
Скопируйте код кода следующим образом:
общедоступная статическая <K,V> Map<K,V> синхронизированная карта (Map<K,V> m)
Этот метод возвращает синхронизированную карту, что означает, что возвращаемая карта является потокобезопасной. Следует отметить, что при переборе возвращаемой карты необходимо вручную синхронизироваться по возвращаемой карте, иначе это приведет к неопределенному поведению:
Скопируйте код кода следующим образом:
Карта m = Collections.synchronizedMap(new HashMap());
...
Set s = m.keySet(); // Не обязательно в синхронизированном блоке
...
synced(m) { // Синхронизация по m, а не по s!
Iterator i = s.iterator(); // Должен быть в синхронизированном блоке
пока (i.hasNext())
Фу(я.следующий());
}
3. В HashMap в качестве ключа может использоваться значение null, и такой ключ может быть только один; может быть один или несколько ключей, соответствующее значение которого равно нулю; Когда метод get() возвращает нулевое значение, это может означать, что ключ не существует в HashMap, или это также может означать, что значение, соответствующее ключу, равно нулю. Поэтому в HashMap метод get() нельзя использовать для определения наличия определенного ключа в HashMap, но для определения следует использовать метод containsKey(). Ключевое значение Hashtable не может быть нулевым, иначе: java.lang.NullPointerException.
4.HashTable использует перечисление, а HashMap использует итератор.
Вышеупомянутое — лишь поверхностные различия, и их реализации также сильно различаются.
5. Размер хеш-массива в HashTable по умолчанию равен 11, а метод увеличения — old*2+1. Размер хеш-массива в HashMap по умолчанию равен 16, и он должен быть экспонентой 2.
6. Использование хеш-значений отличается. HashTable напрямую использует хеш-код объекта. Код выглядит следующим образом:
Скопируйте код кода следующим образом:
int hash = key.hashCode();
int index = (хеш & 0x7FFFFFFFF) % tab.length;
HashMap пересчитывает хэш-значение и использует AND вместо модуля, например метод put HashMap:
Скопируйте код кода следующим образом:
public V put (ключ K, значение V) {
если (ключ == ноль)
вернуть putForNullKey (значение);
int hash = hash(key.hashCode());
int я = indexFor(хеш, table.length);
for (Entry<K,V> e = table[i]; e != null; e = e.next) {
Объект К;
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
V oldValue = e.value;
е.значение = значение;
e.recordAccess(это);
вернуть старое значение;
}
}
модКаунт++;
addEntry (хеш, ключ, значение, я);
вернуть ноль;
}
Скопируйте код кода следующим образом:
статический int hash(int h) {
// Эта функция гарантирует, что хэш-коды, отличающиеся только
// постоянные кратные в каждой позиции бита имеют ограниченное
// количество коллизий (примерно 8 при коэффициенте загрузки по умолчанию).
ч ^= (ч >>> 20) ^ (ч >>> 12);
вернуть h ^ (h >>> 7) ^ (h >>> 4);
}
Скопируйте код кода следующим образом:
static int indexFor(int h, int length) {
вернуть h & (длина-1);
}