précédent | suivant | table des matières | s'évaluer |
|
La classe ArrayList implémente un tableau d’objets
qui peut grandir ou rétrécir à la demande, ce qui débarrasse le programmeur de
la gestion de la taille du tableau. Comme pour un tableau on peut accéder à un
élément du ArrayList, par un indice.
Les éléments de la liste tableau sont représentés dans un tableau d'objets de type
E : elementData, qui
sont tous tassés en tête du tableau dans les élément d’indice 0 à size
nombre d’éléments présents dans le ArrayList.
Une instance de ArrayList contenant quatre objets peut être représentée de la façon suivante : |
Lorsque le tableau est plein (size == taille du tableau), et qu’on veut ajouter un élément dans le tableau, le tableau est agrandi : la nouvelle taille est l’ancienne taille *3/2 plus 1.
Insertion d'un élément, dans un ArrayList qui contient 4 éléments et qui est déjà plein : le tableau elementData est agrandi. | |
Après ajout, la taille de elementData est 4*3/2+1 = 7 |
public class ArrayList<E> extends AbstractList<E> implementsList<E>, RandomAccess, Cloneable, java.io.Serializable{ private transient E[] elementData;>
private int size; . . .
1 Constructeurs
Le constructeur suivant construit un ListeTableau avec sa capacité initiale :
public ArrayList(int capacityInitial) { super(); if(capacityInitial<0) throw new IllegalArgumentException("capacityInitial : " +capacityInitial) elementData = (E[])new Object[capacityInitial]; size = 0; }
Le constructeur par défaut construit un ListeTableau de 10 emplacements.
public ArrayList() { this(10); }
Le constructeur suivant permet de construire un ArrayList à partir d'une collection d'objets qui sont de la classe E ou d'une sous-classe de E :
public ArrayList(Collection<? extends E> c) {
size = c.size();
// On se donne 10% de plus pour grandir dans le futur
elementData = (E[])new Object[
(int)Math.min((size*110L)/100,Integer.MAX_VALUE)];
c.toArray(elementData);
}
2 Les méthodes de l'interface Collection :
La méthode add ajoute un élément au ArrayList la méthode appelle la méthode ensureCapacity, qui vérifie qu’il y a de la place pour réaliser l’ajout, et s’il n’y a pas de place agrandit le tableau. La méthode ensureCapacity pouvant servir à un utilisateur de la classe, elle est publique.
public void ensureCapacity(capaciteMin){ // assure que la capacité du tableau représentant les éléments // est au moins de capaciteMin int ancienneCapacite = elementData.length; if (capaciteMin > ancienneCapacite) { E [] ad = elementData; int nouvelleCapacity = ancienneCapacite * 3 / 2 + 1; if(nouvelleCapacity < capaciteMin) nouvelleCapacity = capaciteMin; elementData = (E[])new Object[nouvelleCapacity]; System.arraycopy(ad, 0, elementData, 0, size); } }
La méthode add ajoute un élément en fin de tableau :
public boolean add(E o){ ensureCapacity(size+1); elementData[size++] = o; return true; }
La méthode clear enlève tous les éléments du vecteur, size retourne le nombre d’éléments du ArrayList et isEmpty retourne vrai si et seulement si le ArrayListest vide :
public void clear(){ for( int i = 0; i< nbElements; ++i) elementData = null; size = 0; }
public int size(){return size;}
public boolean isEmpty(){ return size ==0; }
La méthode contains retourne true si o appartient au ArrayList et false sinon :
public boolean contains(Object o){ return indexOf(o)!=-1; }
La méthode remove enlève la première occurrence de o du ArrayList, si elle existe et dans ce cas retourne true, sinon la méthode retourne false : dans le cas où l’élément est enlevé, il faut « retasser » le ArrayList :
public boolean remove(Object o){ if(o == null){ for (int index = 0; index < size; index++) if (elementData[index] == null) { fastRemove(index); return true; } }else{ for (int index = 0; index < size; index++) if (o.equals(elementData[index])){ fastRemove(index); return true; } } return false; }
private void fastRemove(int index) {
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index, numMoved);
elementData[--size] = null; // le Garbage Collector peut éventuellement récupérer l'espace
}
Les deux méthodes suivantes convertissent un ArrayList en un tableau d’Object :
public Object [] toArray(){ Object [] resultat = new Object[size]; System.arraycopy(elementData, 0, resultat, 0, size); return resultat; }
La méthode suivante, copie tous les éléments du ArrayList dans le tableau t et retourne ce tableau si celui ci estassez grand, sinon ellecopie les éléments dans un tableau qui est créé et le retourne.
public <T> T[] toArray(T[] t) { if (t.length < size) t = (T[])java.lang.reflect.Array.newInstance(t.getClass().getComponentType(),size); System.arraycopy(elementData, 0, t, 0, size); if (t.length > size) t[size] = null; return t; }
Parmi les opérations de masse, seule la méthode addAll est redéfinie, pour profiter de l'optimisation due au arraycopy :
public boolean addAll(Collection<? extends E> c) { Object[] a = c.toArray(); int numNew = a.length; ensureCapacity(size + numNew); System.arraycopy(a, 0, elementData, size, numNew); size += numNew; return numNew != 0; }
3 Les méthodes de l'interface List :
La méthode suivante permet d’ajouter un élément à un indice donné dans le ArrayList :
public void add(int index, Object o){
if( index < 0 || index > size) throw new IndexOutOfBoundsException();
ensureCapacity( size + 1);
// déplacement des elements d’indice >= index
System.arraycopy(elementData, index, elementData, index+1,size - index );
elementData[index] = o;
++size;
}
La méthode get retourne l’élément se trouvant à un indice, ou lève une exception :
public Object get(int index){ if(index < 0 || index >= nbElements) throw new IndexOutOfBoundsException(); return elementData[index]; }
Les deux méthodes suivantes retournent l’indice d’un objet dans le ArrayList s’il est présent, -1 sinon. indexOf commence au début du ArrayList et lastIndexOf commence à la fin du vecteur :
public int indexOf(Object elem) { if (elem == null) { for (int i = 0; i < size; i++) if(elementData[i]==null) return i; }else { for (int i = 0; i < size; i++) if (elem.equals(elementData[i])) return i; } return -1; } |
public int lastIndexOf(Object elem) { if (elem == null){ for (int i = size-1; i >= 0; i--) if(elementData[i]==null) return i; }else{ for (int i = size-1; i >= 0; i--) if (elem.equals(elementData[i])) return i; } return -1; } |
La méthode Object remove(int index) permet d’enlever du ArrayList l’élément se trouvant à l’indice index si celuici est correct, et retourne l’objet enlevé du ArrayList :
public E remove(int index){ if( index < 0 || index >= size) throw new IndexOutOfBoundsException(); E o = elementData[index]; System.arraycopy(elementData, index+1, elementData, index, size - index - 1); elementData[ size - 1]=null; --size; return o; }
La méthode Object set(int index, Object o) modifie l’objet se trouvant en position index dans le vecteur, en lui affectant o, et retourne l’objet qui occupait cette place avant.
public e set(int index, e o){ if( index < 0 || index >= size)>throw new IndexOutOfBoundsException(); E x = elementData[index]; elementData[index] = o; return x; }
4 Méthode propres à ArrayList
TrimToSize ajuste la capacité du ArrayList à son nombre d'éléments.
public void trimToSize(){ int ancienneCapacity = elementData.length; if(nbElements < ancienneCapacity) { E[] oldData = elementData; elementData = (E[])newObject[size]; System.arraycopy(oldData, 0, elementData,0, nbElements); } }