6.    Tableaux et listes



6.1    Introduction

Ensemble d’éléments de même type désignés par un nom unique. Chaque élément est accédé directement et il est repéré par un indice.

Fig. 6.1 Tableau de dix éléments


int tE[];   - référence

6.2    Création et initialisation de tableaux

tE = new int[5] ; // tE fait référence à un tableau de 5 entiers



Fig. 6.2 Déclaration d'un tableau

int tE[] ;        int [] tE ;

int [] tE1, tE2 ; // tE1 et tE2 sont des références à des tableaux d’entiers
est équivalent à :
int tE1[], tE2[] ;

int tE1[], n, tE2[] ; // tE1 et tE2 sont des tableaux d’entiers, n est entier.

Person tp[] = new Person [10];
Lors de la déclaration d’une référence de tableau, on peut fournir une liste d’expressions entre accolades, comme dans :
char voyelle[ ] = {'a', 'e', 'i', 'o', 'u'}; // un tableau de cinq éléments.
int n;

int tb[ ] = { 10,2*n, 14, n+5}; //un tableau de quatre éléments.

int tE[5] ; // erreur : on ne peut pas indiquer de dimension ici.
tb = { 10,2*n, 14, n+5}; // erreur, l'initialisation  n’est utilisable que dans une déclaration.

6.3    Utilisation de tableaux

length
public class Tab {
    public static void main(String arg[]){
        char vowel[] = {'a','e','i','o','u'};
        System.out.println ("number of vowel elements: "+vowel.length);
    }
}

element access
public class Tab1 {
    public static void main(String arg[]){
        char vowel[] = {'a','e','i','o','u'};
        System.out.println("vowel elements:");
        for(int i=0;i < vowel.length;i++){
            System.out.print ("\t"+vowel[i]);
        }
        System.out.println();
    }
}

Structure de contrôle adaptée aux collections  for ... each (ne s’applique qu’à des consultations de valeurs)
public class Tab2 {
    public static void main(String arg[]){
        char vowel[] = {'a','e','i','o','u'};
        System.out.println("vowel elements:");
        for(char v:vowel){
            System.out.print ("\t"+v);
        }
        System.out.println();
    }
}

System.arraycopy(source,début_Source, destination, début_Destination,longueur);
public class Vowl {
    public static void main(String arg[]){
        char vowel[] = {'a','e','i','o','u'};
        System.out.println("vowel elements:");
        for(char v:vowel){
            System.out.print ("\t"+v);
        }
        System.out.println();
        char tmp[] = new char[vowel.length+1];
        System.arraycopy(vowel, 0, tmp, 0, vowel.length);
        tmp[tmp.length-1]= 'y';
        vowel = tmp;
        System.out.println("vowel elements:");
        for(char v:vowel){
            System.out.print ("\t"+v);
        }
        System.out.println();
    }
}


Fig. 6.3 Affectation des deux références du tableau


6.4    Tableaux multidimensionnels


Fig. 6.4 Un tableau à deux dimensions de deux lignes et d’un nombre variable de colonnes.

Les déclarations suivantes sont équivalentes.
int tab[][];
int [] tab [];
int [][] tab;

Matrice créée avec new
public class Matrix {
    public static void main(String arg[]){
        int matrix[][] = new int[3][6];
        for(int line[]:matrix ){                     // for ... each
            for (int k : line){                     //for … each
                System.out.print("\t"+k);
            }
            System.out.println();
        }
    }
}

Matrice avec initialisation
public class Matrix1 {
    public static void main(String arg[]){
        int matrix[][] = {{1,2*3,7},{6,8,9}};
        for(int line[]:matrix ){
            for (int k : line){
                System.out.print("\t"+k);
            }
            System.out.println();
        }
    }
}

Tableau irrégulier
public class Tabl {
    public static void main(String arg[]){
        int ex[][] = new int[3][ ];
        ex[0] = new int [3];
        ex[1] = new int[5];
        ex[2] = new int[4];
        for(int line[]:ex ){
            for (int k : line){
                System.out.print("\t"+k);
            }
            System.out.println();
        }
    }
}

Avec l'initialisation
public class Tabl1 {
    public static void main(String arg[]){
        int ex[][] = {{1,2,3},{4,5,6,7},{8,9}};
        for(int line[]:ex ){
            for (int k : line){
                System.out.print("\t"+k);
            }
            System.out.println();
        }
    }
}

