Cet article décrit comment utiliser les tableaux en langage Java. Seul seront traités les tableaux à une dimension. Les tableaux à plusieurs dimensisons seront traités dans un article spécifique.
Comme dans la plupart des langages, Java permet de gérer un groupe de données de même types sous forme de tableau dont chaque élément est accessible à partir d’un indice. Dans cette première partie, nous aborderons les tableaux à une dimension.
En Java, le type Tableau n’est pas une classe et pourtant, une instance de Tableau est bien un objet qui hérite de java.lang.Object, il est créé sur le tas à partir de l’opérateur new et on y accède par une référence.
Les tableaux implémentent les interfaces Serializable et Clonable et redéfinissent la méthode clone(). Contrairement aux collections, ils ne peuvent pas être redimensionnés une fois créés mais un tableau peut contenir aussi bien des objets que des types primitifs
Pour déclarer un tableau, on définit un type comme pour une variable de base, auquel on ajoute des crochets ouvrant et fermant pour indiquer qu’il s’agit d’un tableau.
Création d’un tableau de types primitifs
Pour créer un tableau dont on connaît sa taille, il est possible de le préciser au moment de sa déclarations.
Pour un tableau devant contenir 10 entiers, vous pourrez utiliser la syntaxe suivante :
Dans le cas d’un programme dont la taille du tableau n’est connue qu’à l’exécution, vous pouvez déclarer et initialiser la taille du tableau en 2 temps comme suit :
Création d’un tableau d’objets
Pour créer un tableau de String, la syntaxe est identique :
Imaginez que vous ayez créé une classe Personne, vous allez pouvoir créer un tableau de 10 personnes comme suit :
Remarque : Lors de la déclaration d’un tableau, Java autorise une syntaxe de type C mais cette dernière est déconseillée car considérée comme moins clair, ce qui donne :String s[] ; pour un tableau de chaînes.
Pour connaître la taille d’un tableau, ces derniers disposent d’un attribut publique length qu’il suffit de lire.
Exemple pour connaître la taille d’un tableau t :
Remarque : L’attribut length est final c’est à dire non modifiable, ce qui est logique puisqu’un tableau ne peut être redimensionné une fois créé.
Les instructions précédentes ont créées des tableaux de 10 cellules mais ces dernières ne contiennent aucune valeur de définies.
Remarque : En fait, les cellules non initialisées contiennent une valeur par défaut qui dépend du type. Une cellule d’entier aura la valeur zero et une cellule devant contenir un objet aura la valeur null par exemple.
On accède en lecture et en écriture à un tableau en spécifiant le n° de la cellule entre crochets avec un indice allant de 0 à la (taille - 1) du tableau.
Affecter une valeur à une cellule
Affecter une valeur à la première cellule d’un tableau d’entiers :
Pour affecter un objet dans un tableau, il faut utiliser l’opérateur new avec un constructeur si l’objet n’a pas été créé auparavant :
ou en 2 temps :
Initialiser le contenu d’un tableau lors de sa création
Lorsque l’on connaît les valeurs d’un tableau au moment de sa déclaration, nous n’avons pas besoin de spécifier sa taille et on peut utiliser la syntaxe suivante :
On peut également créer un tableau anonyme avec la syntaxe suivante :
Ces 2 syntaxes sont utilisables avec des tableaux d’objets en n’oubliant pas d’appeler les constructeurs pour chaque valeur.
Lire le contenu d’une cellule
Pour lire le contenu d’une cellule, il suffit de connaître son indice.
Lire la 3ième cellule d’un tableau d’entier par exemple :
Pour un objet :
On aura souvent besoin d’accéder séquentiellement aux cellules d’un tableau soit pour l’initialiser, soit pour le lire.
A l’aide d’une boucle for
L’exemple suivant montre comment initialiser l’ensemble d’un tableau à l’aide d’une boucle for :
A l’aide d’une boucle for each
Lorsque dans la boucle, on n’a pas besoin de connaître l’indice de chaque élément à traiter, on peut utiliser la syntaxe de type for each (depuis Java 5).
L’exemple suivant montre comment afficher à l’écran l’ensemble des éléments du tableau d’entiers :
L’avantage de cette écriture, est que nous n’avons pas besoin de spécifier le nombre d’éléments du tableau, ce qui peut éviter des erreurs.
A l’aide d’un stream et d’un lambda
Depuis Java 8, nous pouvons utiliser les tableaux en tant que streams. On peut donc écrire l’équivalent de l’exemple précédent comme ceci :
Une fois un tableau transformé en stream, il est possible de faire des opérations sur l’ensemble comme, par exemple, le calcul de la moyenne d’un tableau de chiffres. Exemple :
Remarque : Voir paragraphe suivant pour plus d’informations sur la classe Arrays utilisée dans cet l’exemple.
La classe Arrays (avec un s à ne pas confondre avec le type Array) fournit plusieurs méthodes statiques pour réaliser des actions sur des tableaux comme la recherche, le tris etc… Plusieurs de ces méthodes seront utilisées dans les exemples qui vont suivre.
Il peut être utile de transformer un tableau en une chaîne de caractères, par exemple pour afficher son contenu dans une console pour lors de tests. On pourrait faire cela à partir d’une boucle mais voyons comment obtenir ce résultat à partir d’une seule instruction.
Si nous initialisons le tableau suivant :
et si nous écrivons le code suivant :
A l’execution, nous obtenons l’affichage suivant qui n’est pas satisfaisant.
Pour afficher le contenu du tableau, nous allons utiliser une méthode de la calsse Arrays.
Ce qui donne :
ATTENTION : La méthode Arrays.toString() utilise la méthode toString() de chaque élément lorsqu’il s’agit d’objets. Vous devrez donc ne pas oublier de la redéfinir dans vos propres classes.
Si le type d’affichage proposé par défaut ne nous conviens pas, depuis Java 8 nous pouvons utiliser la méthode String.join()
qui nous permet de choisir le séparateur comme dans l’exemple suivant :
Ce qui donne :
Cas particulier des tableaux de char
Pour les tableaux de char, il est possible d’afficher le contenu directement :
qui affiche :
Utilisation de l’opérateur égal avec les tableaux
Comme les tableaux sont des objets créés sur le tas (opérateur new), si vous utilisez l’opérateur =, vous obtiendrez 2 références sur un même tableau.
Prenons l’exemple suivant :
t1[ 0 ] aura la même valeur que t2[ 0 ] car les 2 variables font références au même tableau en mémoire du fait de l’utilisation de l’opérateur égal.
Utilisation de la méthode clone()
Les tableaux sont clonable et redéfinissent la méthode clone() que l’on peut donc utiliser pour créer une copie de tableau.
Reprenons le cas d’un tableau d’entiers.
L’exemple précédent montre bien que nous avons à faire à 2 tableaux différents.
Remarque : Avant Java 5, vous auriez été obligé de transtyper le tableau retourné par la méthode clone().
Cas des tableaux d’objets
Nous pourrons également utiliser la méthode clone() pour les tableaux d’objets. Il faudra simplement se souvenir que chaque cellule du second tableau contiendra une référence sur le même objet que la cellule correspondante du premier tableau (pas de copie profonde). Donc, si vous réinitialisez un nouvel objet dans la cellule du second tableau, la cellule correspondante du premier tableau ne sera pas modifiée et il n’y aura pas d’effet de bord, par contre, si vous modifiez les propriétés d’un objet à partir d’un tableau venant d’être copié, vous modifierez également l’objet référencé par le second tableau.
L’exemple suivant crée un premier tableau avec 2 objets modifiables. On copie ce premier tableau dans un second à l’aide de clone() , puis on modifie un des objet contenu dans la cellule du premier tableau.
Que l’on accède à partir du premier ou du second tableau, c’est un même objet qui est modifié. Les tableaux sont bien différents et leurs cellules sont bien dupliquées mais chacune contient une valeur identique qui est la référence sur un même objet.
Remarque : Si vous utilisez des tableaux d’objets immuables comme des String ou LocalDate, vous n’aurez pas ce risque puisque par définition, ce sont de nouveaux objets qui sont créés en cas de modification.
Remarque : Les tableaux peuvent être dupliqués même lorsqu’ils contiennent des objet non clonable du fait que la duplication n’effectue pas de copie profonde. Dans le cas d’objets, il n’y a que les références qui sont dupliquées.
Pour ne copier qu’un groupe d’éléments d’un tableau dans un autre, Java fournit la méthode suivante :
System.ArrayCopy( tableauSource, posDepart, tableauDestination, posDepart, nbElementsACopier );
Exemple :
Affiche :
Cette méthode est très pratique car elle permet d’utiliser le même tableau comme source et destination pour, par exemple décaler les valeurs de cellules.
L’exemple suivant décale les valeur de 1 vers la gauche comme si l’on supprimait la première cellule :
Affiche :
Il est possible d’obtenir un tableau de char à partir d’une chaine de caractère en utilisant la méthode toCharArray()
Exemple :
Arrays.fill( tableau, valeur );
On peut également ne remplir qu’une partie du tableau en indiquant le premier indice de cellule et le dernier non compris.
Arrays.fill( tableau, indiceDebut, indiceFin, valeur );
Exemple :
Affiche :
Dans certains cas, on peut avoir besoin d’utiliser des méthodes qui manipulent des collections alors que nos données se trouvent dans un tableau. Pour utiliser ce dernier comme une liste, on peut utiliser la méthode suivante :
Arrays.asList( tableau )
ATTENTION : Cette méthode ne duplique pas les données dans une liste, elle permet simplement d’utiliser le tableau comme une liste.
Exemple :
La classe Arrays fournit plusieurs méthodes de tris permettant de trier différents types de données basées sur l’algorithme QuickSort.
Arrays.sort( tableau ).
Trier un tableau de types primitifs
Pour trier des tableaux de types primitifs, vous pourrez utiliser les méthodes correspondantes :
Arrays.sort( byte[] t );
Arrays.sort( char[] t );
etc...
Exemple de tri d’un tableau d’entiers :
Affiche :
Trier un tableau d’objets
Les principales méthodes, pour trier des tableaux d’objets sont :
Arrays.sort( Object[] t );
Arrays.sort T[], Comparator< ? super T > c );
Votre tableau devra contenir des objets implémentant des l’interface Comparable si vous utilisez la première méthode sinon, vous devrez utiliser la seconde méthode avec un objet Comparator.
L’exemple suivant montre une tentative de tris avec un tableau d’objets non comparables :
qui affichera l’erreur suivante :
Si nous désirons trier le tableau de personnes d’après leurs noms, nous pourrons utiliser la seconde méthode en définissant un Comparator comme dans l’exemple suivant :
En Java 8 on peut écrire l’appel à la méthode de tri de manière plus concise avec un lambda. Ce qui donne :
La méthode de recherche d’un élément dans un tableau est :
Arrays.binarySearch( tableau, recherche ): int
Si la valeur est trouvée, la méthode renvoi son indice dans le tableau, sinon renvoi une valeur négative.
ATTENTION : Le tableau doit être trié.
Exemple :
Affiche :
En ce qui concerne la recherche dans un tableau d’objets, ce dernier devra être trié donc les objets devront être comparables ou alors, utiliser la méthode suivante en spécifiant le Comparator.
Arrays.binarySearch( T[], T clé, Comparator< ? super T > c );
Passage de paramètres
Les tableaux peuvent être passés en paramètres de méthodes mais vous ne pouvez pas définir une taille lors de la déclaration de la méthode. Vous devrez donc ajouter du code à l’intérieur de la méthode pour tester le nombre d’éléments du tableau.
Exemple :
L’exemple précédent peut être remplacée par une méthode avec un nombre de paramètres variables puisque ces derniers se retrouvent dans un tableau dans la méthode.
Exemple :
Remarque : Même avec la seconde syntaxe, il sera possible d’appeler la méthode en lui passant un tableau sous la forme d’un tableau anonyme.
Tableau en retour d’une méthode
Une méthode peut très bien renvoyer un tableau qui pourra être d’une taille quelconque.
Remarques générales sur les tableaux et méthodes
Les tableaux étant des objets, que ce soit en tant que paramètres ou de valeurs de retour d’une méthode, il s’agit bien de références qui sont utilisées et les règles et comportements sont les mêmes que pour les instances de classes.
Les tableaux étant des objets, ils héritent bien d’une méthode equals() mais qui se contente, comme l’opérateur == de ne tester que les références et non pas le contenu du tableau. Il faudra donc utiliser la méthode Arrays.equals() pour tester si 2 tableaux différents sont égaux.
Exemple :
affiche :
Les types Tableaux héritent de Object et implémentent les interfaces Cloneable et Serializable donc, tout tableau peut être converti dans un de ces trois types.
Dans le cas de tableaux d’objets, vous pourrez également transtyper un type tableau dans un type parent
Par exemple, le type String implémente l’interface Comparable. On peut donc écrire le code suivant :
Nous venons de voir les principales possibilités des tableaux à une dimensions en langage Java.
Dans un autre paragraphe nous traiterons des tableaux à plusieurs dimensions qui ne sont en fait que des tableaux de tableaux mais qui ont quelques méthodes spécifiques pour leurs traitement.
Crée par: chris
Créé le: 16 août 2017
Modifié le: 13 avril 2018
Nombre de visites: 8642
Popularité: 6 %
Popularité absolue: 1
2003-2024 LePpf
Plan du site
| Se connecter |
RSS 2.0 |
Sur YouTube
Visiteurs connectés : 2
Nombre moyen de visites quotidiennes sur le site: 265