Un tableau est un objet rassemblant un nombre donné de variables déclarées d'un même type et installées consécutivement en mémoire ; ces variables sont appelées les éléments du tableau ; le nombre d'éléments, appelé la longueur du tableau, est représenté par le champ length du tableau ; ce champ est non modifiable ; un tableau de longueur nulle est dit vide.
À tout type correspond un type de tableaux obtenu en suffixant [] à son nom : par exemple, les types int[] des tableaux d'entiers, String[] des tableaux de chaînes de caractères, int[][] des tableaux de tableaux d'entiers. Les tableaux ne sont pas des valeurs, mais des objets qui n'existent dans la mémoire que s'ils sont créés. La déclaration d'une variable de type tableau ne crée pas de tableau :
int[] a;
Un tableau est créé grâce à l'opérateur
new[]. L'expression spécifiant la longueur, entre les crochets «
[ » et « ] », doit être de type int (ou
d'un sous-type de int), et n'est pas nécessairement constante ;
sa valeur doit être positive ou nulle. Les éléments d'un tableau sont
toujours initialisés à la valeur nulle de leur type
(figure ).
La valeur de cette expression est une référence au tableau créé : il s'agit d'une nouvelle sorte de valeur, différente des valeurs primitives. Comme toute valeur, celle-ci peut être affectée à une variable, qui doit avoir été déclarée de type int[] :
int[] t = new int[4];
Cette définition déclare t comme un nom dont le type est «
tableau de int» ; l'évaluation de new int[4] crée
un objet qui comporte un bloc de mémoire pouvant contenir quatre
int ; enfin, t est initialisé par une référence à cet
objet, et chacun de ses quatre éléments est initialisé à 0
(figure ).
Il est aussi possible de définir un tableau en initialisant
explicitement ses éléments, comme dans l'exemple suivant qui initialise
a[0] à 1, a[1] à 2, etc.
(figure ) :
int[] a = new int[] {1, 2, 3, 4}; int[] a = {1, 2, 3, 4}; // FORME SIMPLIFIÉE
La seconde forme ne peut être employée que lors de la définition d'une
variable ; la première forme, new []
{
... }
, est une expression de type [] qui
définit et initialise un tableau anonyme
et peut être employée dans d'autres contextes qu'une initialisation, par
exemple en argument d'une fonction.
Les éléments d'un tableau sont toujours accédés par indexation à partir
de zéro : les quatre éléments du tableau a sont a[0],
a[1], a[2] et a[3]. Ces
a[], et plus généralement
a[exp], pour une expression arithmétique
exp de type int (ou d'un sous-type de int),
sont des variables désignant les éléments du tableau, et peuvent donc
être le membre gauche d'une affectation :
int k = ...; a[k+1] = 12;
C'est une erreur de tenter d'accéder à un élément hors des bornes du tableau (par exemple a[-4], a[4]). Cette tentative déclenche à l'exécution l'exception ArrayIndexOutOfBoundsException.
Un tableau, une fois défini, ne peut pas être redimensionné : on ne peut
pas lui ajouter ou lui retirer des éléments, ni affecter une valeur à
son champ length. C'est pourquoi le type
java.util.List (voir § ), qui n'a pas cette
limitation, est fréquemment utilisé à la place d'un type tableau.
Cependant, la longueur d'un tableau n'a pas à être connue à la
compilation (ce qui est une contrainte des tableaux en Pascal, C et
C++) ; on peut définir un tableau dont la longueur, puis les éléments,
sont lus sur l'entrée standard en cours d'exécution, ou encore dont la
longueur est calculée à l'exécution, par une fonction quelconque :
double[] t = new double[f(n)];
Tous les tableaux sont à allocation dynamique.
static double sommerÉléments(double[] a) { double somme = 0; for (int i=0; i<a.length; i++) { somme += a[i]; } return somme; } static double[] tableauAléatoire(int n) { double[] b = new double[n]; for (int i=0; i<b.length(); i++) { b[i] = Math.random(); } return b; } public static void main (String[] args) { double[] t = tableauAléatoire(10) double s = sommerÉléments(t); // ... }
Le tableau argument est passé par valeur ; or, la valeur de cet argument est une référence à un tableau ; c'est cette référence qui sert à initialiser le paramètre correspondant, lors de l'invocation de la fonction. Ceci permet à la fonction de modifier les éléments du tableau. Par exemple, on échange la valeur de deux éléments d'un tableau par :
static void échangerÉléments(int[] a, int m, int n) { int v = a[m] ; a[m] = a[n] ; a[n] = v; } public static void main (String[] args) { int[] a = new int[] {1, 2, 3, 4, 5, 6}; échangerÉléments(a, 2, 4); // a = {1, 2, 5, 4, 3, 6} // ... }
Il est souvent commode d'utiliser un tableau pour rassembler plusieurs valeurs de retour d'une fonction, quand ces valeurs sont de même nature et que leur nombre n'est pas connu. Par exemple, si l'on demande de calculer les solutions réelles d'une équation, on pourra retourner ces solutions dans un tableau :
static double[] solutions(...) { ... }
Une invocation de cette fonction aura la forme suivante :
static double[] racines = solutions( ... );
Si la fonction solutions crée un tableau dont la longueur est le nombre de solutions, on peut alors accéder à ce nombre par racines.length et, selon cette valeur, aux racines éventuelles racines[0], racines[1], etc.
[][]
. La déclaration du nom du
tableau ne crée aucun objet :
int[][] t;
Deux niveaux de création sont nécessaires :
t = new int[2][];
crée un tableau de longueur 2, dont les éléments sont des références à des
tableaux de int, ces éléments étant initialisés à
null. Ensuite, une boucle permet de créer chacune des lignes
du tableau bidimensionnel, les éléments de chaque ligne étant initialisés à
0 (figure ) :
for (int i=0; i<t.length; i++) t[i] = new int[3];
On accède à ses éléments par double indexation : t[0][0], t[0][1] et t[0][2] pour la première ligne, t[1][0], t[1][1] et t[1][2] pour la seconde. Comme t est un tableau, une indexation partielle est admise : les expressions t[0] et t[1] désignent des tableaux de longueur 3. Ces deux niveaux de création peuvent être effectués en une seule fois, par l'affectation suivante, qui crée un tableau rectangulaire à 2 lignes et 3 colonnes, dont tous les éléments sont nuls :
t = new int[2][3];
Il est aussi possible de créer des tableaux non rectangulaires, chaque ligne ayant son nombre d'éléments :
for (int i=0; i<t.length; i++) t[i] = new int[i+1];
Enfin, on peut créer un tableau bidimensionnel en initialisant explicitement ses éléments de la façon suivante :
t = new int[][] { new int[] {1, 2, 3}, new int[] {4, 5, 6} };
Lors de la définition d'un nom, le constructeur new int[][] peut être omis :
int[][] t = { {1, 2, 3}, {4, 5, 6} };
Il est également facile de construire un tableau avec des lignes de longueurs différentes :
t = new int[][] { new int[] {1}, new int[] {2, 3}, new int[] {4, 5, 6} };