Classe Arrays — Méthodes utilitaires pour tableaux
Prérequis
Maîtriser la déclaration, la création et l'initialisation des tableaux en Java. Connaître les types primitifs et les tableaux d'objets. Comprendre la notion de classe utilitaire avec méthodes statiques.
Objectifs
Découvrir la classe java.util.Arrays et ses nombreuses méthodes utilitaires. Savoir trier, rechercher, remplir, comparer et copier des tableaux efficacement. Maîtriser les versions séquentielles (sort) et parallèles (parallelSort) de tri.
1. Introduction à la classe Arrays
La classe java.util.Arrays fournit de nombreuses méthodes statiques pour manipuler des tableaux : tri, recherche, comparaison, remplissage, copie, conversion en chaîne, etc. Ces méthodes sont surchargées pour tous les types primitifs et pour les objets.
Une fois que vous aurez compris le pouvoir des tableaux, vous voudrez les utiliser pour stocker toutes sortes d'objets. Il est fréquent de vouloir effectuer des tâches similaires avec des tableaux différents (remplissage, tri, recherche). La classe Arrays centralise ces opérations.
La classe Arrays est située dans le package java.util. Utilisez import java.util.*; ou import java.util.Arrays; pour y accéder.
2. Tableau des méthodes principales
| Méthode | Description | Disponible depuis |
|---|---|---|
static int binarySearch(type[] a, type key) |
Recherche binaire — retourne l'indice de la clé (ou valeur négative si non trouvée) | Java 1.2 |
static boolean equals(type[] a, type[] a2) |
Compare deux tableaux élément par élément | Java 1.2 |
static void fill(type[] a, type val) |
Remplit tout le tableau avec la valeur spécifiée | Java 1.2 |
static void sort(type[] a) |
Trie le tableau en ordre croissant (Dual-Pivot Quicksort) | Java 1.2 |
static void sort(type[] a, int from, int to) |
Trie une plage spécifique du tableau | Java 1.2 |
static void parallelSort(type[] a) |
Trie en parallèle (Fork/Join) — plus efficace pour grands volumes | Java 8 |
static void parallelSort(type[] a, int from, int to) |
Trie une plage en parallèle | Java 8 |
static List<T> asList(T... a) |
Convertit un tableau en liste de taille fixe | Java 1.2 |
static type[] copyOf(type[] original, int newLength) |
Copie un tableau (troncature ou extension avec valeurs par défaut) | Java 6 |
static type[] copyOfRange(type[] original, int from, int to) |
Copie une plage du tableau vers un nouveau tableau | Java 6 |
static String toString(type[] a) |
Retourne une représentation textuelle du tableau (ex: [1, 2, 3]) |
Java 1.5 |
static int hashCode(type[] a) |
Calcule le code de hachage basé sur le contenu | Java 1.5 |
static void setAll(type[] a, IntFunction<? extends type> generator) |
Remplit le tableau en utilisant une fonction génératrice | Java 8 |
static void parallelSetAll(type[] a, IntFunction<? extends type> generator) |
Remplit en parallèle avec une fonction génératrice | Java 8 |
type
Dans le tableau ci-dessus, type représente un type de données. Une version surchargée de chaque méthode existe pour : int, long, short, byte, char, float, double, et Object.
3. Affichage d'un tableau — toString()
Exemple 1 — Arrays.toString()
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
int[] entiers = {2, 4, 5, 9, 5, 9};
String[] noms = {"Mostafa", "Amal", "Youssef"};
System.out.println(Arrays.toString(entiers));
System.out.println(Arrays.toString(noms));
}
}
[2, 4, 5, 9, 5, 9] [Mostafa, Amal, Youssef]
Pour les tableaux à deux dimensions, utilisez Arrays.deepToString() :
int[][] matrice = {{1, 2}, {3, 4}};
System.out.println(Arrays.deepToString(matrice));
// [[1, 2], [3, 4]]
4. Tri de tableaux — sort() et parallelSort()
4.1 Tri simple (sort)
Exemple 2 — Tri d'un tableau d'entiers
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
int[] nombres = {9, 4, 2, 5, 9, 5};
Arrays.sort(nombres);
System.out.println(Arrays.toString(nombres));
}
}
[2, 4, 5, 5, 9, 9]
4.2 Tri parallèle (parallelSort) — Java 8+
Les méthodes parallelSort() utilisent l'infrastructure Fork/Join pour trier en parallèle, ce qui améliore les performances sur les grands tableaux (milliers ou millions d'éléments).
Exemple 3 — Tri parallèle
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
int[] nombres = {9, 4, 2, 5, 9, 5};
Arrays.parallelSort(nombres);
System.out.println(Arrays.toString(nombres));
}
}
[2, 4, 5, 5, 9, 9]
4.3 Tri d'une plage spécifique
Exemple 4 — Tri d'une plage (de l'indice 2 à 6)
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
int[] nombres = {8, 3, 7, 1, 9, 2, 6, 4};
// Tri des indices 2 (inclus) à 6 (exclus) → indices 2,3,4,5
Arrays.sort(nombres, 2, 6);
System.out.println(Arrays.toString(nombres));
}
}
[8, 3, 1, 2, 7, 9, 6, 4]
5. Recherche binaire — binarySearch()
La recherche binaire nécessite que le tableau soit préalablement trié dans l'ordre croissant. Sinon, le résultat est indéterminé.
Exemple 5 — Recherche binaire
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
int[] nombres = {25, 30, 45, 50, 52, 60};
// Tableau déjà trié
int index = Arrays.binarySearch(nombres, 45);
System.out.println("Indice de 45 : " + index);
// Recherche d'une valeur absente
int indexAbsent = Arrays.binarySearch(nombres, 35);
System.out.println("Indice de 35 : " + indexAbsent);
}
}
Indice de 45 : 2 Indice de 35 : -3
- Si la clé est trouvée : indice ≥ 0
- Si la clé n'est pas trouvée : -(pointInsertion) - 1, où
pointInsertionest l'indice où la clé devrait être insérée pour maintenir l'ordre trié
Exemple : -3 signifie que 35 devrait être inséré à l'indice 2 (avant 45).
6. Remplissage — fill()
Exemple 6 — Remplissage d'un tableau
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
int[] tableau = new int[5];
// Remplir tout le tableau avec la valeur 10
Arrays.fill(tableau, 10);
System.out.println(Arrays.toString(tableau));
// Remplir une plage (indices 1 à 3 exclus → indices 1,2)
int[] tableau2 = {1, 2, 3, 4, 5};
Arrays.fill(tableau2, 1, 3, 99);
System.out.println(Arrays.toString(tableau2));
}
}
[10, 10, 10, 10, 10] [1, 99, 99, 4, 5]
7. Comparaison — equals()
Exemple 7 — Comparaison de tableaux
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
int[] t1 = {1, 2, 3};
int[] t2 = {1, 2, 3};
int[] t3 = {1, 2, 4};
System.out.println("t1 equals t2 : " + Arrays.equals(t1, t2));
System.out.println("t1 equals t3 : " + Arrays.equals(t1, t3));
// Pour les tableaux 2D, utilisez deepEquals()
int[][] m1 = {{1, 2}, {3, 4}};
int[][] m2 = {{1, 2}, {3, 4}};
System.out.println("m1 deepEquals m2 : " + Arrays.deepEquals(m1, m2));
}
}
t1 equals t2 : true t1 equals t3 : false m1 deepEquals m2 : true
8. Copie — copyOf() et copyOfRange()
Exemple 8 — Copie de tableaux
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
int[] original = {2, 4, 5, 9, 5, 9};
// Copie partielle (3 premiers éléments)
int[] copie1 = Arrays.copyOf(original, 3);
System.out.println("Copie 3 éléments : " + Arrays.toString(copie1));
// Extension (remplissage avec 0 pour int)
int[] copie2 = Arrays.copyOf(original, 10);
System.out.println("Extension à 10 : " + Arrays.toString(copie2));
// Copie d'une plage (indices 1 à 4)
int[] copie3 = Arrays.copyOfRange(original, 1, 5);
System.out.println("Plage [1,5[ : " + Arrays.toString(copie3));
}
}
Copie 3 éléments : [2, 4, 5] Extension à 10 : [2, 4, 5, 9, 5, 9, 0, 0, 0, 0] Plage [1,5[ : [4, 5, 9, 5]
int[], long[], short[], byte[]→ 0float[], double[]→ 0.0char[]→ '\u0000'boolean[]→ falseObject[]→ null
9. Conversion en liste — asList()
Exemple 9 — Conversion tableau → liste
import java.util.Arrays;
import java.util.List;
public class Test {
public static void main(String[] args) {
// Attention : asList fonctionne avec les types objets, pas les primitifs
Integer[] nombres = {10, 20, 30, 40};
List<Integer> liste = Arrays.asList(nombres);
System.out.println("Liste : " + liste);
System.out.println("Élément à l'indice 2 : " + liste.get(2));
// Modification de la liste → modification du tableau d'origine
liste.set(1, 99);
System.out.println("Tableau modifié : " + Arrays.toString(nombres));
}
}
Liste : [10, 20, 30, 40] Élément à l'indice 2 : 30 Tableau modifié : [10, 99, 30, 40]
asList()
- La liste retournée est de taille fixe —
add()ouremove()lèventUnsupportedOperationException. - Ne fonctionne pas avec les types primitifs. Pour
int[], utilisezArrays.stream(entiers).boxed().toList()(Java 16+).
10. Remplissage avec générateur — setAll() et parallelSetAll() (Java 8+)
Exemple 10 — Remplissage avec fonction génératrice
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
int[] carres = new int[10];
int[] factorielle = new int[10];
// Remplir avec les carrés des indices
Arrays.setAll(carres, i -> i * i);
// Remplir avec les factorielles (version parallèle)
Arrays.parallelSetAll(factorielle, i -> {
int result = 1;
for (int j = 2; j <= i; j++) result *= j;
return result;
});
System.out.println("Carrés : " + Arrays.toString(carres));
System.out.println("Factorielle : " + Arrays.toString(factorielle));
}
}
Carrés : [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] Factorielle : [1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880]
11. Exemple complet — Manipulation avancée
Exemple 11 — Toutes les méthodes combinées
import java.util.Arrays;
public class DemoArrays {
public static void main(String[] args) {
// 1. Création et remplissage
int[] notes = new int[20];
Arrays.setAll(notes, i -> (int)(Math.random() * 100) + 1);
System.out.println("Notes originales : " + Arrays.toString(notes));
// 2. Tri
Arrays.parallelSort(notes);
System.out.println("Notes triées : " + Arrays.toString(notes));
// 3. Recherche de la médiane
double mediane;
if (notes.length % 2 == 0) {
mediane = (notes[notes.length/2 - 1] + notes[notes.length/2]) / 2.0;
} else {
mediane = notes[notes.length/2];
}
System.out.printf("Médiane : %.1f%n", mediane);
// 4. Recherche d'une valeur
int rechercher = 75;
int pos = Arrays.binarySearch(notes, rechercher);
if (pos >= 0) {
System.out.printf("%d trouvé à l'indice %d%n", rechercher, pos);
} else {
int insertion = -pos - 1;
System.out.printf("%d non trouvé — serait à l'indice %d%n", rechercher, insertion);
}
// 5. Copie des meilleures notes (top 5)
int[] meilleures = Arrays.copyOfRange(notes, notes.length - 5, notes.length);
System.out.println("Top 5 : " + Arrays.toString(meilleures));
// 6. Remplissage
int[] notesEchec = Arrays.copyOf(notes, notes.length);
Arrays.fill(notesEchec, 0, 10, 0); // Les 10 premiers deviennent 0
System.out.println("Avec échecs : " + Arrays.toString(notesEchec));
}
}
Notes originales : [45, 23, 78, 12, 89, 34, 56, 91, 23, 45, 67, 45, 89, 12, 34, 56, 78, 90, 23, 45] Notes triées : [12, 12, 23, 23, 23, 34, 34, 45, 45, 45, 45, 56, 56, 67, 78, 78, 89, 89, 90, 91] Médiane : 45.0 75 non trouvé — serait à l'indice 14 Top 5 : [78, 89, 89, 90, 91] Avec échecs : [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 45, 56, 56, 67, 78, 78, 89, 89, 90]
12. Exercice
Analyse statistique avancée
Utiliser la classe Arrays pour effectuer une analyse statistique complète sur un tableau de notes.
Travail demandé
- Générer un tableau de 1000 notes aléatoires (valeurs entières entre 0 et 20)
- Trier le tableau avec
parallelSort() - Calculer et afficher :
- La note minimale et maximale
- La moyenne (avec
Arrays.stream().average()ou somme manuelle) - La médiane (valeur centrale)
- Le premier quartile (25%) et le troisième quartile (75%)
- L'écart interquartile (Q3 - Q1)
- Créer un histogramme des notes (fréquence par note)
- Afficher les notes les plus fréquentes
import java.util.Arrays;
import java.util.stream.IntStream;
public class StatistiquesNotes {
public static void main(String[] args) {
// 1. Génération des notes
int taille = 1000;
int[] notes = new int[taille];
Arrays.setAll(notes, i -> (int)(Math.random() * 21)); // 0 à 20 inclus
System.out.println("=== STATISTIQUES DES NOTES ===");
System.out.println("Nombre de notes : " + notes.length);
// 2. Tri
Arrays.parallelSort(notes);
// 3. Statistiques de base
int min = notes[0];
int max = notes[notes.length - 1];
System.out.println("Note minimale : " + min);
System.out.println("Note maximale : " + max);
// Moyenne
double moyenne = Arrays.stream(notes).average().orElse(0.0);
System.out.printf("Moyenne : %.2f%n", moyenne);
// Médiane
double mediane;
if (notes.length % 2 == 0) {
mediane = (notes[notes.length/2 - 1] + notes[notes.length/2]) / 2.0;
} else {
mediane = notes[notes.length/2];
}
System.out.printf("Médiane : %.1f%n", mediane);
// Quartiles
int q1Index = notes.length / 4;
int q3Index = 3 * notes.length / 4;
double q1 = notes[q1Index];
double q3 = notes[q3Index];
System.out.printf("Premier quartile (Q1) : %.1f%n", q1);
System.out.printf("Troisième quartile (Q3) : %.1f%n", q3);
System.out.printf("Écart interquartile : %.1f%n", q3 - q1);
// 4. Histogramme des fréquences
int[] frequences = new int[21]; // notes de 0 à 20
for (int note : notes) {
frequences[note]++;
}
System.out.println("\n--- HISTOGRAMME DES NOTES ---");
for (int i = 0; i < frequences.length; i++) {
if (frequences[i] > 0) {
int barres = frequences[i] / 10; // 1 barre = 10 étudiants
String barreVisual = "*".repeat(Math.min(barres, 50));
System.out.printf("Note %2d : %4d étudiants %s%n", i, frequences[i], barreVisual);
}
}
// 5. Notes les plus fréquentes
int maxFreq = 0;
for (int freq : frequences) {
if (freq > maxFreq) maxFreq = freq;
}
System.out.print("\nNotes les plus fréquentes (note : nombre) : ");
for (int i = 0; i < frequences.length; i++) {
if (frequences[i] == maxFreq) {
System.out.printf("%d:%d ", i, maxFreq);
}
}
System.out.println("\n");
// 6. Distribution par catégories
int[] categories = new int[5]; // 0-4, 5-9, 10-14, 15-17, 18-20
for (int note : notes) {
if (note <= 4) categories[0]++;
else if (note <= 9) categories[1]++;
else if (note <= 14) categories[2]++;
else if (note <= 17) categories[3]++;
else categories[4]++;
}
System.out.println("--- RÉPARTITION PAR CATÉGORIES ---");
System.out.printf("[0-4] : %3d étudiants (%.1f%%)%n", categories[0], categories[0] * 100.0 / taille);
System.out.printf("[5-9] : %3d étudiants (%.1f%%)%n", categories[1], categories[1] * 100.0 / taille);
System.out.printf("[10-14] : %3d étudiants (%.1f%%)%n", categories[2], categories[2] * 100.0 / taille);
System.out.printf("[15-17] : %3d étudiants (%.1f%%)%n", categories[3], categories[3] * 100.0 / taille);
System.out.printf("[18-20] : %3d étudiants (%.1f%%)%n", categories[4], categories[4] * 100.0 / taille);
}
}
Arrays.setAll(): génération conditionnelle des élémentsArrays.parallelSort(): tri optimisé pour grands volumesArrays.stream().average(): calcul direct de la moyenne- Tableau de fréquences : technique classique pour compter les occurrences
- Calcul des quartiles : utilisation des indices fractionnaires
L'essentiel en bref
- La classe
java.util.Arraysfournit des méthodes statiques pour manipuler des tableaux de tous types. toString(): affichage lisible — utilisezdeepToString()pour les tableaux 2D.sort()/parallelSort(): tri en ordre croissant —parallelSortest plus efficace pour les grands tableaux.binarySearch(): recherche efficace — nécessite un tableau trié.fill(): remplit tout ou partie d'un tableau avec une valeur.equals()/deepEquals(): comparaison élément par élément.copyOf()/copyOfRange(): copie avec troncature ou extension.asList(): conversion tableau → liste (taille fixe).setAll()/parallelSetAll(): remplissage programmatique (Java 8+).
La classe Arrays existe depuis Java 1.2 (1998) avec les méthodes fondamentales (sort, binarySearch, equals, fill). Java 1.5 (2004) a ajouté toString() et hashCode(). Java 6 (2006) a introduit copyOf() et copyOfRange(). Java 8 (2014) a révolutionné la classe avec l'ajout de parallelSort(), setAll(), parallelSetAll(), et l'intégration avec l'API Stream (Arrays.stream()). Ces améliorations reflètent l'évolution de Java vers le support du parallélisme et de la programmation fonctionnelle.
Discussion (0)
Soyez le premier à laisser un commentaire !
Laisser un commentaire
Votre commentaire sera visible après modération.