Quel algorithme est utilisé pour convertir un ArrayList <T> à un LinkedHashSet <T> dans la version JRE

Amit Upadhyay:

Je voulais obtenir un listdes éléments uniques d'un listavec des éléments en double et l'ordre des éléments apparaissant dans la liste devrait être maintenue.

Pour ce faire, je aurais pu écrire un algorithme comme:

private ArrayList<T> getUnique(ArrayList<T> list)
{
    // maintain a hashmap of numbers and a uniqueList to be returned(ArrayList<T>)
    // Add element in result list and the hashmap if the element isn't already present in the hashmap, else just add in the hashmap

    HashMap<T, Boolean> map = new HashMap<>();
    ArrayList<T> uniqueList = new ArrayList<>();

    for (T t: list)
    {
        if (map.get(t) == null)
        {
            // t wasn't present so, adding them in map as well as in the list
            map.put(t, true);
            uniqueList.add(t);
        }
    }
    return uniqueList;
}

Cet algorithme prendra du O(n)temps avec un O(n)espace supplémentaire (pour HashMap).

Ou tout simplement, je aurais pu utiliser la syntaxe ci-dessous:

Set<T> set = new LinkedHashSet<>(list);

La syntaxe ci - dessus en Java est utilisé pour obtenir un setdes éléments uniques de listl'ordre d'apparition des mêmes éléments que celui de list. Ensuite convertir cet ensemble dans une liste. ( ArrayList<T> uniqueList = new ArrayList<>(set);)

Je suppose la complexité de temps est également ici O(n). Je voulais savoir quel algorithme Java utilise pour cela.

Je vois la classe est nommé LinkedHashSet, donc je pensais qu'ils pourraient utiliser certains LinkedListconcepts pour y parvenir, je regardais dans le code source, et a trouvé ces trucs:

  1. Dans LinkedHashSet.java, le constructeur ressemble à :

143: public LinkedHashSet(Collection<? extends T> c) 144: { 145: super(c); 146: } ici est la source.

  1. Alors, je regardais le constructeur de la classe parent -à- dire HashSet, j'ai trouvé:

public HashSet(Collection<? extends E> c) { map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16)); addAll(c); }

  1. Ensuite, je cherchais la addAllméthode, je l' ai trouvé dans la AbstractCollectionclasse (qui est le grand - parent de HashSetclasse), la définition de la fonction est:

public boolean addAll(Collection<? extends E> c) { boolean modified = false; for (E e : c) if (add(e)) modified = true; return modified; }

C'est l' appel addqui ressemble à :

public boolean add(E e) { throw new UnsupportedOperationException(); } ici .

Je ne pouvais pas comprendre cela. Quel algorithme utilisent-ils pour cette tâche?

Smbchde:

Pour quelqu'un qui cherche l'histoire

Base sur le code source de LinkedHashSet , HashSet , LinkedHashMap . Lors de la construction d' un LinkedHashSetqui se prolonge HashSetavec un autre collection (ligne LinkedHashSet.java 143),

public LinkedHashSet(Collection<? extends T> c)  
{  
  super(c);  
}

Qui appellera (ligne HashSet.java 136):

public HashSet(Collection<? extends T> c)
{
  this(Math.max(2 * c.size(), HashMap.DEFAULT_CAPACITY));
  addAll(c);
}

et ensuite appeler (ligne HashSet.java 122):

public HashSet(int initialCapacity, float loadFactor)
{
  map = init(initialCapacity, loadFactor);
}

Étant donné que la initméthode est en overridedLinkedHashSet

HashMap<T, String> init(int capacity, float load)
{
 return new LinkedHashMap<T, String>(capacity, load);
}

Le support mapest un LinkedHashMap.

Selon java doc de LinkedHashMap

Cette classe fournit toutes les opérations optionnelles Carte et permis null éléments. Comme HashMap, il fournit des performances en temps constant pour les opérations de base (addition, contient et supprimer), en supposant que les éléments fonction de hachage correctement se dispersent dans les seaux. La performance est susceptible d'être légèrement inférieur à celui de HashMap, en raison de la charge supplémentaire de maintenir la liste liée, à une exception près: itérer sur la collection-vues d'un LinkedHashMap nécessite un temps proportionnel à la taille de la carte, quelle que soit sa capacité . Itérer sur une table de hachage est susceptible d'être plus cher, ce qui nécessite un temps proportionnel à sa capacité.

Et la addméthode HashSetest -

public boolean add(E e) {
   return map.put(e, PRESENT)==null;
}

D' où la complexité temporelle moyenne est O (n) pour la construction. Pour l'algorithme, je pense que vous pouvez lire le code de LinkedHashMap pour plus de détails. Pour en savoir plus Comment est la mise en œuvre interne de LinkedHashMap différent de la mise en œuvre HashMap? , HashSet vs LinkedHashSet

Je suppose que tu aimes

Origine http://43.154.161.224:23101/article/api/json?id=222889&siteId=1
conseillé
Classement