HashSet vs LinkedHashSet


153

Qual'è la differenza tra loro? lo so

Un LinkedHashSet è una versione ordinata di HashSet che mantiene un elenco doppiamente collegato tra tutti gli elementi. Usa questa classe invece di HashSet quando ti preoccupi dell'ordine di iterazione. Quando si scorre attraverso un HashSet l'ordine è imprevedibile, mentre un LinkedHashSet consente di scorrere gli elementi nell'ordine in cui sono stati inseriti.

Ma nel codice sorgente di LinkedHashSet ci sono solo costruttori di chiamata di HashSet. Quindi, dove si trova l'elenco doppio e l'ordine di inserzione?


2
usa l'opzione Intellij (Ctrl + B) per rintracciare la risposta. :)
Delta,

ovviamente è necessario il codice sorgente allegato. :)
Delta,

Risposte:


65

Le bugie di risposta in cui costruttori d' le LinkedHashSetusi per costruire la classe di base:

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);
}

E (un esempio di) un HashSetcostruttore che accetta un argomento booleano è descritto e si presenta così:

/**
 * 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);
}

2
Una classe genitore con funzionalità esplicite per una classe figlio, un argomento ignorato per distinguere
Traubenfuchs

5
Non esattamente un design pulito che utilizza un parametro fittizio per chiarire le ambiguità del costruttore.
Eric J.,

8
È un design ragionevolmente pulito, perché l'API è pulita (questo costruttore HashSet è un pacchetto privato). I dettagli di implementazione non contano per gli utenti della classe. Mantenere questo codice potrebbe essere più difficile, ma nel caso delle classi java.util, anche piccoli miglioramenti delle prestazioni possono giustificarlo.
lbalazscs,

25

LinkedHashSetI costruttori invocano il seguente costruttore della classe base:

HashSet(int initialCapacity, float loadFactor, boolean dummy) {
  map = new LinkedHashMap<E, Object>(initialCapacity, loadFactor);
}

Come puoi vedere, la mappa interna è a LinkedHashMap. Se guardi dentro LinkedHashMap, scoprirai il seguente campo:

private transient Entry<K, V> header;

Questa è la lista collegata in questione.


24

HashSet è un Set non ordinato e non ordinato .
LinkedHashSet è la versione ordinata di HashSet.

L'unica differenza tra HashSet e LinkedHashSet è che:
LinkedHashSet mantiene l'ordine di inserimento.

Quando eseguiamo l'iterazione attraverso un HashSet , l'ordine è imprevedibile mentre è prevedibile in caso di LinkedHashSet .

Il motivo per cui LinkedHashSet mantiene l'ordine di inserimento è che:
La struttura di dati utilizzata sottostante è Doubly-Linked-List .


9

Dovresti guardare la fonte del HashSetcostruttore che chiama ... è un costruttore speciale che rende il supporto Mapun LinkedHashMapanziché un solo HashMap.


Grazie, in HashSet esiste un costruttore per la creazione di LinkedHashMap, che viene chiamato in LinkedHashSet e tutta la logica è in LinkedHashMap
Shikarn-O

5

Ti suggerisco di usare la LinkedHashSetmaggior parte delle volte, perché ha prestazioni complessivamente migliori ):

  1. Ordine di iterazione prevedibile LinkedHashSet (Oracle)
  2. LinkedHashSet è più costoso per inserimenti di HashSet;
  3. In generale prestazioni leggermente migliori rispetto a HashMap, perché il più delle volte usiamo le strutture Set per iterare.

Test delle prestazioni:

------------- 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

È possibile visualizzare la pagina di test di origine qui: L'esempio di test delle prestazioni finali


2
Non vedo alcun riscaldamento della JVM prima di quei "benchmark", quindi non prenderei sul serio nessuno di questi dati. Per saperne di più
Felix S

3

HashSet: effettivamente non ordinato. se si passa il parametro significa

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

Out Put: potrebbe 2,1,3non essere prevedibile. la prossima volta un altro ordine.

LinkedHashSet() che producono l'ordine FIFO.


3

HashSet non mantenere l'ordine degli articoli inseriti
LinkedHashSet mantenere l'ordine degli articoli inseriti

Esempio

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 produzione

1
ab
2

LinkedHashSet produzione

2
1
ab

2

HashSet:

La struttura dei dati sottolineata è Hashtable. Non sono consentiti oggetti duplicati. L'ordine di inserimento non viene conservato e si basa sul codice hash degli oggetti. L'inserimento nullo è possibile (solo una volta). Implementa l'interfaccia Serializable, Clonable ma non RandomAccess. È meglio scegliere HashSet se l'operazione frequente è un'operazione di ricerca.

In HashSet non sono consentiti duplicati. Se gli utenti stanno cercando di inserire duplicati quando non avremo eccezioni di compilazione o di runtime. il metodo add restituisce semplicemente false.

Costruttori:

HashSet h = new HashSet (); crea un oggetto HashSet vuoto con capacità iniziale predefinita 16 e il rapporto di riempimento predefinito (fattore di carico) è 0,75.

HashSet h = new HashSet (int initialCapacity); crea un oggetto HashSet vuoto con initialCapacity specificato e la razione di riempimento predefinita è 0,75.

HashSet h = new HashSet (int initialCapacity, float fillRatio);

HashSet h = new HashSet (Collection c); crea un oggetto HashSet equivalente per la raccolta specificata. Questo costruttore intendeva la conversione tra oggetti di raccolta.

LinkedHashSet:

È una classe figlio di HashSet. è esattamente lo stesso di HashSet incluso (Costruttori e Metodi) tranne le seguenti differenze.

Differenze HashSet:

  1. La struttura dei dati sottolineata è Hashtable.
  2. L'ordine di inserimento non viene conservato.
  3. introdotta la versione 1.2.

LinkedHashSet:

  1. La struttura dei dati sottolineata è una combinazione di LinkedList e Hashtable.
  2. L'ordine di inserimento viene conservato.
  3. Indicato nella versione 1.4.

1

Se dai un'occhiata ai costruttori chiamati dalla LinkedHashSetclasse vedrai che internamente è un oggetto LinkedHashMapusato come supporto.


0

Tutti i metodi e i costruttori sono uguali, ma solo una differenza è che LinkedHashset manterrà l'ordine di inserimento ma non consentirà duplicati.

Hashset non manterrà alcun ordine di inserzione. È una combinazione di Elenco e Imposta semplice :)

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.