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 большую часть времени, потому что он имеет лучшую производительность в целом):

  1. Предсказуемый порядок итераций LinkedHashSet (Oracle)
  2. LinkedHashSet дороже для вставок, чем HashSet;
  3. В целом немного лучшая производительность, чем 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:

  1. Подчеркнутая структура данных - Hashtable.
  2. Порядок вставки не сохраняется.
  3. представил версию 1.2.

LinkedHashSet:

  1. Подчеркнутая структура данных представляет собой комбинацию LinkedList и Hashtable.
  2. Порядок вставки сохраняется.
  3. Выпущено в версии 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 просто:)

Другие вопросы по тегам