Framework de collections Java

Dès avant Java 2, Java fournissait des classes ad hoc. Par exemple : Dictionary, Vector, Stack et Properties ; ces classes servaient à stocker et manipuler des groupes d'objets.

Bien que ces classes soient très utiles, elles manquent d'un thème central et unifié. Pour cette raison, la façon d'utiliser la classe Vector est assez différente de celle d'utiliser la classe Properties.

Le framework de collections a été conçu pour répondre aux objectifs suivants.

  • Le framework doit être performant. Les implémentations des collections de base (tableaux dynamiques, listes chaînées, arbres, tables de hachage) doivent également être efficaces.

  • Le framework permet à différents types de collections de fonctionner de manière similaire, avec un haut degré d'interopérabilité.

  • Les extensions et adaptations d'une collection doivent être simples.

À cette fin, l'ensemble du framework de collections est conçu autour d'un ensemble d'interfaces standard. Vous pouvez directement utiliser les implémentations standard de ces interfaces, telles que :LinkedList, HashSet, etTreeSet, etc. De plus, vous pouvez également implémenter vos propres collections via ces interfaces.

D'après le diagramme du framework de collections ci-dessus, on peut voir que le framework de collections Java comprend principalement deux types de conteneurs : l'un est Collection, qui stocke une collection d'éléments ; l'autre est Map, qui stocke des associations de paires clé/valeur. L'interface Collection a 3 sous-types : List, Set et Queue. En dessous de celles-ci se trouvent quelques classes abstraites, et enfin des classes d'implémentation concrètes. Les plus couramment utilisées incluentArrayList、LinkedList、HashSet、LinkedHashSet, HashMap, LinkedHashMap, et ainsi de suite.

Le framework de collections est une architecture unifiée pour représenter et manipuler des collections. Tous les frameworks de collections contiennent les éléments suivants :

  • Interfaces :

    Ce sont des types de données abstraits qui représentent des collections. Par exemple : Collection, List, Set, Map, etc. La raison pour laquelle plusieurs interfaces sont définies est de manipuler les objets de collection de différentes manières.
  • Implémentations (classes) :Ce sont des implémentations concrètes des interfaces de collection. En substance, ce sont des structures de données réutilisables, par exemple : ArrayList, LinkedList, HashSet, HashMap.

  • Algorithmes :Ce sont quelques calculs utiles effectués par des méthodes dans des objets qui implémentent les interfaces de collection, par exemple : la recherche et le tri. Ces algorithmes réalisent le polymorphisme car une même méthode peut avoir différentes implémentations sur des interfaces similaires.

En plus des collections, le framework définit également plusieurs interfaces et classes Map. Les Maps stockent des paires clé/valeur. Bien que les Maps ne soient pas des collections, elles sont entièrement intégrées aux collections.

Le système du framework de collections est illustré dans la figure ci-dessous.

Le framework de collections Java fournit un ensemble d'interfaces et de classes performantes et faciles à utiliser. Le framework de collections Java se trouve dans le paquetage java.util, vous devez donc importer ce paquetage lorsque vous utilisez le framework de collections.


Interfaces de collection

Le framework de collections définit quelques interfaces. Cette section donne un aperçu de chaque interface :

Non. Description de l'interface
1 Interface Collection

Collection est l'interface de collection la plus fondamentale. Une Collection représente un groupe d'objets, c'est-à-dire les éléments de la Collection. Java ne fournit pas de classes qui héritent directement de Collection ; il fournit uniquement des sous-interfaces qui en héritent (comme List et Set).

L'interface Collection stocke un groupe d'objets non uniques et non ordonnés.

2 Interface List