Lorsqu’on transmet un nom de tableau en argument, ou en retour d’une méthode, on transmet en fait (une copie de) la référence au tableau. La méthode agit alors directement sur le tableau concerné et non sur une copie.
Méthode statique pour modifier les valeurs

public class Tabl2 {
    public static void main(String arg[]){
        int ex[][]={{1,2,3},{4,5,6,7},{8,9}};
        init(ex);
        for(int line[]:ex ){
            for (int k : line){
                System.out.print("\t"+k);
            }
            System.out.println();
        }
    }
    public static void init(int tb[][]){
        for(int i=0;i<tb.length;i++){
            for(int j =0; j<tb[i].length;j++){
                tb[i][j]=(int)(Math.random()*10);
            }
        }
    }
}

Les référenses des lignes du tableau peuvent changer pendant l'exécution du programme
public class Tab_ir {
    public static void main(String arg[]){
        int tab[][] = new int[3][2];
        prt(tab);
        tab[1] = new int [4];
        prt(tab);
    }
    public static void prt(int tab[][]){
        System.out.println("\ntab:");
        for(int line[]:tab ){
            for (int k : line){
                System.out.print("\t"+k);
            }
            System.out.println();
        }       
    }
}

6.5    Les tableaux d'objets

class Birthday
public class Birthday {
    private int day,month,year;
    public Birthday(int d, int m, int y){
        this.day = d;
        this.month=m;
        this.year = y;
    }
    public String toString(){
        return "("+day+","+month+","+year+")";
    }
}

Birthday tab[] = new Birthday[2];


Fig. 6.5 Tableau de deux références nulle

Pour créer des objets il faut appeler le constructeur pour chaque référence:
tab[0] = new Birthday(7, 7, 1980);
tab[1] = new Birthday(20, 12, 1984);


Fig. 6.6 Tableau de deux objets

