précédent | suivant | table des matières

AbstractList

Sommaire
  1. Les méthodes abstraites
  2. Les méthodes optionnelles
  3. Les autres méthodes
  4. Implémentation des itérateurs
  5. La méthode subList
  6. La méthode equals

La classe abstraite AbstractList implémente certaines des nouvelles fonctionnalités de l’interface List. Ces nouvelles fonctionnalités sont des méthodes avec indice. Elles supposent que la structure sous-jacente servant à représenter la liste est une structure à accès direct par indice (tableau). Pour implanter un conteneur avec une liste chaînée, on utilisera plutôt la classe abstraite AbstractSequentialList

public abstract class AbstractList<E> 
      extends AbstractCollection<E>  
      implements List<E>

1 Les méthodes abstraites :

abstract public E get(int index);

2 Les méthodes optionnelles (à définir dans les sous-classes qui le souhaitent):

  
 
   public void add(int index, E element) {
         throw new UnsupportedOperationException();
   }
   public E set(int index, E element) {
        throw new UnsupportedOperationException();
   }
   
   public E remove(int index) {
        throw new UnsupportedOperationException();
   }
   

3 Les autres méthodes :

   public boolean add(E o) {
      add(size(), o);
      return true;
   }

   
Les méthodes indexOf :
   public int indexOf(Object o) {
       ListIterator<E> e = listIterator();
       if (o==null) {
           while (e.hasNext())
           if (e.next()==null)
               return e.previousIndex();
       } else {
           while (e.hasNext())
           if (o.equals(e.next()))
               return e.previousIndex();
       }
       return -1;
   }
   public int lastIndexOf(Object o) {
       ListIterator<E> e = listIterator(size());
       if (o==null) {
           while (e.hasPrevious())
           if (e.previous()==null)
               return e.nextIndex();
       } else {
           while (e.hasPrevious())
             if (o.equals(e.previous()))
                 return e.nextIndex();
       }
       return -1;
   }
Les opérations ensemblistes :
   public void clear() {
         for (Iterator<E> it = Iterator(); it.hasNext(); ){ 
            it.next();
            it.remove();
         }
   }
   public boolean addAll(int ind, Collection<? extends E> c) {
        boolean modifie = false;
        Iterator<? extends E> e = c.iterator();
        while (e.hasNext()) {
            add(index++, e.next());
            modifie = true;
         }
        return modifie;
   }

4 Implémentation des itérateurs :

   public Iterator<E> iterator() {
        return Itr();
   }

La classe imbriquée Itr implémente l’interface Iterator, et est définie de la façon suivante :


private  class Itr implements Iterator {
   // indice du prochain élément à retourner par next
   int curseur =0;
   // indice du dernier élément  retourné par next
   int  derRet = -1;

modCompte est un attribut de la classe AbstractList qui représente le nombre de fois que la liste a été structurellement modifiée : une modification structurelle est un (ou plusieurs) ajout(s), un (ou plusieurs) retrait(s) qui risquent de rendre incohérents les parcours à l'aide d'itérateurs. Un itérateur stocke la valeur de modCompte quand il est créé, et lève une exception si, lors d'une utilisation de l'itérateur, le modCompte de l'objet collection ne correspond pas au modCompte de l'itérateur.

   intmodCompteAttendu = modCompte; 
   public boolean hasNext() {
       return curseur != size();
   }
  public E next() {
      testModification();
      try {
         E next = get(curseur);
         derRet = curseur++;
         return next;
      } catch(IndexOutOfBoundsException e) {
          testModification();
          throw new NoSuchElementException();
      }
   }
  final void testModification() {
      if (modCompte != modCompteAttendu)
         throw new ConcurrentModificationException();
  }
 
   public void remove() {
     if (derRet == -1) // l'opération précédente n'est pas un next
           throw new IllegalStateException();
     testModification();
     try {     
        AbstractList.this.remove(derRet);// appel du remove de la classe englobante
        if(derRet < curseur) curseur--;
        derRet = -1;
        modCompteAttendu= modCompte; // on remet à jour modCompteAttendu : modCompte a été modifié.
     } catch(IndexOutOfBoundsException e) {
          throw new ConcurrentModificationException();
     }
   }
 

Les méthodes suivantes retournent un ListIterator :

   ListIterator listIterator() {
      return listIterator(0);
   }

   ListIterator listIterator(final int index) {
     if (index<0 || index>nbElements)
         throw new IndexOutOfBoundsException("Index: "+index);
     return new ListItr(index);
   }

La classe imbriquée ListItr implémente l’interface ListIterator :

   private class ListItr extends Itr implements ListIterator<E>
   ListItr(int index) {
      curseur = index;
   }
   public boolean hasPrevious() {
        return curseur != 0;
   }
   public E previous() {
       testModification();
       try {
           int i = curseur - 1;
           E previous = get(i);
           derRet = curseur = i;
           return previous;
       } catch(IndexOutOfBoundsException e) {
           testModification();
           throw new NoSuchElementException();
       }
   }
   public int nextIndex() {
      return curseur;
   }
   public int previousIndex() {
      return curseur-1;
   }
   void set(Object o) {
      if (derRet == -1)
        throw new IllegalStateException();
      testModification();
     try{
       AbstractList.this.set(derRet, o);
       modCompteAttendu= modCompte;
     }catch(IndexOutOfBoundsException e) {
        throw new ConcurrentModificationException();
     }
   }
   public void add(Object o) {
      testModification();
      try {       
        AbstractList.this.add(curseur++, o);
        derRet = -1;
        modCompteAttendu= modCompte;
      }catch(IndexOutOfBoundsException e) {
         throw new ConcurrentModificationException();
      }
   }

5 La méthode subList( int depuis, int jusqua)

   public List<E> subList(int fromIndex, int toIndex) {
        return (this instanceof RandomAccess )
                new RandomAccessSubList<E>(this, fromIndex, toIndex) :
                new SubList<E>(this, fromIndex, toIndex));

    }

Les classes SubList (sous classe de AbstractList) et sa dérivée RandomAccessSubList sont des classes privées du paquetage java.util.

6 La méthode equals

La méthode equals est définie de la façon suivante :

    public boolean equals(Object o) {
       if (o == this)
           return true;
       if (!(o instanceof List))
           return false;
       ListIterator<E> e1 = listIterator();
       ListIterator e2 = ((List) o).listIterator();
       while(e1.hasNext() && e2.hasNext()) {
          E o1 = e1.next();
          Object o2 = e2.next();
          if (!(o1==null ? o2==null : o1.equals(o2)))
          return false;
       }
       return !(e1.hasNext() || e2.hasNext());
   }

haut de la page