web-dev-qa-db-fra.com

HashSet vs LinkedHashSet

Quelle est la différence entre eux? je le sais 

Un LinkedHashSet est une version ordonnée de HashSet qui maintient une liste doublement chaînée entre tous les éléments. Utilisez cette classe au lieu de HashSet quand vous vous souciez de l'ordre des itérations. Lorsque vous parcourez un hachage, le L'ordre est imprévisible, alors qu'un LinkedHashSet vous permet de parcourir les éléments dans l'ordre dans lequel ils ont été insérés. 

Mais dans le code source de LinkedHashSet, il n’existe que des constructeurs appelants de HashSet. Alors, où se trouvent la liste à double liaison et l'ordre d'insertion?

134
Shikarn-O

La réponse réside dans quels constructeurs la LinkedHashSet utilise pour construire la classe de 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);
}

Et (un exemple de) un constructeur HashSet qui prend un argument booléen est décrit, et ressemble à ceci:

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

Les constructeurs LinkedHashSet invoquent le constructeur de classe de base suivant:

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

Comme vous pouvez le constater, la carte interne est une LinkedHashMap. Si vous regardez à l'intérieur de LinkedHashMap, vous découvrirez le champ suivant:

private transient Entry<K, V> header;

Ceci est la liste liée en question.

23
NPE

Vous devriez regarder la source du constructeur HashSet qu’elle appelle ... c’est un constructeur spécial qui fait du Map de sauvegarde une LinkedHashMap au lieu de juste une HashMap.

9
ColinD

Un hachage est non ordonné et non trié. LinkedHashSet est la version commandée de HashSet. La seule différence entre HashSet et LinkedHashSet est que LinkedHashSet conserve l'ordre d'insertion. Lorsque nous parcourons un hachage, l'ordre est imprévisible alors qu'il est prévisible dans le cas de LinkedHashSet ..__ La raison pour laquelle LinkedHashSet conserve l'ordre d'insertion est que la structure de données sous-jacente est une liste à double liaison.

8
Hema Ganapathy

Je vous suggère d'utiliser LinkedHashSet la plupart du temps, car il présente meilleure performance globale):

  1. Prévisible _ {itération commande LinkedHashSet (Oracle)
  2. LinkedHashSet est plus cher pour les insertions que HashSet;
  3. En général, les performances sont légèrement meilleures que HashMap _, car la plupart du temps, nous utilisons des structures Set pour les itérer.

Des tests de performance:

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

Vous pouvez voir la page de test source ici: The Final Performance Testing Example

5
Dmytro Melnychuk

HashSet: En fait non ordonné. Si vous passez le paramètre

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

Out Put: Peut-être 2,1,3 non prévisible. la prochaine fois une autre commande.

LinkedHashSet() qui produit l'ordre FIFO.

3
Justin

HashSet:

La structure de données soulignée est Hashtable . Les objets en double ne sont pas autorisés. L'ordre d'insertion n'est pas conservé et il est basé sur le code de hachage des objets . Une insertion nulle est possible (une seule fois) . Elle implémente Serializable, Clonable mais pas l'interface RandomAccess . HashSet est préférable si l'opération fréquente est une opération de recherche.

Dans HashSet, les doublons ne sont pas autorisés.Si les utilisateurs tentent d'insérer des doublons sans aucune exception de compilation ou d'exécution. La méthode add renvoie simplement false.

Constructeurs:

HashSet h = new HashSet (); crée un objet HashSet vide avec une capacité initiale par défaut de 16 et un taux de remplissage par défaut (facteur de charge) de 0,75.

HashSet h = new HashSet (int initialCapacity); crée un objet HashSet vide avec initialCapacity spécifié et le taux de remplissage par défaut est de 0,75.

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

HashSet h = nouveau HashSet (Collection c); crée un objet HashSet équivalent pour la collection donnée. Ce constructeur était destiné à la conversion entre objets de collection.

LinkedHashSet:

C'est une classe enfant de HashSet. c'est exactement la même chose que HashSet incluant (Constructeurs et Méthodes) à l'exception des différences suivantes.

Différences HashSet:

  1. La structure de données soulignée est Hashtable.
  2. L'ordre d'insertion n'est pas préservé.
  3. introduit la version 1.2.

LinkedHashSet:

  1. La structure de données soulignée est une combinaison de LinkedList et Hashtable.
  2. L'ordre d'insertion est préservé.
  3. Produit en version 1.4.
2
Umapathi

HashSet ne conserve pas l'ordre des éléments d'insertion
LinkedHashSet maintenir l'ordre de l'élément d'insertion

Exemple

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 sortie

1
ab
2

LinkedHashSet sortie

2
1
ab
2
Linh

Si vous examinez les constructeurs appelés à partir de la classe LinkedHashSet, vous verrez qu'en interne, c'est une LinkedHashMap utilisée à des fins de sauvegarde.

1
reef

Toutes les méthodes et tous les constructeurs sont identiques, mais une seule différence est que LinkedHashset conservera l'ordre d'insertion mais n'autorisera pas les doublons.

Hashset ne conservera aucun ordre d'insertion . C'est une combinaison de List et Set simple :)

0
Anand Mohan