J'ai souvent rencontré de telles questions lors des entretiens dans le passé. Hélas, j'ai honte, la fondation est trop pauvre, il n'y a aucun moyen, je me sens du tort
Nous devons maintenant parler des différences et des connexions entre ces trois: ces trois implémentent l'interface de liste, toutes ont des méthodes définies dans l'interface de liste, et ont également des méthodes d'interface de collecte;
ArrayList: utilise la méthode du tableau pour stocker les données, la requête et la vitesse de modification sont rapides, mais la vitesse d'addition et de suppression est lente;
LinkedList: utilise la méthode de la liste liée pour stocker les données, la vitesse de requête et de modification est lente, mais la vitesse d'addition et de suppression est rapide.
Vector: Il utilise également des tableaux de stockage. itérateurs, énumérations, get (int index) et indexof (int index), mais ArrayList n'a pas d'énumérations
ArrayList et Vector Utilisent les tableaux pour stocker des données. Les opérations, les données d'indextes sont rapidement insérées. ou la traversée vers l'arrière, mais seul cet élément est requis lors de l'insertion de données.
Les tables linéaires, les listes liées et les tables de hachage sont couramment utilisées. Ces classes sont toutes dans le package java.util. Cet article tente d'expliquer aux lecteurs le rôle de chaque classe et comment les utiliser correctement grâce à une description simple.
Collection ├List │ ├LinkedList │ ├ArrayList │ └Vector │ └stack └setmap ├hashTable ├hashmap └weakhashmap
Interface de collecte
La collection est l'interface de collection la plus élémentaire. Certaines collections permettent les mêmes éléments tandis que d'autres ne le font pas. Certains peuvent trier mais d'autres ne le peuvent pas. Le SDK Java ne fournit pas de classes directement héritées de la collection.
Toutes les classes qui implémentent l'interface de collection doivent fournir deux constructeurs standard: le constructeur sans paramètre est utilisé pour créer une collection vide, et un constructeur de paramètres de collection est utilisé pour créer une nouvelle collection, cette nouvelle collection et passez. même élément. Ce dernier constructeur permet à l'utilisateur de copier une collection.
Comment itérer à travers chaque élément d'une collection? Quel que soit le type réel de la collection, il prend en charge une méthode Iterator (), qui renvoie un itérateur, et utilise cet itérateur pour accéder à chaque élément de la collection un par un. Les usages typiques sont les suivants:
Iterator it = collection.iterator ();
Les deux interfaces dérivées de l'interface de collection sont la liste et le définition.
Interface de liste
La liste est une collection commandée, et l'utilisation de cette interface vous permet de contrôler avec précision la position de chaque insertion d'élément. Les utilisateurs peuvent utiliser des index (la position des éléments dans la liste, similaire aux indices de tableau) pour accéder aux éléments de la liste, ce qui est similaire aux tableaux de Java.
Contrairement à l'ensemble mentionné ci-dessous, la liste permet les mêmes éléments.
En plus de la méthode Iterator () qui a l'interface de collecte nécessaire, la liste fournit également une méthode ListIterator (), qui renvoie une interface listIterator. Supprimer, définir des éléments et peut également traverser vers l'avant ou vers l'arrière.
Les classes courantes qui implémentent les interfaces de liste incluent LinkedList, ArrayList, Vector et Stack.
Classe LinkedList
LinkedList implémente l'interface de liste, permettant des éléments nuls. De plus, LinkedList fournit des méthodes supplémentaires Get, Supprimer, INSERT à l'en-tête ou à la queue de la liste Linked. Ces opérations permettent à LinkedList d'être utilisé comme pile, file d'attente ou file d'attente bidirectionnelle.
Notez que LinkedList n'a pas de méthode synchrone. Si plusieurs threads accèdent à une liste en même temps, vous devez implémenter vous-même l'accès à la synchronisation. Une solution consiste à construire une liste synchrone lors de la création:
List list = collections.SynchronizedList (new LinkedList (...));
Classe ArrayList
ArrayList implémente les tableaux de taille variable. Il permet tous les éléments, y compris null. ArrayList n'est pas synchronisé.
Le temps d'exécution de la taille, iSempty, get, set méthodes est constant. Cependant, la surcharge de la méthode ADD est une constante amortie, et il faut du temps (n) pour ajouter n éléments. Les autres méthodes ont un temps d'exécution linéaire.
Chaque instance ArrayList a une capacité, qui est de la taille du tableau utilisé pour stocker des éléments. Cette capacité peut augmenter automatiquement à mesure que de nouveaux éléments sont constamment ajoutés, mais l'algorithme de croissance n'est pas défini. Lorsqu'un grand nombre d'éléments doivent être insérés, la méthode d'assurance peut être appelée avant d'insérer pour augmenter la capacité de la liste Array pour améliorer l'efficacité de l'insertion.
Comme LinkedList, ArrayList n'est également pas synchronisé.
Classe vectorielle
Le vecteur est très similaire à ArrayList, mais le vecteur est synchrone. Iterator créé par Vector, bien que Iterator créé par ArrayList, soit la même interface que Iterator créée par ArrayList, car le vecteur est synchronisé, lorsqu'un itérateur est créé et est utilisé, un autre thread modifie l'état du vecteur (par exemple, en ajoutant ou en supprimant certains) pour le moment, la conception concurrentModificationException sera lancée lorsque la méthode de l'itérateur sera appelée, de sorte que l'exception doit être capturée.
Classe de pile
Stack Hérite de Vector, implémentant une dernière pile de premier out. La pile fournit 5 méthodes supplémentaires pour permettre à Vector d'être utilisée comme pile. Les méthodes de base push et pop et la méthode PEEK obtiennent les éléments en haut de la pile, la méthode vide teste si la pile est vide et la méthode de recherche détecte la position d'un élément dans la pile. La pile est juste créée et est une pile vide.
Définir l'interface
SET est une collection qui ne contient pas d'éléments en double, c'est-à-dire que deux éléments E1 et E2 ont e1.equals (e2) = false, et Set a au plus un élément nul.
De toute évidence, le constructeur de Set a une contrainte et le paramètre de collecte passé ne peut pas contenir d'éléments en double.
Veuillez noter: les objets mutables doivent être exploités avec soin. Si un élément mutable dans un ensemble modifie son propre état, provoquant l'objet.equals (objet) = true pour causer certains problèmes.
Interface cartographique
Veuillez noter que la carte n'hérite pas de l'interface de collecte, et MAP fournit un mappage de la clé à la valeur. Une carte ne peut pas contenir la même touche et chaque clé ne peut cartographier qu'une seule valeur. L'interface de carte fournit trois types de vues de la collection.
Classe de hachage
Le hashable hérite de l'interface MAP et implémente une table de hachage avec un mappage de valeur clé. Tout objet non nulle peut être utilisé comme clé ou valeur.
Utilisez Put (Key, Value) pour ajouter des données, utilisez Get (Key) pour récupérer les données.
Le hachage ajuste les performances par les paramètres de capacité initiale et de facteur de charge. Habituellement, le facteur de charge par défaut 0,75 peut mieux atteindre le temps et l'équilibre de l'espace. L'augmentation du facteur de charge peut économiser de l'espace, mais le temps de recherche correspondant augmentera, ce qui affectera les opérations comme Get and Put.
Un exemple simple d'utilisation d'un hashtable est le suivant: Mettez 1, 2 et 3 dans un hashtable, et leurs clés sont "une", "deux", "trois" respectivement:
Nombres de hashtable = new hashTable ();
nombres.put ("un", nouvel entier (1));
nombres.put ("deux", nouvel entier (2));
nombres.put ("trois", nouvel entier (3));
Pour éliminer un nombre, comme 2, utilisez la clé correspondante:
Entier n = (entier) nombres.get ("deux");
System.out.println ("deux =" + n);
Étant donné qu'un objet en tant que clé déterminera la position de la valeur correspondante en calculant sa fonction de hachage, tout objet en tant que clé doit implémenter le code de hash et égal aux méthodes. HashCode et égal aux méthodes héritent de l'objet racine. ) = Vrai, alors leur code de hachage doit être le même, mais si les deux objets sont différents, leurs codes de hash peuvent ne pas être différents. de faire fonctionner les tables de hachage à augmenter.
Si le même objet a des codes de hachage différents, l'opération sur la table de hachage aura des résultats inattendus (la méthode GET attendue renvoie Null). en même temps.
Le haschable est synchronisé.
Classe de hashmap
Hashmap est similaire à Hashable, la différence est que le hashmap est asynchrone et permet une valeur nul et une clé nul et une clé nul. , mais lorsque Hashmap est considéré comme une collection (la méthode VALEUR () peut renvoyer une collection), sa surcharge de temps de sous-opération itérative est proportionnelle à la capacité de HashMAP. Par conséquent, si les performances des opérations d'itération sont très importantes, ne définissez pas la capacité d'initialisation du hashmap pour être trop élevée ou si le facteur de charge est trop faible.
Classe faiblehashmap
WIBLHASHMAP est un Hashmap amélioré qui met en œuvre la «référence faible» à la clé.
Résumer
Si la pile, la file d'attente et d'autres opérations sont impliquées, vous devriez envisager d'utiliser la liste.
Si le programme est dans un environnement unique ou si l'accès est dans un seul thread, compte tenu des classes asynchrones, elle est plus efficace.
Portez une attention particulière au fonctionnement des tables de hachage.
Essayez de renvoyer l'interface au lieu du type réel, comme le renvoi d'une liste au lieu d'une liste Array. C'est pour la programmation abstraite.
Synchronisation
Le vecteur est synchrone. Certaines méthodes de cette classe garantissent que les objets du vecteur sont en file d'attente. ArrayList est asynchrone, donc les objets dans ArrayList ne sont pas des filets. Étant donné que les exigences de synchronisation affecteront l'efficacité de l'exécution, l'utilisation d'ArrayList est un bon choix si vous n'avez pas besoin de collections de filetage, ce qui peut éviter les frais généraux de performances inutiles en raison de la synchronisation.
Croissance des données
À partir du mécanisme de mise en œuvre interne, ArrayList et Vector utilisent tous deux des tableaux (array) pour contrôler les objets de la collection. Lorsque vous ajoutez des éléments à ces deux types, si le nombre d'éléments dépasse la longueur actuelle du tableau interne, ils doivent étendre la longueur du tableau interne. 50% d'origine de cela, donc la dernière fois que vous obtenez cette collection prendra toujours plus de place que vous avez réellement besoin. Donc, si vous souhaitez enregistrer beaucoup de données dans une collection, il y a certains avantages à utiliser Vector, car vous pouvez éviter les frais généraux de ressources inutiles en définissant la taille d'initialisation de la collection.
Mode d'utilisation
Dans ArrayList et Vector, il faut le même temps pour trouver des données à partir d'un emplacement spécifié (via l'index) ou pour ajouter et supprimer un élément à la fin de l'ensemble. Cependant, si des éléments sont ajoutés ou supprimés ailleurs dans l'ensemble, le temps passé augmentera linéairement: O (ni), où N représente le nombre d'éléments dans l'ensemble, et I représente la position d'index où les éléments augmentent ou suppriment les éléments. Pourquoi cela se produit-il? On pense que lors de l'exécution des opérations ci-dessus, tous les éléments après les éléments i-th et i-te de l'ensemble doivent effectuer des opérations de déplacement. Qu'est-ce que tout cela signifie?
Cela signifie que vous recherchez simplement des éléments dans une position spécifique ou ajoutez et supprimez et supprimez les éléments à la fin de la collection, puis utiliser Vector ou ArrayList est OK. S'il s'agit d'une autre opération, vous feriez mieux de choisir une autre classe d'opération de collecte. Par exemple, le temps qu'il faut pour que la classe de collection LinkList ajouter ou supprimer des éléments à n'importe quelle position de la collection est la même? est l'emplacement de l'index. LinkList créera également des objets pour chaque élément inséré, et tout ce que vous devez comprendre apportera également des frais généraux supplémentaires.
Enfin, dans le livre Practical Java, Peter Haggar suggère d'utiliser un tableau simple (tableau) au lieu d'un vecteur ou d'un arraylist. Cela est particulièrement vrai pour les programmes avec une efficacité d'exécution élevée. Étant donné que l'utilisation des tableaux (tableau) évite la synchronisation, les appels de méthode supplémentaires et la réallocation inutile des opérations spatiales.