On peut l'initier le tableau lors de sa déclaration
Birthday tab[] = {new Birthday(7,7,1980, new Birthday(20,12,1984)};

Exemples

Тableau unidimensionnel

public class Tab1 {
    public static void main(String[] arg) {
        Birthday[] bd1= {new Birthday(8,12,2001),new Birthday(3,4,1978)},
                  bd2= new Birthday[2];

        System.out.print("bd1: ");
        for(Birthday b:bd1) {
            System.out.print("\t"+b);           
        }
        System.out.println();
        System.out.print("bd2: ");
        for(Birthday b:bd2) {
            System.out.print("\t"+b);           
        }
        System.out.println();
        bd2[0]=new Birthday(9,1,2000);
        bd2[1]=new Birthday(4,3,1976);
        System.out.print("bd2: ");
        for(Birthday b:bd2) {
            System.out.print("\t"+b);           
        }
    }
}

Тableau à deux dimensions

public class Tab {
    public static void main(String arg[]){
        Birthday bd[][]=new Birthday[3][4];
        init(bd);
        for(Birthday line[]:bd ){
            for (Birthday k : line){
                System.out.print("\t"+k);
            }
            System.out.println();
        }
    }
    public static void init(Birthday tb[][]){
        int months[][]= {{1,3,5,7,8,10,12},   //31 days
                                 {4,6,9,11} };        //30 days
        for(int i=0;i<tb.length;i++){
            for(int j =0; j<tb[i].length;j++){
                int year = (int)(Math.random()*80+1940); // from 1940 to 2019
                int month = (int)(Math.random()*12+1);    // from 1 to 12
                int day;
                if (in(months,month)==0) {
                    day=(int)(Math.random()*31+1);         // from 1 to 31
                }
                else if(in(months,month)==1) {
                    day=(int)(Math.random()*30+1);       // from 1 to 30                  
                }
                else if (year%400==0||(year%4==0)&&(year%100!=0)) {
                    day=(int)(Math.random()*29+1);     // from 1 to 29 leap year
                }
                else {
                    day=(int)(Math.random()*28+1);     // from 1 to 28
                }
                tb[i][j]=new Birthday(day,month,year);
            }
        }
    }
    public static int in(int months[][], int crmonth) { //in line 0 - 31 days
        for (int i =0;i<months.length;i++) {            //in line 1 - 30 days
            for(int j=0;j<months[i].length;j++) {
                if (crmonth == months[i][j]){
                    return i;
                }
            }           
        }
        return -1;  // not found
    }
}

6.6    Les lists  (dans java.util)

Une liste est une collection d'objets qui est par définition une collection ordonnée, également connue en tant que séquence. Contrairement au tableau, le nombre d'éléments dans la liste peut être réduit ou agrandi.

Une collection Liste ne peut contenir  que des objets.

Il existe deux implémentations de liste à usage général - ArrayList et LinkedList. Le plus utilisée, est ArrayList. Elle offre un accès en temps constant de position, et elle peut profiter de System.arraycopy quand on doit déplacer plusieurs éléments en même temps.

List<Object> listOfObjects = new ArrayList<Object>(); 

class Person{
            ...
        }
        class Student extends Person{
            ...
        }
        List<Person> listOfPersons = new ArrayList<Person>();

Utilisation

Exemple
import java.util.*;
public class ListDemo {
   public static void main(String args[]) {
      // Create an array list
      ArrayList <String>  al = new ArrayList <String>();
      System.out.println("initial size:"+al.size());
      // add elements to the array list
      al.add("C");
      al.add("A");
      al.add("E");
      al.add("B");
      al.add("D");
      al.add("F");
      System.out.println("the new size:"+al.size());
      for(int i = 0; i <al.size(); i++){
         System.out.println(al.get(i));
      }
     String ex = al.remove (2);
     System.out.println("removing value:"+ex);
     System.out.println("size after remove:"+al.size());
     for(int i = 0; i <al.size(); i++){
         System.out.println(al.get(i));
     }
   }
}
initial size:0
the new size:6
C
A
E
B
D
F
removing value:E
size after remove:5
C
A
B
D
F

Vous pouvez consulter davantage d'informations sur les méthodes de classe  ici.

Iterateurs

  Pour parcourir une ArrayList on peut utiliser aussi des iterateurs. Il y deux types d'iterateur - Iterator et ListIterator. 

Iterator est un objet en Java qui permet de parcourir les éléments d'une collection.  Iterator est disponible pour toutes les implémentations de Collections, telles que List et Set. Il permet d'accéder aux éléments d'une collection de manière séquentielle sans connaître sa structure sous-jacente.
Il est construit à l'aide de la méthode ArrayList -  Iterator<E> iterator()

et offre trois méthodes principales : 

On ne peut parcourir une collection que dans le sens direct à l'aide d'un Iterator.

ListIterator n'est utilisé que pour les listes. Il est construit à l'aide de la méthode ArrayList - ListIterator<E> listIterator()

Il est plus puissant et offre  des méthodes suivantes:



Exemples:

import java.util.*;
public class IteratorDemo {
    public static void main(String arg[]){
        // Create an array list
          ArrayList <String>  al = new ArrayList <String>();
          // add elements to the array list
          al.add("C");
          al.add("A");
          System.out.println("ArrayList:"+al.get(0)+" "+al.get(1));
         
          ListIterator<String> litr = al.listIterator();
         /* litr.set("new");             error- there is no element in the iterator
                              returned by litr.next() or litr.previous() */         
          System.out.println("next index "+litr.nextIndex());
          System.out.println("previos index "+litr.previousIndex());
         
          System.out.println(litr.next());
          System.out.println("next index "+litr.nextIndex());
          System.out.println("previous index "+litr.previousIndex());
         
          litr.set("modified");     // modify the last element returned
                                          // by next() or previous()
          System.out.println("ArrayList:"+al.get(0)+" "+al.get(1));
         
    }
}

import java.util.*;
public class IteratorDemo {
   public static void main(String args[]) {
      // Create an array list
      ArrayList <String>  al = new ArrayList <String>();
      // add elements to the array list
      al.add("C");
      al.add("A");
      al.add("E");
      al.add("B");
      al.add("D");
      al.add("F");

      // Use iterator to display contents of al
      System.out.print("Original contents of al: ");
      Iterator<String> itr = al.iterator();
      while(itr.hasNext()) {
         String element = itr.next();
         System.out.print(element + " ");
      }
      System.out.println();
     
      // Modify objects being iterated
      ListIterator<String> litr = al.listIterator();
      while(litr.hasNext()) {
         String element = litr.next();
         litr.set(element + "+");
      }
      System.out.print("Modified contents of al: ");
      itr = al.iterator();
      while(itr.hasNext()) {
         String element = itr.next();
         System.out.print(element + " ");
      }
      System.out.println();

      // Now, display the list backwards
      System.out.print("Modified list backwards: ");
      while(litr.hasPrevious()) {
         String element = litr.previous();
         System.out.print(element + " ");
       }
       System.out.println();
    }
}

Pour plus d'information consultez Iterate through List in Java