Java Language
Tableaux
Recherche…
Introduction
Les tableaux permettent le stockage et la récupération d'une quantité arbitraire de valeurs. Ils sont analogues aux vecteurs en mathématiques. Les tableaux de tableaux sont analogues aux matrices et agissent comme des tableaux multidimensionnels. Les tableaux peuvent stocker toutes les données de tout type: les primitives telles que les types int
ou de référence tels que Object
.
Syntaxe
-
ArrayType[] myArray;
// Déclaration des tableaux -
ArrayType myArray[];
// Une autre syntaxe valide (moins utilisée et déconseillée) -
ArrayType[][][] myArray;
// Déclarer des tableaux déchiquetés multidimensionnels (repeter [] s) -
ArrayType myVar = myArray[index];
// Accès à l'élément (lecture) à l'index -
myArray[index] = value;
// Attribuer une valeur à l'index
de position du tableau -
ArrayType[] myArray = new ArrayType[arrayLength];
// Syntaxe d'initialisation de tableau -
int[] ints = {1, 2, 3};
// Syntaxe d'initialisation du tableau avec les valeurs fournies, longueur déduite du nombre de valeurs fournies: {[valeur1 [, valeur2] *]} -
new int[]{4, -5, 6} // Can be used as argument, without a local variable
-
int[] ints = new int[3]; // same as {0, 0, 0}
-
int[][] ints = {{1, 2}, {3}, null};
// Initialisation du tableau multidimensionnel. int [] étend Object (tout comme AnyType []), donc null est une valeur valide.
Paramètres
Paramètre | Détails |
---|---|
ArrayType | Type du tableau. Cela peut être primitif ( int , long , byte ) ou Objects ( String , MyObject , etc.). |
indice | Index fait référence à la position d'un certain objet dans un tableau. |
longueur | Chaque tableau, lors de sa création, nécessite une longueur définie. Ceci est soit fait lors de la création d'un tableau vide ( new int[3] ) ou implicite lors de la spécification des valeurs ( {1, 2, 3} ). |
Création et initialisation de tableaux
Cas de base
int[] numbers1 = new int[3]; // Array for 3 int values, default value is 0
int[] numbers2 = { 1, 2, 3 }; // Array literal of 3 int values
int[] numbers3 = new int[] { 1, 2, 3 }; // Array of 3 int values initialized
int[][] numbers4 = { { 1, 2 }, { 3, 4, 5 } }; // Jagged array literal
int[][] numbers5 = new int[5][]; // Jagged array, one dimension 5 long
int[][] numbers6 = new int[5][4]; // Multidimensional array: 5x4
Les tableaux peuvent être créés en utilisant n'importe quel type de primitive ou de référence.
float[] boats = new float[5]; // Array of five 32-bit floating point numbers.
double[] header = new double[] { 4.56, 332.267, 7.0, 0.3367, 10.0 };
// Array of five 64-bit floating point numbers.
String[] theory = new String[] { "a", "b", "c" };
// Array of three strings (reference type).
Object[] dArt = new Object[] { new Object(), "We love Stack Overflow.", new Integer(3) };
// Array of three Objects (reference type).
Pour le dernier exemple, notez que les sous-types du type de tableau déclaré sont autorisés dans le tableau.
Les tableaux pour les types définis par l'utilisateur peuvent également être construits de manière similaire aux types primitifs
UserDefinedClass[] udType = new UserDefinedClass[5];
Tableaux, collections et flux
// Parameters require objects, not primitives
// Auto-boxing happening for int 127 here
Integer[] initial = { 127, Integer.valueOf( 42 ) };
List<Integer> toList = Arrays.asList( initial ); // Fixed size!
// Note: Works with all collections
Integer[] fromCollection = toList.toArray( new Integer[toList.size()] );
//Java doesn't allow you to create an array of a parameterized type
List<String>[] list = new ArrayList<String>[2]; // Compilation error!
// Streams - JDK 8+
Stream<Integer> toStream = Arrays.stream( initial );
Integer[] fromStream = toStream.toArray( Integer[]::new );
Introduction
Un tableau est une structure de données contenant un nombre fixe de valeurs primitives ou des références à des instances d'objets.
Chaque élément d'un tableau est appelé un élément et chaque élément est accessible par son index numérique. La longueur d'un tableau est établie lorsque le tableau est créé:
int size = 42;
int[] array = new int[size];
La taille d'un tableau est fixée à l'exécution lors de l'initialisation. Il ne peut pas être modifié après l'initialisation. Si la taille doit être mutable à l'exécution, une classe Collection
telle ArrayList
doit être utilisée à la place. ArrayList
stocke des éléments dans un tableau et prend en charge le redimensionnement en allouant un nouveau tableau et en copiant des éléments de l'ancien tableau.
Si le tableau est de type primitif, c'est-à-dire
int[] array1 = { 1,2,3 };
int[] array2 = new int[10];
les valeurs sont stockées dans le tableau lui-même. En l'absence d'initialiseur (comme dans array2
ci-dessus), la valeur par défaut attribuée à chaque élément est 0
(zéro).
Si le type de tableau est une référence d'objet, comme dans
SomeClassOrInterface[] array = new SomeClassOrInterface[10];
le tableau contient alors des références à des objets de type SomeClassOrInterface
. Ces références peuvent faire référence à une instance de SomeClassOrInterface
ou de toute sous-classe (pour les classes) ou à la classe d'implémentation (pour les interfaces) de SomeClassOrInterface
. Si la déclaration de tableau n'a pas d'initialiseur, la valeur par défaut de null
est affectée à chaque élément.
Comme tous les tableaux sont int
-indexed, la taille d'un tableau doit être spécifiée par un int
. La taille du tableau ne peut pas être spécifiée comme un long
:
long size = 23L;
int[] array = new int[size]; // Compile-time error:
// incompatible types: possible lossy conversion from
// long to int
Les tableaux utilisent un système d' index basé sur zéro , ce qui signifie que l'indexation commence à 0
et se termine à la length - 1
.
Par exemple, l'image suivante représente un tableau de taille 10
. Ici, le premier élément est à l'indice 0
et le dernier élément à l'indice 9
, au lieu que le premier élément soit à l'indice 1
et le dernier élément à l'index 10
(voir la figure ci-dessous).
Les accès aux éléments des tableaux se font à temps constant . Cela signifie que l'accès au premier élément du tableau a le même coût (en temps) d'accès au deuxième élément, au troisième élément, etc.
Java offre plusieurs façons de définir et d'initialiser des tableaux, notamment des notations littérales et des constructeurs . Lors de la déclaration de tableaux utilisant le new Type[length]
, chaque élément sera initialisé avec les valeurs par défaut suivantes:
-
0
pour les types numériques primitifs :byte
,short
,int
,long
,float
etdouble
. -
'\u0000'
(caractère nul) pour lechar
de type. -
false
pour le typeboolean
. -
null
pour les types de référence .
Création et initialisation de tableaux de type primitif
int[] array1 = new int[] { 1, 2, 3 }; // Create an array with new operator and
// array initializer.
int[] array2 = { 1, 2, 3 }; // Shortcut syntax with array initializer.
int[] array3 = new int[3]; // Equivalent to { 0, 0, 0 }
int[] array4 = null; // The array itself is an object, so it
// can be set as null.
Lors de la déclaration d'un tableau, []
apparaîtra dans le type au début de la déclaration (après le nom du type) ou dans le déclarateur d'une variable particulière (après le nom de la variable), ou les deux:
int array5[]; /* equivalent to */ int[] array5;
int a, b[], c[][]; /* equivalent to */ int a; int[] b; int[][] c;
int[] a, b[]; /* equivalent to */ int[] a; int[][] b;
int a, []b, c[][]; /* Compilation Error, because [] is not part of the type at beginning
of the declaration, rather it is before 'b'. */
// The same rules apply when declaring a method that returns an array:
int foo()[] { ... } /* equivalent to */ int[] foo() { ... }
Dans l'exemple suivant, les deux déclarations sont correctes et peuvent être compilées et exécutées sans aucun problème. Cependant, la convention de codage Java et le guide de style Java de Google découragent tous les deux le formulaire entre parenthèses après le nom de la variable. Les crochets identifient le type de tableau et doivent apparaître avec la désignation du type . La même chose devrait être utilisée pour les signatures de retour de méthode.
float array[]; /* and */ int foo()[] { ... } /* are discouraged */
float[] array; /* and */ int[] foo() { ... } /* are encouraged */
Le type déconseillé est destiné à accueillir les utilisateurs de la transition C , qui sont familiarisés avec la syntaxe de C qui contient les crochets après le nom de la variable.
En Java, il est possible d'avoir des tableaux de taille 0
:
int[] array = new int[0]; // Compiles and runs fine.
int[] array2 = {}; // Equivalent syntax.
Cependant, comme il s’agit d’un tableau vide, aucun élément ne peut être lu ou assigné:
array[0] = 1; // Throws java.lang.ArrayIndexOutOfBoundsException.
int i = array2[0]; // Also throws ArrayIndexOutOfBoundsException.
De tels tableaux vides sont généralement utiles en tant que valeurs de retour, de sorte que le code appelant ne doit se préoccuper que du traitement d'un tableau, plutôt que d'une valeur null
potentielle pouvant mener à une NullPointerException
.
La longueur d'un tableau doit être un entier non négatif:
int[] array = new int[-1]; // Throws java.lang.NegativeArraySizeException
La taille du tableau peut être déterminée en utilisant un champ final public appelé length
:
System.out.println(array.length); // Prints 0 in this case.
Remarque : array.length
renvoie la taille réelle du tableau et non le nombre d'éléments de tableau auxquels une valeur a été attribuée, contrairement à ArrayList.size()
qui renvoie le nombre d'éléments de tableau auxquels une valeur a été attribuée.
Création et initialisation de tableaux multidimensionnels
La manière la plus simple de créer un tableau multidimensionnel est la suivante:
int[][] a = new int[2][3];
Il créera deux tableaux int
trois longueurs: a[0]
et a[1]
. Ceci est très similaire à l'initialisation classique de style C des tableaux multidimensionnels rectangulaires.
Vous pouvez créer et initialiser en même temps:
int[][] a = { {1, 2}, {3, 4}, {5, 6} };
Contrairement à C , où seuls les tableaux rectangulaires multidimensionnels sont pris en charge, les tableaux internes ne doivent pas nécessairement être de même longueur, ni même définis:
int[][] a = { {1}, {2, 3}, null };
Ici, a[0]
est un tableau int
longueur, tandis a[1]
est un tableau int
deux longueurs et a[2]
est null
. Les tableaux comme celui-ci sont appelés tableaux irréguliers ou tableaux déchiquetés , c’est-à-dire qu’ils sont des tableaux de tableaux. Les tableaux multidimensionnels en Java sont implémentés en tant que tableaux de tableaux, c'est-à-dire que le array[i][j][k]
est équivalent à ((array[i])[j])[k]
. Contrairement à C # , le array[i,j]
syntaxe array[i,j]
n'est pas pris en charge en Java.
Représentation multidimensionnelle des tableaux en Java
Création et initialisation de tableaux de type référence
String[] array6 = new String[] { "Laurel", "Hardy" }; // Create an array with new
// operator and array initializer.
String[] array7 = { "Laurel", "Hardy" }; // Shortcut syntax with array
// initializer.
String[] array8 = new String[3]; // { null, null, null }
String[] array9 = null; // null
En plus des littéraux et des primitives de String
présentés ci-dessus, la syntaxe de raccourci pour l'initialisation du tableau fonctionne également avec les types d' Object
canoniques:
Object[] array10 = { new Object(), new Object() };
Les tableaux étant covariants, un tableau de type référence peut être initialisé en tant que tableau d'une sous-classe, bien qu'une ArrayStoreException
soit émise si vous essayez de définir un élément sur autre chose qu'une String
:
Object[] array11 = new String[] { "foo", "bar", "baz" };
array11[1] = "qux"; // fine
array11[1] = new StringBuilder(); // throws ArrayStoreException
La syntaxe de raccourci ne peut pas être utilisée pour cela car la syntaxe de raccourci aurait un type implicite d' Object[]
.
Un tableau peut être initialisé avec des éléments nuls en utilisant String[] emptyArray = new String[0]
. Par exemple, un tableau comme celui-ci est utilisé pour créer un Array
partir d'une Collection
lorsque la méthode nécessite le type d'exécution d'un objet.
Dans les deux types de primitive et de référence, une initialisation de tableau vide (par exemple, String[] array8 = new String[3]
) initialisera le tableau avec la valeur par défaut pour chaque type de données .
Création et initialisation de tableaux de type générique
Dans les classes génériques, les tableaux de types génériques ne peuvent pas être initialisés comme ceci en raison de l' effacement de type :
public class MyGenericClass<T> {
private T[] a;
public MyGenericClass() {
a = new T[5]; // Compile time error: generic array creation
}
}
Au lieu de cela, ils peuvent être créés en utilisant l'une des méthodes suivantes: (notez que cela générera des avertissements non vérifiés)
En créant un tableau
Object
et en le convertissant en type générique:a = (T[]) new Object[5];
C'est la méthode la plus simple, mais comme le tableau sous-jacent est toujours de type
Object[]
, cette méthode ne fournit pas de sécurité de type. Par conséquent, cette méthode de création d'un tableau est mieux utilisée que dans la classe générique - non exposée publiquement.En utilisant
Array.newInstance
avec un paramètre de classe:public MyGenericClass(Class<T> clazz) { a = (T[]) Array.newInstance(clazz, 5); }
Ici, la classe de
T
doit être explicitement passée au constructeur. Le type de retour deArray.newInstance
est toujoursObject
. Cependant, cette méthode est plus sûre car le tableau nouvellement créé est toujours de typeT[]
et peut donc être externalisé en toute sécurité.
Remplissage d'un tableau après l'initialisation
Arrays.fill()
peut être utilisé pour remplir un tableau avec la même valeur après l'initialisation:
Arrays.fill(array8, "abc"); // { "abc", "abc", "abc" }
fill()
peut également attribuer une valeur à chaque élément de la plage spécifiée du tableau:
Arrays.fill(array8, 1, 2, "aaa"); // Placing "aaa" from index 1 to 2.
Depuis la version 8 de Java, la méthode setAll
et son équivalent Concurrent
parallelSetAll
peuvent être utilisés pour définir chaque élément d'un tableau sur des valeurs générées. Ces méthodes sont passées à une fonction de générateur qui accepte un index et renvoie la valeur souhaitée pour cette position.
L'exemple suivant crée un tableau d'entiers et définit tous ses éléments sur leur valeur d'index respective:
int[] array = new int[5];
Arrays.setAll(array, i -> i); // The array becomes { 0, 1, 2, 3, 4 }.
Déclaration séparée et initialisation des tableaux
La valeur d'un index pour un élément de tableau doit être un nombre entier (0, 1, 2, 3, 4, ...) et inférieur à la longueur du tableau (les index sont basés sur zéro). Sinon, une exception ArrayIndexOutOfBoundsException sera lancée:
int[] array9; // Array declaration - uninitialized
array9 = new int[3]; // Initialize array - { 0, 0, 0 }
array9[0] = 10; // Set index 0 value - { 10, 0, 0 }
array9[1] = 20; // Set index 1 value - { 10, 20, 0 }
array9[2] = 30; // Set index 2 value - { 10, 20, 30 }
Les tableaux ne peuvent pas être réinitialisés avec la syntaxe de raccourci de l'initialiseur de tableau
Il n'est pas possible de réinitialiser un tableau via une syntaxe de raccourci avec un initialiseur de tableau, car un initialiseur de tableau ne peut être spécifié que dans une déclaration de champ ou une déclaration de variable locale ou dans une expression de création de tableau.
Cependant, il est possible de créer un nouveau tableau et de l'assigner à la variable utilisée pour référencer l'ancien tableau. Bien que cela entraîne la ré-initialisation du tableau référencé par cette variable, le contenu de la variable est un tableau complètement nouveau. Pour ce faire, le new
opérateur peut être utilisé avec un initialiseur de tableau et affecté à la variable de tableau:
// First initialization of array
int[] array = new int[] { 1, 2, 3 };
// Prints "1 2 3 ".
for (int i : array) {
System.out.print(i + " ");
}
// Re-initializes array to a new int[] array.
array = new int[] { 4, 5, 6 };
// Prints "4 5 6 ".
for (int i : array) {
System.out.print(i + " ");
}
array = { 1, 2, 3, 4 }; // Compile-time error! Can't re-initialize an array via shortcut
// syntax with array initializer.
Création d'un tableau à partir d'une collection
Deux méthodes dans java.util.Collection
créent un tableau à partir d'une collection:
Object[] toArray()
peut être utilisé comme suit:
Set<String> set = new HashSet<String>();
set.add("red");
set.add("blue");
// although set is a Set<String>, toArray() returns an Object[] not a String[]
Object[] objectArray = set.toArray();
<T> T[] toArray(T[] a)
peut être utilisé comme suit:
Set<String> set = new HashSet<String>();
set.add("red");
set.add("blue");
// The array does not need to be created up front with the correct size.
// Only the array type matters. (If the size is wrong, a new array will
// be created with the same type.)
String[] stringArray = set.toArray(new String[0]);
// If you supply an array of the same size as collection or bigger, it
// will be populated with collection values and returned (new array
// won't be allocated)
String[] stringArray2 = set.toArray(new String[set.size()]);
La différence entre eux est plus que juste avoir des résultats non typés vs typés. Leurs performances peuvent également différer (pour plus de détails, veuillez lire cette section d'analyse des performances ):
-
Object[] toArray()
utilise unearraycopy
vectorisée, qui est beaucoup plus rapide que laarraycopy
vérifiée pararraycopy
utilisée dansT[] toArray(T[] a)
. -
T[] toArray(new T[non-zero-size])
doit mettre à zéro le tableau à l'exécution, alors queT[] toArray(new T[0])
ne le fait pas. Un tel évitement rend le dernier appel plus rapide que le premier. Analyse détaillée ici: tableaux de sagesse des anciens .
À partir de Java SE 8+, où le concept de Stream
a été introduit, il est possible d'utiliser le Stream
produit par la collection pour créer un nouveau tableau à l'aide de la méthode Stream.toArray
.
String[] strings = list.stream().toArray(String[]::new);
Exemples pris de deux réponses ( 1 , 2 ) à Convertir 'ArrayList en' String [] 'en Java sur Stack Overflow.
Tableaux à une chaîne
Depuis Java 1.5, vous pouvez obtenir une représentation String
du contenu du tableau spécifié sans itérer chaque élément. Utilisez simplement Arrays.toString(Object[])
ou Arrays.deepToString(Object[])
pour les tableaux multidimentionnels:
int[] arr = {1, 2, 3, 4, 5};
System.out.println(Arrays.toString(arr)); // [1, 2, 3, 4, 5]
int[][] arr = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
System.out.println(Arrays.deepToString(arr)); // [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
Arrays.toString()
méthode Arrays.toString()
utilise la méthode Object.toString()
pour produire les valeurs String
de chaque élément du tableau. En plus du tableau de type primitif, il peut être utilisé pour tous les types de tableaux. Par exemple:
public class Cat { /* implicitly extends Object */
@Override
public String toString() {
return "CAT!";
}
}
Cat[] arr = { new Cat(), new Cat() };
System.out.println(Arrays.toString(arr)); // [CAT!, CAT!]
S'il n'y a pas de substitution à toString()
pour la classe, alors le toString()
hérité de Object
sera utilisé. Généralement, la sortie n'est pas très utile, par exemple:
public class Dog {
/* implicitly extends Object */
}
Dog[] arr = { new Dog() };
System.out.println(Arrays.toString(arr)); // [Dog@17ed40e0]
Créer une liste à partir d'un tableau
La méthode Arrays.asList()
peut être utilisée pour renvoyer une List
taille fixe contenant les éléments du tableau donné. La List
résultante sera du même type de paramètre que le type de base du tableau.
String[] stringArray = {"foo", "bar", "baz"};
List<String> stringList = Arrays.asList(stringArray);
Remarque : cette liste est soutenue par ( une vue de) le tableau d'origine, ce qui signifie que toute modification apportée à la liste modifiera le tableau et inversement. Cependant, les modifications de la liste qui changeraient sa taille (et donc la longueur du tableau) déclencheront une exception.
Pour créer une copie de la liste, utilisez le constructeur de java.util.ArrayList
prenant une Collection
en argument:
String[] stringArray = {"foo", "bar", "baz"};
List<String> stringList = new ArrayList<String>(Arrays.asList(stringArray));
Dans Java SE 7 et versions ultérieures, une paire de crochets <>
(un ensemble vide d'arguments de type) peut être utilisée, appelée Diamond . Le compilateur peut déterminer les arguments de type à partir du contexte. Cela signifie que les informations de type peuvent être omises lors de l'appel du constructeur de ArrayList
et qu'elles seront automatiquement déduites lors de la compilation. Cela s'appelle Type Inference, qui fait partie de Java Generics .
// Using Arrays.asList()
String[] stringArray = {"foo", "bar", "baz"};
List<String> stringList = new ArrayList<>(Arrays.asList(stringArray));
// Using ArrayList.addAll()
String[] stringArray = {"foo", "bar", "baz"};
ArrayList<String> list = new ArrayList<>();
list.addAll(Arrays.asList(stringArray));
// Using Collections.addAll()
String[] stringArray = {"foo", "bar", "baz"};
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, stringArray);
Un point à noter à propos du diamant est qu'il ne peut pas être utilisé avec les classes anonymes .
// Using Streams
int[] ints = {1, 2, 3};
List<Integer> list = Arrays.stream(ints).boxed().collect(Collectors.toList());
String[] stringArray = {"foo", "bar", "baz"};
List<Object> list = Arrays.stream(stringArray).collect(Collectors.toList());
Remarques importantes relatives à l'utilisation de la méthode Arrays.asList ()
Cette méthode renvoie
List
, qui est une instance deArrays$ArrayList
(classe interne statique deArrays
) et nonjava.util.ArrayList
. LaList
résultante est de taille fixe. Cela signifie que l'ajout ou la suppression d'éléments n'est pas pris en charge et lancera uneUnsupportedOperationException
:stringList.add("something"); // throws java.lang.UnsupportedOperationException
Une nouvelle
List
peut être créée par le passage d' un tableau soutenu parList
au constructeur d'une nouvelleList
. Cela crée une nouvelle copie des données, qui a une taille modifiable et qui n'est pas soutenue par le tableau d'origine:List<String> modifiableList = new ArrayList<>(Arrays.asList("foo", "bar"));
L'appel de
<T> List<T> asList(T... a)
sur un tableau primitif, tel qu'unint[]
, produira uneList<int[]>
dont le seul élément est le tableau de primitives source au lieu des éléments réels du tableau source.La raison de ce comportement est que les types primitifs ne peuvent pas être utilisés à la place des paramètres de type générique, de sorte que le tableau primitif tout entier remplace le paramètre de type générique dans ce cas. Pour convertir un tableau primitif en
List
, tout d'abord, convertissez le tableau primitif en un tableau du type wrapper correspondant (c'est-à-dire appelezArrays.asList
sur unInteger[]
au lieu d'unint[]
).Par conséquent, cela va imprimer
false
:int[] arr = {1, 2, 3}; // primitive array of int System.out.println(Arrays.asList(arr).contains(1));
D'un autre côté, cela sera
true
:Integer[] arr = {1, 2, 3}; // object array of Integer (wrapper for int) System.out.println(Arrays.asList(arr).contains(1));
Cela imprimera également
true
, car le tableau sera interprété comme unInteger[]
):System.out.println(Arrays.asList(1,2,3).contains(1));
Tableaux multidimensionnels et dentelés
Il est possible de définir un tableau avec plusieurs dimensions. Au lieu d'être accessible en fournissant un index unique, un tableau multidimensionnel est accessible en spécifiant un index pour chaque dimension.
La déclaration du tableau multidimensionnel peut être effectuée en ajoutant []
pour chaque dimension à une valeur de décomposition de tableau régulière. Par exemple, pour créer un tableau int
dimensions, ajoutez un autre ensemble de crochets à la déclaration, par exemple int[][]
. Cela continue pour les tableaux à trois dimensions ( int[][][]
) et ainsi de suite.
Pour définir un tableau à deux dimensions avec trois lignes et trois colonnes:
int rows = 3;
int columns = 3;
int[][] table = new int[rows][columns];
Le tableau peut être indexé et lui attribuer des valeurs avec cette construction. Notez que les valeurs non attribuées sont les valeurs par défaut pour le type d'un tableau, dans ce cas 0
pour int
.
table[0][0] = 0;
table[0][1] = 1;
table[0][2] = 2;
Il est également possible d'instancier une dimension à la fois et même de créer des tableaux non rectangulaires. Celles-ci sont plus communément appelées tableaux déchiquetés .
int[][] nonRect = new int[4][];
Il est important de noter que même s’il est possible de définir une dimension de tableau irrégulier, son niveau précédent doit être défini.
// valid
String[][] employeeGraph = new String[30][];
// invalid
int[][] unshapenMatrix = new int[][10];
// also invalid
int[][][] misshapenGrid = new int[100][][10];
Comment les tableaux multidimensionnels sont représentés en Java
Source de l'image: http://math.hws.edu/eck/cs124/javanotes3/c8/s5.html
Intialisation littérale du tableau dentelé
Les tableaux multidimensionnels et les tableaux irréguliers peuvent également être initialisés avec une expression littérale. Les éléments suivants déclarent et remplissent un tableau int
2x3:
int[][] table = {
{1, 2, 3},
{4, 5, 6}
};
Remarque : Les sous-réseaux déchiquetés peuvent également être null
. Par exemple, le code suivant déclare et renseigne un tableau int
deux dimensions dont le premier sous-tableau est null
, le second sous-tableau est de longueur nulle, le troisième sous-tableau a une longueur et le dernier sous-tableau est un tableau à deux longueurs:
int[][] table = {
null,
{},
{1},
{1,2}
};
Pour les tableaux multidimensionnels, il est possible d'extraire des tableaux de dimension inférieure par leurs indices:
int[][][] arr = new int[3][3][3];
int[][] arr1 = arr[0]; // get first 3x3-dimensional array from arr
int[] arr2 = arr1[0]; // get first 3-dimensional array from arr1
int[] arr3 = arr[0]; // error: cannot convert from int[][] to int[]
ArrayIndexOutOfBoundsException
L' ArrayIndexOutOfBoundsException
est ArrayIndexOutOfBoundsException
lorsqu'un index non existant d'un tableau est en cours d'accès.
Les tableaux sont indexés sur zéro, donc l'index du premier élément est 0
et l'index du dernier élément est la capacité du tableau moins 1
(ie array.length - 1
).
Par conséquent, toute demande d'un élément de tableau par l'indice i
doit satisfaire à la condition 0 <= i < array.length
, sinon le ArrayIndexOutOfBoundsException
sera jeté.
Le code suivant est un exemple simple où une ArrayIndexOutOfBoundsException
est levée.
String[] people = new String[] { "Carol", "Andy" };
// An array will be created:
// people[0]: "Carol"
// people[1]: "Andy"
// Notice: no item on index 2. Trying to access it triggers the exception:
System.out.println(people[2]); // throws an ArrayIndexOutOfBoundsException.
Sortie:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 2
at your.package.path.method(YourClass.java:15)
Notez que l'index illégal auquel vous accédez est également inclus dans l'exception ( 2
dans l'exemple); cette information pourrait être utile pour trouver la cause de l'exception.
Pour éviter cela, vérifiez simplement que l'index est dans les limites du tableau:
int index = 2;
if (index >= 0 && index < people.length) {
System.out.println(people[index]);
}
Obtenir la longueur d'un tableau
Les tableaux sont des objets qui fournissent de l'espace pour stocker jusqu'à sa taille des éléments de type spécifié. La taille d'un tableau ne peut pas être modifiée après la création du tableau.
int[] arr1 = new int[0];
int[] arr2 = new int[2];
int[] arr3 = new int[]{1, 2, 3, 4};
int[] arr4 = {1, 2, 3, 4, 5, 6, 7};
int len1 = arr1.length; // 0
int len2 = arr2.length; // 2
int len3 = arr3.length; // 4
int len4 = arr4.length; // 7
Le champ length
d'un tableau stocke la taille d'un tableau. C'est un final
champ et ne peut pas être modifié.
Ce code indique la différence entre la length
d'un tableau et la quantité d'objets stockés par un tableau.
public static void main(String[] args) {
Integer arr[] = new Integer[] {1,2,3,null,5,null,7,null,null,null,11,null,13};
int arrayLength = arr.length;
int nonEmptyElementsCount = 0;
for (int i=0; i<arrayLength; i++) {
Integer arrElt = arr[i];
if (arrElt != null) {
nonEmptyElementsCount++;
}
}
System.out.println("Array 'arr' has a length of "+arrayLength+"\n"
+ "and it contains "+nonEmptyElementsCount+" non-empty values");
}
Résultat:
Array 'arr' has a length of 13
and it contains 7 non-empty values
Comparer les tableaux pour l'égalité
Types Array héritent leurs equals()
(et hashCode()
) implémentations de java.lang.Object , donc equals()
à equals()
ne retourne vrai lorsque l'on compare contre exactement le même objet tableau. Pour comparer les tableaux en fonction de leurs valeurs, utilisez java.util.Arrays.equals
, qui est surchargé pour tous les types de tableau.
int[] a = new int[]{1, 2, 3};
int[] b = new int[]{1, 2, 3};
System.out.println(a.equals(b)); //prints "false" because a and b refer to different objects
System.out.println(Arrays.equals(a, b)); //prints "true" because the elements of a and b have the same values
Lorsque le type d'élément est un type de référence, Arrays.equals()
appelle equals()
sur les éléments du tableau pour déterminer l'égalité. En particulier, si le type d'élément est lui-même un type de tableau, la comparaison d'identité sera utilisée. Pour comparer les tableaux multidimensionnels pour l’égalité, utilisez Arrays.deepEquals()
comme ci-dessous:
int a[] = { 1, 2, 3 };
int b[] = { 1, 2, 3 };
Object[] aObject = { a }; // aObject contains one element
Object[] bObject = { b }; // bObject contains one element
System.out.println(Arrays.equals(aObject, bObject)); // false
System.out.println(Arrays.deepEquals(aObject, bObject));// true
Étant donné que les ensembles et les cartes utilisent equals()
et hashCode()
, les tableaux ne sont généralement pas utiles en tant qu'éléments de définition ou clés de carte. Soit les envelopper dans une classe d'assistance qui implémente equals()
et hashCode()
en fonction des éléments du tableau, soit les convertir en instances List
et stocker les listes.
Tableaux à diffuser
Conversion d'un tableau d'objets en Stream
:
String[] arr = new String[] {"str1", "str2", "str3"};
Stream<String> stream = Arrays.stream(arr);
La conversion d'un tableau de primitives en Stream
aide d' Arrays.stream()
transformera le tableau en une spécialisation primitive de Stream:
int[] intArr = {1, 2, 3};
IntStream intStream = Arrays.stream(intArr);
Vous pouvez également limiter le Stream
à une série d'éléments du tableau. L'index de démarrage est inclusif et l'index de fin est exclusif:
int[] values = {1, 2, 3, 4};
IntStream intStream = Arrays.stream(values, 2, 4);
Une méthode similaire à Arrays.stream()
apparaît dans la classe Stream
: Stream.of()
. La différence est que Stream.of()
utilise un paramètre varargs, vous pouvez donc écrire quelque chose comme:
Stream<Integer> intStream = Stream.of(1, 2, 3);
Stream<String> stringStream = Stream.of("1", "2", "3");
Stream<Double> doubleStream = Stream.of(new Double[]{1.0, 2.0});
Itération sur les tableaux
Vous pouvez effectuer une itération sur les tableaux en utilisant des améliorations pour les boucles (aka foreach) ou en utilisant des index de tableaux:
int[] array = new int[10];
// using indices: read and write
for (int i = 0; i < array.length; i++) {
array[i] = i;
}
// extended for: read only
for (int e : array) {
System.out.println(e);
}
Il convient de noter qu’il n’ya pas de moyen direct d’utiliser un Iterator sur un tableau, mais qu’il peut être facilement converti en une liste pour obtenir un objet Iterable
via la bibliothèque Arrays.
Pour les tableaux en boîte, utilisez Arrays.asList :
Integer[] boxed = {1, 2, 3};
Iterable<Integer> boxedIt = Arrays.asList(boxed); // list-backed iterable
Iterator<Integer> fromBoxed1 = boxedIt.iterator();
Pour les tableaux primitifs (utilisant java 8), utilisez des flux (en particulier dans cet exemple - Arrays.stream -> IntStream ):
int[] primitives = {1, 2, 3};
IntStream primitiveStream = Arrays.stream(primitives); // list-backed iterable
PrimitiveIterator.OfInt fromPrimitive1 = primitiveStream.iterator();
Si vous ne pouvez pas utiliser les flux (pas de Java 8), vous pouvez choisir d'utiliser la bibliothèque de goyave de Google:
Iterable<Integer> fromPrimitive2 = Ints.asList(primitives);
Dans les tableaux à deux dimensions ou plus, les deux techniques peuvent être utilisées de manière un peu plus complexe.
Exemple:
int[][] array = new int[10][10];
for (int indexOuter = 0; indexOuter < array.length; indexOuter++) {
for (int indexInner = 0; indexInner < array[indexOuter].length; indexInner++) {
array[indexOuter][indexInner] = indexOuter + indexInner;
}
}
for (int[] numbers : array) {
for (int value : numbers) {
System.out.println(value);
}
}
Il est impossible de définir un tableau sur une valeur non uniforme sans utiliser une boucle basée sur un index.
Bien sûr, vous pouvez également utiliser des boucles while
ou do-while
lors d'une itération à l'aide d'indices.
Une note de prudence: lorsque vous utilisez des indices de tableau, assurez-vous que l'index est compris entre 0
et array.length - 1
(tous deux inclus). Ne faites pas d'hypothèses codées sur la longueur du tableau, sinon vous risquez de casser votre code si la longueur du tableau change, mais pas vos valeurs codées en dur.
Exemple:
int[] numbers = {1, 2, 3, 4};
public void incrementNumbers() {
// DO THIS :
for (int i = 0; i < numbers.length; i++) {
numbers[i] += 1; //or this: numbers[i] = numbers[i] + 1; or numbers[i]++;
}
// DON'T DO THIS :
for (int i = 0; i < 4; i++) {
numbers[i] += 1;
}
}
Il est également préférable que vous n'utilisiez pas de calculs fantaisistes pour obtenir l'index mais que vous utilisiez l'index pour effectuer des itérations et que si vous avez besoin de valeurs différentes, calculez-les.
Exemple:
public void fillArrayWithDoubleIndex(int[] array) {
// DO THIS :
for (int i = 0; i < array.length; i++) {
array[i] = i * 2;
}
// DON'T DO THIS :
int doubleLength = array.length * 2;
for (int i = 0; i < doubleLength; i += 2) {
array[i / 2] = i;
}
}
Accéder aux tableaux dans l'ordre inverse
int[] array = {0, 1, 1, 2, 3, 5, 8, 13};
for (int i = array.length - 1; i >= 0; i--) {
System.out.println(array[i]);
}
Utilisation de tableaux temporaires pour réduire la répétition du code
Itérer sur un tableau temporaire au lieu de répéter le code peut rendre votre code plus propre. Il peut être utilisé lorsque la même opération est effectuée sur plusieurs variables.
// we want to print out all of these
String name = "Margaret";
int eyeCount = 16;
double height = 50.2;
int legs = 9;
int arms = 5;
// copy-paste approach:
System.out.println(name);
System.out.println(eyeCount);
System.out.println(height);
System.out.println(legs);
System.out.println(arms);
// temporary array approach:
for(Object attribute : new Object[]{name, eyeCount, height, legs, arms})
System.out.println(attribute);
// using only numbers
for(double number : new double[]{eyeCount, legs, arms, height})
System.out.println(Math.sqrt(number));
Gardez à l'esprit que ce code ne doit pas être utilisé dans les sections critiques, car un tableau est créé chaque fois que la boucle est entrée et que les variables primitives sont copiées dans le tableau et ne peuvent donc pas être modifiées.
Copier des tableaux
Java propose plusieurs méthodes pour copier un tableau.
pour la boucle
int[] a = { 4, 1, 3, 2 };
int[] b = new int[a.length];
for (int i = 0; i < a.length; i++) {
b[i] = a[i];
}
Notez que l'utilisation de cette option avec un tableau Object au lieu d'un tableau primitif remplira la copie en référence au contenu d'origine plutôt qu'à sa copie.
Object.clone ()
Puisque les tableaux sont des Object
en Java, vous pouvez utiliser Object.clone()
.
int[] a = { 4, 1, 3, 2 };
int[] b = a.clone(); // [4, 1, 3, 2]
Notez que la méthode Object.clone
pour un tableau effectue une copie superficielle , c.-à-d. Object.clone
renvoie une référence à un nouveau tableau qui référence les mêmes éléments que le tableau source.
Arrays.copyOf ()
java.util.Arrays
fournit un moyen simple d'effectuer la copie d'un tableau sur un autre. Voici l'utilisation de base:
int[] a = {4, 1, 3, 2};
int[] b = Arrays.copyOf(a, a.length); // [4, 1, 3, 2]
Notez que Arrays.copyOf
fournit également une surcharge qui vous permet de changer le type du tableau:
Double[] doubles = { 1.0, 2.0, 3.0 };
Number[] numbers = Arrays.copyOf(doubles, doubles.length, Number[].class);
System.arraycopy ()
public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
Copie un tableau du tableau source spécifié, en commençant à la position spécifiée, à la position spécifiée du tableau de destination.
Ci-dessous un exemple d'utilisation
int[] a = { 4, 1, 3, 2 };
int[] b = new int[a.length];
System.arraycopy(a, 0, b, 0, a.length); // [4, 1, 3, 2]
Arrays.copyOfRange ()
Principalement utilisé pour copier une partie d'un tableau, vous pouvez également l'utiliser pour copier un tableau entier vers un autre, comme ci-dessous:
int[] a = { 4, 1, 3, 2 };
int[] b = Arrays.copyOfRange(a, 0, a.length); // [4, 1, 3, 2]
Bâtis de coulée
Les tableaux sont des objets, mais leur type est défini par le type des objets contenus. Par conséquent, on ne peut pas simplement convertir A[]
en T[]
, mais chaque membre du A[]
spécifique doit être converti en un objet T
Exemple générique:
public static <T, A> T[] castArray(T[] target, A[] array) {
for (int i = 0; i < array.length; i++) {
target[i] = (T) array[i];
}
return target;
}
Ainsi, étant donné un tableau A[]
:
T[] target = new T[array.Length];
target = castArray(target, array);
Java SE fournit la méthode Arrays.copyOf(original, newLength, newType)
à cet effet:
Double[] doubles = { 1.0, 2.0, 3.0 };
Number[] numbers = Arrays.copyOf(doubles, doubles.length, Number[].class);
Supprimer un élément d'un tableau
Java ne fournit pas de méthode directe dans java.util.Arrays
pour supprimer un élément d'un tableau. Pour l'exécuter, vous pouvez soit copier le tableau d'origine sur un nouveau sans l'élément pour supprimer ou convertir votre tableau dans une autre structure permettant la suppression.
Utiliser ArrayList
Vous pouvez convertir le tableau en java.util.List
, supprimer l'élément et convertir la liste en un tableau comme suit:
String[] array = new String[]{"foo", "bar", "baz"};
List<String> list = new ArrayList<>(Arrays.asList(array));
list.remove("foo");
// Creates a new array with the same size as the list and copies the list
// elements to it.
array = list.toArray(new String[list.size()]);
System.out.println(Arrays.toString(array)); //[bar, baz]
Utiliser System.arraycopy
System.arraycopy()
peut être utilisé pour faire une copie du tableau d'origine et supprimer l'élément souhaité. Ci-dessous un exemple:
int[] array = new int[] { 1, 2, 3, 4 }; // Original array.
int[] result = new int[array.length - 1]; // Array which will contain the result.
int index = 1; // Remove the value "2".
// Copy the elements at the left of the index.
System.arraycopy(array, 0, result, 0, index);
// Copy the elements at the right of the index.
System.arraycopy(array, index + 1, result, index, array.length - index - 1);
System.out.println(Arrays.toString(result)); //[1, 3, 4]
Utiliser Apache Commons Lang
Pour supprimer facilement un élément, vous pouvez utiliser la bibliothèque Apache Commons Lang et en particulier la méthode statique removeElement()
de la classe ArrayUtils
. Ci-dessous un exemple:
int[] array = new int[]{1,2,3,4};
array = ArrayUtils.removeElement(array, 2); //remove first occurrence of 2
System.out.println(Arrays.toString(array)); //[1, 3, 4]
Covariance des tableaux
Les tableaux d'objets sont covariants, ce qui signifie que, tout comme Integer
est une sous-classe de Number
, Integer[]
est une sous-classe de Number[]
. Cela peut sembler intuitif, mais peut entraîner un comportement surprenant:
Integer[] integerArray = {1, 2, 3};
Number[] numberArray = integerArray; // valid
Number firstElement = numberArray[0]; // valid
numberArray[0] = 4L; // throws ArrayStoreException at runtime
Bien que Integer[]
soit une sous-classe de Number[]
, il ne peut contenir que des Integer
s, et essayer d’attribuer un élément Long
génère une exception d’exécution.
Notez que ce comportement est unique pour les tableaux et peut être évité en utilisant une List
générique à la place:
List<Integer> integerList = Arrays.asList(1, 2, 3);
//List<Number> numberList = integerList; // compile error
List<? extends Number> numberList = integerList;
Number firstElement = numberList.get(0);
//numberList.set(0, 4L); // compile error
Il n'est pas nécessaire que tous les éléments du tableau partagent le même type, tant qu'ils constituent une sous-classe du type de tableau:
interface I {}
class A implements I {}
class B implements I {}
class C implements I {}
I[] array10 = new I[] { new A(), new B(), new C() }; // Create an array with new
// operator and array initializer.
I[] array11 = { new A(), new B(), new C() }; // Shortcut syntax with array
// initializer.
I[] array12 = new I[3]; // { null, null, null }
I[] array13 = new A[] { new A(), new A() }; // Works because A implements I.
Object[] array14 = new Object[] { "Hello, World!", 3.14159, 42 }; // Create an array with
// new operator and array initializer.
Object[] array15 = { new A(), 64, "My String" }; // Shortcut syntax
// with array initializer.
Comment changez-vous la taille d'un tableau?
La réponse simple est que vous ne pouvez pas faire cela. Une fois qu'un tableau a été créé, sa taille ne peut plus être modifiée. Au lieu de cela, un tableau ne peut être "redimensionné" qu'en créant un nouveau tableau avec la taille appropriée et en copiant les éléments du tableau existant vers le nouveau.
String[] listOfCities = new String[3]; // array created with size 3.
listOfCities[0] = "New York";
listOfCities[1] = "London";
listOfCities[2] = "Berlin";
Supposons (par exemple) qu'un nouvel élément listOfCities
être ajouté au tableau listOfCities
défini ci-dessus. Pour ce faire, vous devrez:
- créer un nouveau tableau de taille 4,
- copier les 3 éléments existants de l'ancien tableau dans le nouveau tableau aux décalages 0, 1 et 2, et
- ajouter le nouvel élément au nouveau tableau à l'offset 3.
Il y a plusieurs façons de faire ce qui précède. Avant Java 6, le moyen le plus concis était le suivant:
String[] newArray = new String[listOfCities.length + 1];
System.arraycopy(listOfCities, 0, newArray, 0, listOfCities.length);
newArray[listOfCities.length] = "Sydney";
A partir de Java 6, les méthodes Arrays.copyOf
et Arrays.copyOfRange
peuvent le faire plus simplement:
String[] newArray = Arrays.copyOf(listOfCities, listOfCities.length + 1);
newArray[listOfCities.length] = "Sydney";
Pour d'autres moyens de copier un tableau, reportez-vous à l'exemple suivant. Gardez à l'esprit que vous devez disposer d'une copie de tableau de longueur différente de l'original lors du redimensionnement.
Une meilleure alternative au redimensionnement de tableau
Il y a deux inconvénients majeurs à redimensionner un tableau comme décrit ci-dessus:
- C'est inefficace. Pour agrandir un tableau (ou le rendre plus petit), copiez tous les éléments de tableau existants ou tous les allouez et allouez un nouvel objet de tableau. Plus la matrice est grande, plus elle est chère.
- Vous devez pouvoir mettre à jour toutes les variables "live" contenant des références à l'ancien tableau.
Une alternative consiste à créer le tableau avec une taille suffisante pour commencer. Ceci n'est viable que si vous pouvez déterminer cette taille avec précision avant d'allouer le tableau . Si vous ne pouvez pas faire cela, le problème de redimensionnement du tableau se pose à nouveau.
L'autre solution consiste à utiliser une classe de structure de données fournie par la bibliothèque de classes Java SE ou une bibliothèque tierce. Par exemple, la structure «collections» de Java SE fournit un certain nombre d'implémentations des API List
, Set
et Map
avec différentes propriétés d'exécution. La classe ArrayList
se rapproche le plus des caractéristiques de performance d'un tableau brut (par exemple, recherche O (N), obtention et définition de O (1), insertion et suppression aléatoires O (N)) tout en offrant un redimensionnement plus efficace.
(L'efficacité du redimensionnement pour ArrayList
provient de sa stratégie consistant à doubler la taille de la matrice de sauvegarde sur chaque redimensionnement. Dans le cas d'un cas typique, cela signifie que vous ne redimensionnez que occasionnellement. par insert est O(1)
. Il peut être possible d'utiliser la même stratégie lors du redimensionnement d'un tableau brut.)
Trouver un élément dans un tableau
Il existe plusieurs façons de trouver l’emplacement d’une valeur dans un tableau. Les exemples de code suivants supposent tous que le tableau est l'un des suivants:
String[] strings = new String[] { "A", "B", "C" };
int[] ints = new int[] { 1, 2, 3, 4 };
De plus, chacun définit l' index
ou l' index2
sur l'index de l'élément requis ou sur -1
si l'élément n'est pas présent.
Utiliser Arrays.binarySearch
(pour les tableaux triés uniquement)
int index = Arrays.binarySearch(strings, "A");
int index2 = Arrays.binarySearch(ints, 1);
Utiliser un Arrays.asList
(pour les tableaux non primitifs uniquement)
int index = Arrays.asList(strings).indexOf("A");
int index2 = Arrays.asList(ints).indexOf(1); // compilation error
Utiliser un Stream
int index = IntStream.range(0, strings.length)
.filter(i -> "A".equals(strings[i]))
.findFirst()
.orElse(-1); // If not present, gives us -1.
// Similar for an array of primitives
Recherche linéaire en boucle
int index = -1;
for (int i = 0; i < array.length; i++) {
if ("A".equals(array[i])) {
index = i;
break;
}
}
// Similar for an array of primitives
Recherche linéaire en utilisant des bibliothèques tierces telles que org.apache.commons
int index = org.apache.commons.lang3.ArrayUtils.contains(strings, "A");
int index2 = org.apache.commons.lang3.ArrayUtils.contains(ints, 1);
Remarque: L'utilisation d'une recherche linéaire directe est plus efficace que le regroupement dans une liste.
Tester si un tableau contient un élément
Les exemples ci-dessus peuvent être adaptés pour tester si le tableau contient un élément en testant simplement pour voir si l’indice calculé est supérieur ou égal à zéro.
Il existe également des variantes plus concises:
boolean isPresent = Arrays.asList(strings).contains("A");
boolean isPresent = Stream<String>.of(strings).anyMatch(x -> "A".equals(x));
boolean isPresent = false;
for (String s : strings) {
if ("A".equals(s)) {
isPresent = true;
break;
}
}
boolean isPresent = org.apache.commons.lang3.ArrayUtils.contains(ints, 4);
Tri des tableaux
Le tri des tableaux peut être facilement effectué avec l’API des tableaux .
import java.util.Arrays;
// creating an array with integers
int[] array = {7, 4, 2, 1, 19};
// this is the sorting part just one function ready to be used
Arrays.sort(array);
// prints [1, 2, 4, 7, 19]
System.out.println(Arrays.toString(array));
Tri des tableaux de chaînes:
String
n'est pas une donnée numérique, il définit son propre ordre appelé ordre lexicographique, également appelé ordre alphabétique. Lorsque vous triez un tableau de String en utilisant la méthode sort()
, il trie le tableau dans l'ordre naturel défini par l'interface Comparable, comme indiqué ci-dessous:
Ordre croissant
String[] names = {"John", "Steve", "Shane", "Adam", "Ben"};
System.out.println("String array before sorting : " + Arrays.toString(names));
Arrays.sort(names);
System.out.println("String array after sorting in ascending order : " + Arrays.toString(names));
Sortie:
String array before sorting : [John, Steve, Shane, Adam, Ben]
String array after sorting in ascending order : [Adam, Ben, John, Shane, Steve]
Ordre décroissant
Arrays.sort(names, 0, names.length, Collections.reverseOrder());
System.out.println("String array after sorting in descending order : " + Arrays.toString(names));
Sortie:
String array after sorting in descending order : [Steve, Shane, John, Ben, Adam]
Tri d'un tableau d'objets
Afin de trier un tableau d'objets, tous les éléments doivent implémenter l'interface Comparable
ou Comparator
pour définir l'ordre du tri.
Nous pouvons utiliser l'une des méthodes sort(Object[])
pour trier un tableau d'objets dans son ordre naturel, mais vous devez vous assurer que tous les éléments du tableau doivent implémenter Comparable
.
De plus, ils doivent également être mutuellement comparables, par exemple e1.compareTo(e2)
ne doit pas lancer une ClassCastException
pour les éléments e1 et e2 du tableau. Vous pouvez également trier un tableau d'objets sur un ordre personnalisé en utilisant la méthode de sort(T[], Comparator)
, comme illustré dans l'exemple suivant.
// How to Sort Object Array in Java using Comparator and Comparable
Course[] courses = new Course[4];
courses[0] = new Course(101, "Java", 200);
courses[1] = new Course(201, "Ruby", 300);
courses[2] = new Course(301, "Python", 400);
courses[3] = new Course(401, "Scala", 500);
System.out.println("Object array before sorting : " + Arrays.toString(courses));
Arrays.sort(courses);
System.out.println("Object array after sorting in natural order : " + Arrays.toString(courses));
Arrays.sort(courses, new Course.PriceComparator());
System.out.println("Object array after sorting by price : " + Arrays.toString(courses));
Arrays.sort(courses, new Course.NameComparator());
System.out.println("Object array after sorting by name : " + Arrays.toString(courses));
Sortie:
Object array before sorting : [#101 Java@200 , #201 Ruby@300 , #301 Python@400 , #401 Scala@500 ]
Object array after sorting in natural order : [#101 Java@200 , #201 Ruby@300 , #301 Python@400 , #401 Scala@500 ]
Object array after sorting by price : [#101 Java@200 , #201 Ruby@300 , #301 Python@400 , #401 Scala@500 ]
Object array after sorting by name : [#101 Java@200 , #301 Python@400 , #201 Ruby@300 , #401 Scala@500 ]
Conversion de tableaux entre les primitives et les types en boîte
Parfois, la conversion de types primitifs en types encadrés est nécessaire.
Pour convertir le tableau, il est possible d'utiliser des flux (en Java 8 et plus):
int[] primitiveArray = {1, 2, 3, 4};
Integer[] boxedArray =
Arrays.stream(primitiveArray).boxed().toArray(Integer[]::new);
Avec des versions inférieures, cela peut être en itérant le tableau primitif et en le copiant explicitement dans le tableau encadré:
int[] primitiveArray = {1, 2, 3, 4};
Integer[] boxedArray = new Integer[primitiveArray.length];
for (int i = 0; i < primitiveArray.length; ++i) {
boxedArray[i] = primitiveArray[i]; // Each element is autoboxed here
}
De même, un tableau en boîte peut être converti en un tableau de son homologue primitif:
Integer[] boxedArray = {1, 2, 3, 4};
int[] primitiveArray =
Arrays.stream(boxedArray).mapToInt(Integer::intValue).toArray();
Integer[] boxedArray = {1, 2, 3, 4};
int[] primitiveArray = new int[boxedArray.length];
for (int i = 0; i < boxedArray.length; ++i) {
primitiveArray[i] = boxedArray[i]; // Each element is outboxed here
}