HashSet против LinkedHashSet
В чем разница между ними? я знаю это
LinkedHashSet - это упорядоченная версия HashSet, которая поддерживает двусвязный список для всех элементов. Используйте этот класс вместо HashSet, если вам важен порядок итераций. Когда вы перебираете HashSet, порядок непредсказуем, а LinkedHashSet позволяет перебирать элементы в том порядке, в котором они были вставлены.
Но в исходном коде LinkedHashSet есть только вызывающие конструкторы HashSet. Итак, где же двойной список и порядок вставки?
10 ответов
Ответ заключается в том, какие конструкторы LinkedHashSet
использует для создания базового класса:
public LinkedHashSet(int initialCapacity, float loadFactor) {
super(initialCapacity, loadFactor, true); // <-- boolean dummy argument
}
...
public LinkedHashSet(int initialCapacity) {
super(initialCapacity, .75f, true); // <-- boolean dummy argument
}
...
public LinkedHashSet() {
super(16, .75f, true); // <-- boolean dummy argument
}
...
public LinkedHashSet(Collection<? extends E> c) {
super(Math.max(2*c.size(), 11), .75f, true); // <-- boolean dummy argument
addAll(c);
}
И (один из примеров) HashSet
описан конструктор, который принимает логический аргумент и выглядит так:
/**
* Constructs a new, empty linked hash set. (This package private
* constructor is only used by LinkedHashSet.) The backing
* HashMap instance is a LinkedHashMap with the specified initial
* capacity and the specified load factor.
*
* @param initialCapacity the initial capacity of the hash map
* @param loadFactor the load factor of the hash map
* @param dummy ignored (distinguishes this
* constructor from other int, float constructor.)
* @throws IllegalArgumentException if the initial capacity is less
* than zero, or if the load factor is nonpositive
*/
HashSet(int initialCapacity, float loadFactor, boolean dummy) {
map = new LinkedHashMap<E,Object>(initialCapacity, loadFactor);
}
HashSet является неупорядоченным и несортированным множеством. LinkedHashSet - это упорядоченная версия HashSet. Единственное отличие между HashSet и LinkedHashSet состоит в том, что LinkedHashSet поддерживает порядок вставки. Когда мы перебираем HashSet, порядок непредсказуем, в то время как он предсказуем в случае LinkedHashSet. Причина, по которой LinkedHashSet поддерживает порядок вставки, заключается в том, что базовая структура данных представляет собой двусвязный список.
LinkedHashSet
Конструкторы вызывают следующий конструктор базового класса:
HashSet(int initialCapacity, float loadFactor, boolean dummy) {
map = new LinkedHashMap<E, Object>(initialCapacity, loadFactor);
}
Как видите, внутренняя карта LinkedHashMap
, Если вы посмотрите внутрь LinkedHashMap
вы обнаружите следующее поле:
private transient Entry<K, V> header;
Это связанный список в вопросе.
Я предлагаю вам использовать LinkedHashSet
большую часть времени, потому что он имеет лучшую производительность в целом):
- Предсказуемый порядок итераций LinkedHashSet (Oracle)
- LinkedHashSet дороже для вставок, чем HashSet;
- В целом немного лучшая производительность, чем
HashMap
, потому что большую часть времени мы используем структуры Set для итерации.
Тесты производительности:
------------- TreeSet -------------
size add contains iterate
10 746 173 89
100 501 264 68
1000 714 410 69
10000 1975 552 69
------------- HashSet -------------
size add contains iterate
10 308 91 94
100 178 75 73
1000 216 110 72
10000 711 215 100
---------- LinkedHashSet ----------
size add contains iterate
10 350 65 83
100 270 74 55
1000 303 111 54
10000 1615 256 58
Вы можете увидеть исходную тестовую страницу здесь: Финальный пример тестирования производительности
Вы должны посмотреть на источник HashSet
конструктор это вызывает... это специальный конструктор, который делает поддержку Map
LinkedHashMap
вместо просто HashMap
,
HashSet
не поддерживать порядок вставки элементаLinkedHashSet
поддерживать порядок вставки элемента
пример
Set<String> set = ...;// using new HashSet<>() OR new LinkedHashSet<>()
set.add("2");
set.add("1");
set.add("ab");
for(String value : set){
System.out.println(value);
}
HashSet
выход
1
ab
2
LinkedHashSet
выход
2
1
ab
HashSet:
Подчеркнутая структура данных - Hashtable. Дублирование объектов не допускается. Порядок вставки не сохраняется и основан на хэш-коде объектов. Нулевая вставка возможна (только один раз). Он реализует Сериализуемый, Клонируемый, но не интерфейс RandomAccess. HashSet лучше всего выбирать, если частой операцией является операция поиска.
В HashSet дубликаты запрещены. Если пользователи пытаются вставить дубликаты, когда мы не получим никаких исключений при компиляции или во время выполнения. Метод add возвращает просто false.
Конструкторы:
HashSet h = новый HashSet(); создает пустой объект HashSet с начальной емкостью по умолчанию 16 и коэффициентом заполнения по умолчанию (коэффициент загрузки), равным 0,75.
HashSet h = новый HashSet(int initialCapacity); создает пустой объект HashSet с указанным initialCapacity и коэффициент заполнения по умолчанию составляет 0,75.
HashSet h = новый HashSet (int initialCapacity, float fillRatio);
HashSet h = новый HashSet (коллекция c); создает эквивалентный объект HashSet для данной коллекции. Этот конструктор предназначен для взаимного преобразования между объектами коллекции.
LinkedHashSet:
Это дочерний класс HashSet. он точно такой же, как и HashSet (конструкторы и методы), за исключением следующих различий.
Отличия HashSet:
- Подчеркнутая структура данных - Hashtable.
- Порядок вставки не сохраняется.
- представил версию 1.2.
LinkedHashSet:
- Подчеркнутая структура данных представляет собой комбинацию LinkedList и Hashtable.
- Порядок вставки сохраняется.
- Выпущено в версии 1.4.
HashSet: неупорядоченный на самом деле. если вы передаете параметр означает
Set<Integer> set=new HashSet<Integer>();
for(int i=0;i<set.length;i++)
{
SOP(set)`enter code here`
}
Out Put: может быть 2,1,3
не предсказуемо. в следующий раз другой заказ.
LinkedHashSet()
которые производят заказ FIFO.
Если вы посмотрите на конструкторы, вызванные из LinkedHashSet
класс вы увидите, что внутри это LinkedHashMap
это используется для целей поддержки.
Все методы и конструкторы одинаковы, но есть только одно отличие: LinkedHashset будет поддерживать порядок вставки, но не будет разрешать дублирование.
Hashset не будет поддерживать порядок вставки. Это сочетание List и Set просто:)