List est une Collection ordonnée. Avec cette interface, vous pouvez contrôler précisément la position où chaque élément est inséré, et accéder aux éléments de la List par index (la position de l'élément dans la List, semblable à un indice de tableau). Le premier élément a un index de 0, et les éléments en double sont autorisés.

L'interface List stocke un groupe d'objets non uniques et ordonnés (ordre d'insertion).

3 Set

Set a exactement la même interface, mais se comporte différemment : Set ne stocke pas d'éléments en double

L'interface Set stocke un groupe d'objets uniques et non ordonnés.

4 SortedSet
Hérite de Set et stocke une collection ordonnée.
5 Map

L'interface Map stocke un groupe d'objets clé-valeur et fournit une correspondance de clé vers valeur.

6 Map.Entry
Décrit un élément (paire clé/valeur) dans une Map. C'est une interface interne de Map.
7 SortedMap
Hérite de Map, en conservant les clés par ordre croissant.
8 Enumeration
Il s'agit d'une interface héritée qui définissait des méthodes permettant d'énumérer les éléments d'une collection d'objets (obtenus un à la fois). Cette interface héritée a été remplacée par les itérateurs.

Différences entre Set et List

  • 1. Les instances de l'interface Set stockent des données non ordonnées et sans doublons. Les instances de l'interface List stockent des éléments ordonnés et répétables.

  • 2. Set a une faible efficacité de recherche mais une efficacité élevée de suppression et d'insertion ; l'insertion et la suppression n'entraînent pas de changement de position des éléments.<Les classes d'implémentation incluent HashSet, TreeSet>。

  • 3. List est similaire à un tableau et peut croître dynamiquement ; la longueur de List augmente automatiquement en fonction de la longueur des données réellement stockées. Elle a une efficacité élevée pour trouver des éléments et une faible efficacité pour l'insertion et la suppression, car cela provoque des changements de position d'autres éléments.<Les classes d'implémentation incluent ArrayList, LinkedList, Vector> 。


Classes d'implémentation de Collection (classes de collection)

Java fournit un ensemble de classes de collection standard qui implémentent l'interface Collection. Certaines d'entre elles sont des classes concrètes et peuvent être utilisées directement, tandis que d'autres sont des classes abstraites qui fournissent des implémentations partielles de l'interface.

Les classes de collection standard sont résumées dans le tableau suivant :

Non. Description de la classe
1 AbstractCollection 
Implémente la plupart des interfaces de collection.
2 AbstractList 
Hérite de AbstractCollection et implémente la plupart de l'interface List.
3 AbstractSequentialList 
Hérite de AbstractList et fournit un accès chaîné aux éléments de données plutôt qu'un accès aléatoire.
4 LinkedList

Cette classe implémente l'interface List et autorise les éléments null. Elle est principalement utilisée pour créer des structures de données de liste chaînée. Cette classe n'a pas de méthodes synchronisées. Si plusieurs threads accèdent simultanément à une List, vous devez implémenter vous-même la synchronisation des accès. La solution consiste à construire une List synchronisée lors de la création de la List. Par exemple :

List list=Collections.synchronizedList(newLinkedList(...));

LinkedList a une faible efficacité de recherche.

5 ArrayList

Cette classe implémente également l'interface List et implémente un tableau de taille variable, offrant de meilleures performances lors de l'accès aléatoire aux éléments et de leur parcours. Cette classe est également non synchronisée et ne doit pas être utilisée dans des situations multithread. ArrayList augmente de 50% de sa longueur actuelle, et l'efficacité d'insertion/suppression est faible.

6 AbstractSet 
Hérite de AbstractCollection et implémente la plupart de l'interface Set.
7 HashSet

Cette classe implémente l'interface Set. Les éléments en double ne sont pas autorisés, l'ordre des éléments dans l'ensemble n'est pas garanti, et les éléments avec une valeur null sont autorisés, mais au plus un.

8 LinkedHashSet
A un ordre d'itération prévisibleSetL'implémentation de l'interface par table de hachage et liste chaînée.
9 TreeSet

Cette classe implémente l'interface Set et peut implémenter le tri et d'autres fonctionnalités.

10 AbstractMap 
Implémente la plupart de l'interface Map.
11 HashMap
HashMap est une table de hachage ; son contenu stocké est constitué de mappages de paires clé-valeur.
Cette classe implémente l'interface Map, stocke les données en fonction de la valeur HashCode de la clé, possède une vitesse d'accès très rapide, autorise au plus un enregistrement avec une clé null et ne prend pas en charge la synchronisation des threads.
12 TreeMap
Hérite de AbstractMap et utilise un arbre.
13 WeakHashMap
Hérite de la classe AbstractMap et utilise une table de hachage avec des clés faibles.
14 LinkedHashMap
Hérite de HashMap et trie les éléments en utilisant leur ordre naturel.
15 IdentityHashMap
Hérite de la classe AbstractMap et utilise l'égalité de référence lors de la comparaison de documents.

Plus tôt dans le tutoriel, les classes définies dans le package java.util ont été abordées, comme indiqué ci-dessous :

Non. Description de la classe
1 Vecteur

Cette classe est très similaire à ArrayList, mais cette classe est synchronisée et peut être utilisée dans des situations multithread. Cette classe permet de définir la longueur de croissance par défaut, et la méthode d'extension par défaut est 2 fois l'original.

2 Pile
Stack est une sous-classe de Vector ; elle implémente une pile standard dernier entré, premier sorti.
3 Dictionnaire
La classe Dictionary est une classe abstraite utilisée pour stocker des paires clé/valeur, et sa fonction est similaire à la classe Map.
4 Hashtable

Hashtable est une sous-classe de la classe Dictionary et se trouve dans le package java.util.

5 Propriétés
Properties hérite de Hashtable et représente un ensemble persistant de propriétés. Dans la liste de propriétés, chaque clé et sa valeur correspondante sont des chaînes de caractères.
6 BitSet
Une classe BitSet crée un type spécial de tableau pour contenir des valeurs de bits. La taille du tableau dans BitSet augmente selon les besoins.

Algorithmes de collections

Le framework de collections définit plusieurs algorithmes qui peuvent être utilisés sur des collections et des maps. Ces algorithmes sont définis comme des méthodes statiques de classes de collections.

Lorsqu'on tente de comparer des types incompatibles, certaines méthodes peuvent lever une ClassCastException. Lorsqu'on tente de modifier une collection non modifiable, une UnsupportedOperationException est levée.

Les collections définissent trois variables statiques : EMPTY_SET, EMPTY_LIST et EMPTY_MAP. Ces variables sont toutes immuables.

N° de série Description des algorithmes
1 Algorithmes de collections
Voici une liste de toutes les implémentations d'algorithmes.

Comment utiliser les itérateurs

Habituellement, vous voudrez parcourir les éléments d'une collection. Par exemple, afficher chaque élément de la collection.

Généralement, le parcours des tableaux utilise une boucle for ou une boucle for améliorée. Ces deux méthodes peuvent également être utilisées dans le framework des collections, mais il existe une autre méthode qui utilise un itérateur pour parcourir le framework des collections. C'est un objet qui implémente l'Iteratorinterface Iterator ou l'interface ListIterator.

Les itérateurs vous permettent d'obtenir ou de supprimer des éléments d'une collection via une boucle. ListIterator hérite de Iterator pour permettre un parcours bidirectionnel des listes et la modification des éléments.

N° de série Description des méthodes d'Iterator
1 Utilisation d'Iterator en Java
Ici, à travers des exemples, toutes les méthodes fournies par les interfaces Iterator et ListIterator sont listées.

Parcours d'ArrayList

Exemple

import java.util.*; public class Test{ public static void main(String[] args) { List<String> list=new ArrayList<String>(); list.add("Hello"); list.add("World"); list.add("HAHAHAHA"); //La première méthode de parcours utilise For-Each pour parcourir la List. for (String str : list) { //Cela peut également être réécrit sous la forme for(int i=0;i<list.size();i++) System.out.println(str); } //La deuxième méthode de parcours convertit la liste en un contenu lié à un tableau pour le parcours. String[] strArray=new String[list.size()]; list.toArray(strArray); for(int i=0;i<strArray.length;i++) //Cela peut également être réécrit sous la forme for(String str:strArray) { System.out.println(strArray[i]); } //Le troisième parcours utilise un itérateur pour le parcours concerné. Iterator<String> ite=list.iterator(); while(ite.hasNext())//Détermine s'il y a une valeur après l'élément suivant. { System.out.println(ite.next()); } } }

Analyse :

Les trois méthodes servent à parcourir la collection ArrayList. La troisième méthode utilise un itérateur, ce qui évite de se soucier de dépasser la longueur de la collection pendant le parcours.

Parcours d'une Map

Exemple

import java.util.*; public class Test{ public static void main(String[] args) { Map<String, String> map = new HashMap<String, String>(); map.put("1", "value1"); map.put("2", "value2"); map.put("3", "value3"); //Première : couramment utilisée, récupérer la valeur une seconde fois. System.out.println("Parcourir la clé et la valeur via Map.keySet:"); for (String key : map.keySet()) { System.out.println("key= "+ key + " and value= " + map.get(key)); } //Deuxième System.out.println("Utiliser un itérateur via Map.entrySet pour parcourir la clé et la valeur :"); Iterator<Map.Entry<String, String>> it = map.entrySet().iterator(); while (it.hasNext()) { Map.Entry<String, String> entry = it.next(); System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue()); } //Troisième : recommandé, surtout lorsque la capacité est grande. System.out.println("Parcourir la clé et la valeur via Map.entrySet"); for (Map.Entry<String, String> entry : map.entrySet()) { System.out.println("key= " + entry.getKey() + " et value= " + entry.getValue()); } //Quatrième System.out.println("Parcourir toutes les valeurs via Map.values(), mais ne peut pas parcourir les clés."); for (String v : map.values()) { System.out.println("value= " + v); } } }


Comment utiliser les comparateurs

TreeSet et TreeMap stockent les éléments dans un ordre trié. Cependant, c'est un comparateur qui définit précisément quel ordre de tri est utilisé.

Cette interface nous permet de trier une collection de différentes manières.

N° de série Comparator Méthode Description
1 Utilisation de Java Comparator
Ici, au moyen d'exemples, toutes les méthodes fournies par l'interface Comparator sont listées.

Résumé

Le framework des collections Java fournit aux programmeurs des structures de données et des algorithmes prêts à l'emploi pour les manipuler.

Une collection est un objet qui peut contenir des références à d'autres objets. Les interfaces de collection déclarent les opérations qui peuvent être effectuées sur chaque type de collection.

Les classes et interfaces du framework des collections sont toutes dans le paquetage java.util.

Après l'ajout d'un objet quelconque à une classe de collection, il est automatiquement converti en type Object, donc lorsqu'il est récupéré, une conversion de type forcée est nécessaire.

Autres extensions