Для поиска 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);
}

и (один пример) a 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(int initialCapacity, float loadFactor, boolean dummy) {
  map = new LinkedHashMap<E, Object>(initialCapacity, loadFactor);
}

как вы можете видеть, внутренняя карта является LinkedHashMap. Если вы посмотрите внутрь LinkedHashMap, вы обнаружите следующее поле:

private transient Entry<K, V> header;

Это связанный список в вопрос.


вы должны посмотреть на источник HashSet конструктор его звонки... это специальный конструктор, который делает бэк Map a LinkedHashMap вместо HashMap.


хеш-набор является неупорядоченным и несортированным набором. LinkedHashSet-это упорядоченная версия HashSet.Единственное различие между HashSet и LinkedHashSet заключается в том, что LinkedHashSet поддерживает порядок вставки. Когда мы перебираем хэш-набор, порядок непредсказуем, в то время как он предсказуем в случае LinkedHashSet. Причина, по которой LinkedHashSet поддерживает порядок вставки, заключается в том, что базовая структура данных является двусвязным списком.


Я предлагаю вам использовать LinkedHashSet большую часть времени, потому что он имеет лучшая производительность в целом):

  1. предсказуемым шаг ордер LinkedHashSet (Oracle)
  2. LinkedHashSet дороже для вставок, чем HashSet;
  3. в целом немного лучше производительность, чем HashMap, потому что большую часть времени мы используем набор конструкций для итерация.

тесты производительности:

------------- 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: Вообще-то неупорядоченный. если U передача параметра означает

Set<Integer> set=new HashSet<Integer>();
for(int i=0;i<set.length;i++)
{
  SOP(set)`enter code here`
}

Из Поставить: Может быть 2,1,3 не предсказуем. в следующий раз другой заказ.

LinkedHashSet() которые производят заказ FIFO.


Если вы посмотрите на конструкторы, вызванные из


поиска HashSet:

подчеркнутая структура данных-Hashtable. Дублирование объектов не допускается.порядок вставки не сохраняется и основан на хэш-коде объектов. Возможна вставка Null(только один раз). Он реализует сериализуемый, Clonable, но не RandomAccess интерфейс. HashSet лучше всего выбрать, если частой операцией является операция поиска.

в HashSet дубликаты не допускаются.если пользователи пытаются вставить дубликаты, когда мы не будем получите любые исключения компиляции или выполнения. метод add возвращает просто false.

конструкторы:

HashSet h=new HashSet (); создает пустой объект HashSet с начальной емкостью по умолчанию 16 и коэффициентом заполнения по умолчанию(коэффициент загрузки) 0,75 .

HashSet h=new HashSet (int initialCapacity); создает пустой объект HashSet с заданной initialCapacity, а коэффициент заполнения по умолчанию равен 0.75.

HashSet h=новый HashSet (int initialCapacity, float fillRatio);

HashSet h=new HashSet (коллекция c); создает эквивалентный объект HashSet для данной коллекции. Этот конструктор предназначен для преобразования inter между объектами коллекции.

LinkedHashSet:

это дочерний класс HashSet. он точно такой же, как и HashSet, включая(конструкторы и методы), за исключением следующих различия.

различия Для поиска HashSet:

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

LinkedHashSet:

  1. подчеркнутая структура данных представляет собой комбинацию LinkedList и Hashtable.
  2. порядок вставки сохраняется.
  3. Indroduced в версии 1.4.

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

все методы и конструкторы одинаковы, но только одно отличие LinkedHashset будет поддерживать порядок вставки, но не позволит дублировать.

Hashset не будет поддерживать порядок вставки. Это комбинация списка и набора simple:)