Java, les bases


Les tableaux en Java (2)

Les tableaux à plusieurs dimensions

Montre l’utilisation des tableaux à plusieurs dimensions en langage Java.

Le langage Java permet de définir des tableaux de dimensions quelconques. Voyons comment les déclarer et comment les utiliser.


 Introduction

Dans l’article Les tableaux en Java (1) ont été présentés les tableaux à une dimension en Java. Nous allons maintenant voir l’utilisation de tableaux de dimensions quelconques. Dans les grandes lignes, ce qui a été dit dans ce précédent article reste valable dans la mesure ou en Java, les tableaux multi-dimensionnels ne sont que des tableaux de tableaux. Nous allons donc voir maintenant comment les déclarer et les utiliser et vous montrer quelques fonctions spécifiques disponible dans l’API.

 Création d’un tableau à plusieurs dimensions

Pour créer une matrice de 3 x 3 entiers, on pourra la définir comme suit :

  1. int[][] t = new int[ 3 ][ 3 ];

La ligne précédente déclare et initialise en mémoire un tableau de 3 élements contenant l’adresse de 3 autres tableaux de 3 éléments. ce qui donne :

Comme pour les tableaux à une dimension, on peut le créer et l’initialiser à partir d’un litéral :

  1. int[][] t = { { 0, -2 }, { 32, 6 } };

On poura également utiliser un initialiseur anonyme. Dans l’exemple suivant, on passe le tableau à une fonction :

  1. foncTest2( new int[][] { { 0, -2 }, { 32, 6 } } );

On peut également définir des tableaux à plusieurs dimensions non rectangulaires :

  1. int[][] t = {
  2.     { 1, 2, 3, 4, 5 },
  3.     { 1, 2 },
  4.     { 1, 2, 3, 4, 5, 6 }
  5. };

Télécharger

Bien sur, on peut définir des tableaux aux nombre de dimensions quelconques. Il suffit d’ajouter des crochets supplémentaires comme dans l’exemple suivant :

  1. int[] [] [] multi = new int[ 4 ] [ 2 ] [ 10 ];

 Ecrire et lire une cellule d’un tableau multi-dimensionnel

Pour écrire dans une cellule, nous utilisons autant d’indices entre crochets que de dimensions. Pour notre matrice de 3 x3 du premier exemple, nous pouvons écrire :

  1. t[ 0 ] [1 ] = 2; //met la valeur 2 dans la seconde colonne de la première ligne.

Pour lire, nous faisons l’inverse :

  1. valeur = t[ 0 ][ 1 ];

 Itération sur un tableau multi-dimensionnel

Prenons le tableau suivant :

  1. int[][] t = {
  2.         { 10, 23, 3, 14, -5 },
  3.         { 1, 2 },
  4.         { 13, 12, 31, -41, -5, 61 }
  5. };

Télécharger

Avec une boucle for :

  1. for ( int i = 0; i < t.length; i++ )
  2.                 {
  3.                         for ( int j = 0; j < t[ i ].length; j++ )
  4.                         {
  5.                                 System.out.println( String.format( "t[ %d ][ %d ] =  %d", i, j, t[ i ][ j ] ) );
  6.                         }
  7.                         System.out.println();
  8.                 }

Télécharger

Qui affiche :

Si nous n’utilisons pas les indices dans la boucle, nous pouvons utiliser une boucle de type foreach :

  1. for ( int[] rows: t )
  2.                 {
  3.                         for ( int col: rows )
  4.                         {
  5.                                 System.out.print( Integer.toString( col ) + " " );
  6.                         }
  7.                         System.out.println();
  8.                 }

Télécharger

qui affiche :

En Java 8 nous pouvons utiliser les streams et lambda sur un tableau multi-dimensionnel. L’exemple suivant montre comment balayer l’ensemble des cellules du tableau :

  1. Arrays.stream( t ).flatMapToInt( tableau -> Arrays.stream( tableau) )
  2.                         .forEach( cel -> System.out.print( Integer.toString( cel ) + " ") );

Télécharger

qui affiche :

 Transformer un tableau multi-dimensionnel en chaine

Si nous utilisons la même méthode que pour un objet à une dimensions nous aurons le code suivant :

  1. int[][] t = new int[ 3 ][ 3 ];
  2. System.out.println( Arrays.toString( t ) );

Télécharger

qui affiche :

Ce qui n’est pas ce que nous souhaitons. Comme les tableaux multi-dimensionnels sont des tableaux de tableaux, cette méthode renvoi le contenu du premier tableau qui ne contient que les adresses des 3 sous-tableaux.

Il faut donc utiliser une méthode spécifique à ce type de tableaux qui est :

Arrays.deepToString()
  1. System.out.println( Arrays.deepToString( t ) );

Ce qui donne :

 Tester l’égaliter d’un tableau multi-dimensionnel

Prenons l’exemple des tableaux suivant :

  1. int[][] t1 = { { 1, 2 }, { 3, 4 } };
  2. int[][] t2 = { { 1, 2 }, { 3, 4 } };

Télécharger

Ecrivons le test suivant :

  1. System.out.println( "t1.equals( t2 ) -> " + t1.equals( t2 ) );

Ce qui donne :

Comme pour les tableaux à une dimension, cette méthode ne conviens pas pour comparer 2 tableaux distincts. Utilisons donc la méthode Arrays.equals() comme pour les tableaux à une dimension :

  1. System.out.println( "Arrays.equals( t1, t2 ) -> " + Arrays.equals( t1, t2 ) );

qui donne :

qui renvoi également false.

C’est parce que là encore nous avons à faire à un tableau multi-dimensionnel qui ne tcompare que le premier niveau de chaque tableau. Si nous affichons leur contenu :

  1. System.out.println( "t1 = " + Arrays.toString( t1 ) );
  2. System.out.println( "t2 = " + Arrays.toString( t2 ) );

Télécharger

Nous obtenons :

Nous voyons que leur contenu est différent puisqu’ils ne contiennent pas de valeurs mais les adresses des différents sous-tableaux.

Là encore, nous devons utiliser une méthode spécifique :

Arrays.deepEquals()
  1. System.out.println( "Arrays.deepEquals( t1, t2 ) -> " + Arrays.deepEquals( t1, t2 ) );

qui nous donne bien :

 Conclusion

Nous n’avons pas vu la totalité des fonctions spécifiques aux tableaux multi-dimensionnel. Par exemple, il y a la méthode Arrays.deepHashCode() qui remplace dans ce cas la méthode Arrays.hashCode().

Plus généralement vous pourriez vous demander dans quel cas il vaut mieux utiliser des tableaux et dans quels cas utiliser des Collections, (par exemple le type ArrayList) qui supportent le redimmensionnement dynamique. Les collections ne gèrent pas les types primitifs mais il suffit d’utiliser des classes wrapper correspondantes (Integer pour un int par exemple) sachant que depuis Java 5, le transtypage est implicite. Je pense néanmoins que lorsque l’on a besoin de faire des calculs sur des tableaux de tailles fixes de chiffres, le type tableau est plus pratique et plus efficace, car les cellules contiennent directement les valeurs et non pas des adresses sur des objets.


Article n° 98

Crée par: chris

Créé le: 1er septembre 2017

Modifié le: 1er septembre 2017

Nombre de visites: 666

Popularité: 14 %

Popularité absolue: 3

Mots clés de cet article


SPIP

2003-2019 LePpf
Plan du site | | Contact | RSS 2.0

Visiteurs connectés : 3

Nombre moyen de visites quotidiennes sur le site: 276