Les collections en Java sont principalement concentrées en deux parties, l'une dans le package java.util et l'autre dans java.util.concurrent. Cette dernière est basée sur la première et définit certaines collections qui implémentent des fonctions de synchronisation.
Cet article se concentre principalement sur divers objets de collection sous java.util. Les objets de collection en Java peuvent être grossièrement divisés en trois catégories : Liste, Ensemble et Carte. Le diagramme UML correspondant est le suivant (y compris la plupart des objets de collection sous java.util) :
Aperçu des collections
Les collections List et Set dans Java proviennent de Collection. C'est un bon point d'entrée pour l'apprentissage des collections. Il inclut les opérations qui sont généralement requises dans les collections :
Ajouter des éléments : add/addAll
Effacer la collection : effacer
Supprimer des éléments : supprimer/supprimerTout
Déterminer si la collection contient un élément : contain/containsAll
Déterminez si la collection est vide : isEmpty
Calculer le nombre d'éléments dans une collection : taille
Convertir une collection en tableau : toArray
Obtenir l'itérateur : itérateur
Regardons un exemple simple. Le code suivant renverra une collection dont les éléments sont des entiers générés aléatoirement :
collecte de retour ;
}
1) Utilisez des itérateurs pour parcourir la collection. Comme mentionné lors de la description de l'interface Collection ci-dessus, toutes les collections auront un itérateur que nous pouvons utiliser pour parcourir la collection.
List en Java est une extension efficace du tableau. C'est une structure qui peut contenir des éléments de n'importe quel type si les génériques ne sont pas utilisés, elle ne peut contenir que des éléments du type spécifié par les génériques. Par rapport aux tableaux, la capacité de List peut être étendue de manière dynamique.
Les éléments de la liste peuvent être répétés et les éléments à l'intérieur sont "ordonnés". Le "ordonné" ici ne signifie pas trier, mais signifie que nous pouvons spécifier la position d'un élément dans la collection.
Les objets de collection couramment utilisés dans List incluent : ArrayList, Vector et LinkedList, les deux premiers sont stockés sur la base de tableaux et les seconds sont stockés sur la base de listes chaînées. Parmi eux, Vector est thread-safe, et les deux autres ne le sont pas.
La liste peut contenir null, même si des génériques sont utilisés.
ArrayList est peut-être l'objet de collection le plus couramment utilisé. Dans l'exemple de code ci-dessus, nous l'utilisons également pour instancier un objet Collection, nous n'entrerons donc pas dans les détails ici.
Vecteur
Un exemple de vecteur est le suivant. Voyons d’abord comment générer et générer un vecteur :
[9, 29, 32, 54, 12]
la taille du vecteur est de 3
[29, 32, 54]
LinkedList utilise des listes chaînées pour stocker des données. Son exemple de code est le suivant :
Le résultat est le suivant :
nul
nul
nul
la taille de la liste chaînée est de 8
[100, 84, 19, 57, 68, 26, 27, 47]
Set est similaire à List, les deux sont utilisés pour stocker un seul élément et le nombre d'éléments individuels est incertain. Mais Set ne peut pas contenir d'éléments en double. Si deux éléments identiques sont insérés dans Set, ce dernier élément ne sera pas inséré.
Set peut être grossièrement divisé en deux catégories : Set non trié et Set trié. L'ensemble non trié comprend HashSet et LinkedHashSet, et l'ensemble trié fait principalement référence à TreeSet. Parmi eux, HashSet et LinkedHashSet peuvent contenir null.
Jeu de hachage
HashSet est une collection soutenue par une table de hachage, qui n'est pas thread-safe.
Regardons l'exemple suivant, qui est fondamentalement le même que le premier exemple avec Vector :
pour (int i = 0; i < 3; i++)
{
set.add(nouveau Integer(100));
}
set.add(null);
System.out.println("la taille de l'ensemble est " + set.size());
System.out.println(set);
}
classeMonEntier
{
valeur entière privée ;
public MyInteger (valeur entière)
{
this.value = valeur ;
}
chaîne publique versString()
{
return String.valueOf(value);
}
public int hashCode()
{
renvoyer 1 ;
}
public booléen égal (Objet obj)
{
renvoie vrai ;
}
}
Voici la méthode de test correspondante :
pour (int i = 0; i < 3; i++)
{
set.add(nouveau MyInteger(100));
}
System.out.println("la taille de l'ensemble est " + set.size());
System.out.println(set);
}
TreeSet est un Set qui prend en charge le tri et son interface parent est SortedSet.
Jetons d'abord un coup d'œil aux opérations de base de TreeSet :
Aléatoire r = nouveau Aléatoire();
pour (int i = 0; i < 5; i++)
{
set.add(new Integer(r.nextInt(100)));
}
System.out.println(set);
System.out.println(set.first());
System.out.println(set.last());
System.out.println(set.descendingSet());
System.out.println(set.headSet(new Integer(50)));
System.out.println(set.tailSet(new Integer(50)));
System.out.println(set.subSet(30, 60));
System.out.println(set.floor(50));
System.out.println(set.ceiling(50));
}
[53, 49, 48, 42, 8]
[8, 42, 48, 49]
[53]
[42, 48, 49, 53]
Ensuite, nous redéfinissons d’abord Integer :
public MyInteger2 (valeur int)
{
this.value = valeur ;
}
public int compareTo (Objet arg0)
{
MonEntier2 temp = (MonEntier2)arg0;
if (temp == null) renvoie -1 ;
si (temp.value > this.value)
{
renvoyer 1 ;
}
sinon si (temp.value <this.value)
{
renvoie -1 ;
}
renvoie 0 ;
}
public booléen égal (Objet obj)
{
return compareTo(obj) == 0;
}
chaîne publique versString()
{
return String.valueOf(value);
}
}
La carte stocke des « paires clé-valeur ». Semblable à Set, il existe deux types de cartes en Java : les cartes triées et non triées incluent HashMap, Hashtable et LinkedHashMap, et les cartes triées incluent TreeMap.
Carte non triée
HashMap et Hashtable sont stockés sous forme de tables de hachage. HashMap n'est pas thread-safe, mais Hashtable est thread-safe. Nous pouvons considérer HashMap comme une version « simplifiée » de Hashtable.
HashMap peut stocker null, que ce soit pour la clé ou la valeur. La table de hachage ne peut pas stocker null.
Indépendamment de HashMap ou de Hashtable, si l'on observe son constructeur, nous constaterons qu'il peut avoir deux paramètres : initialCapacity et loadFactor. Par défaut, initialCapacity est égal à 16 et loadFactor est égal à 0,75. Ceci est lié au nombre d'éléments pouvant être stockés dans la table de hachage. Lorsque le nombre d'éléments dépasse initialCapacity*loadFactor, la méthode rehash sera déclenchée pour développer la table de hachage. Si nous devons y insérer trop d’éléments, nous devons ajuster ces deux paramètres de manière appropriée.
Regardons d'abord un exemple de HashMap :
map.put(new Integer(1), "a");
map.put(new Integer(2), "b");
map.put(new Integer(3), "c");
System.out.println(carte);
System.out.println(map.entrySet());
System.out.println(map.keySet());
System.out.println(map.values());
}
map.put(null, null);
map.put(null, null);
map.put(nouveau Integer(4), null);
map.put(new Integer(5), null);
System.out.println(carte);
System.out.println(map.entrySet());
System.out.println(map.keySet());
System.out.println(map.values());
}
table.put(new Integer(1), "a");
table.put(new Integer(2), "b");
table.put(new Integer(3), "c");
System.out.println(table);
System.out.println(table.entrySet());
System.out.println(table.keySet());
System.out.println(table.values());
}
hashTableTest2() vide statique privé
{
Map<Integer,String> table = new Hashtable<Integer, String>();
table.put(null, null);
table.put(null, null);
table.put(nouveau Integer(4), null);
table.put(nouveau Integer(5), null);
System.out.println(table);
System.out.println(table.entrySet());
System.out.println(table.keySet());
System.out.println(table.values());
}
Sorting Map fait principalement référence à TreeMap, qui a une complexité temporelle de O(log(n)) lors de l'ajout, de la suppression et de la recherche d'éléments. Ce n’est pas thread-safe.
Ses caractéristiques sont très similaires à TreeSet, je n’entrerai donc pas dans les détails ici.