Colecții

Conceptul de colecție

Colecția este o acumulare de obiecte, numite elemente. Numărul de elemente se poate modifica în timpul utilizării acesteia, fie prin adaugarea de noi elemente, fie prin eliminarea unor elemente existente. În general, elementele dintr-o colecție sunt diferite, dar se permite sa existe și elemente identice.

Ordinea elementelor dintr-o colecție nu este esentială, dar trebuie să existe o modalitate de a parcurge toate elementele colecției pentru a căuta elementul dorit.

Principala deosebire dintre colecție și structurile de tablou și de înregistrare, deja studiate, constă tocmai în faptul că numărul de elemente ale colecției este variabil, în timp ce la tablou si înregistrare el este fixat în momentul în care se creează structura respectivă. Din această cauză, se mai spune că tabloul și înregistrarea sunt structuri statice, în timp ce colecțiile sunt structuri  dinamice.

Conceptul de iterator al colecției

Pentru a se face posibilă traversarea colecției (adică parcurgerea tuturor elementelor colecției unul dupa altul), s-a introdus conceptul abstract de iterator.

Iteratorul este un obiect care indică, la un moment dat, unul din elementele colecției și permite să se efectueze anumite operații asupra elementului colecției indicat de către iterator, cum ar fi:
    - vizitarea elementului de colecție indicat de iterator;
    - eliminarea elementului indicat de iterator (operație optională);
    - poziționarea iteratorului pe elementul următor al colecției.

Denumirea de iterator provine tocmai de la faptul că acesta poate să treacă de la un element al colecției la altul, deci permite aplicarea unor algoritmi iterativi pe colecția respectivă.

Interfețele Collection și Iterator în Java

In Java API (începând de la JDK 1.2) colecțiile sunt considerate structuri de date abstracte, specificate prin interfața java.util.Collection. Respectarea acestei intefețe permite să se abordeze în mod unitar toate clasele ale căror instanțe se încadrează în conceptul de colecție. Se realizează astfel o unificare a metodelor conținute în toate clasele de colecții (operații comune tuturor colecțiilor), rămânând ca fiecare clasă să conțină și metode specifice.

Principalele operații care se fac asupra unei colecții sunt:
   - adăugarea unui nou element la colecție;
   - traversarea colecției, adică parcurgerea colecției element după element cu posibilă "vizitare" a elementului parcurs;
   - căutarea unui element într-o colecție;
   - eliminarea unui element din colecție.

In Java, iteratorul este instanță a unei clase care implementează interfața java.util.Iterator.
 
Interfata java.util.Collection conține 15 metode, dintre care unele sunt obligatorii, iar altele sunt opționale. Dacă este invocată una din metodele opționale corespunzătoare unei operații nepermise într-o anumită clasă de colecții, ea trebuie să genereze o excepție din clasa java.lang.UnsupportedOperationException

Metodele care realizează operații obligatorii pentru toate clasele care implementează interfața Collection sunt următoarele:
   public boolean isEmpty() - întoarce true dacă această colecție este vidă;
   public int size() - întoarce numărul de elemente din această colecție;
   public boolean contains(Object o) - întoarce true dacă obiectul o există în colecție;
   public boolean containsAll(Collection c) - întoarce true dacă în această colecție există toate elementele colecției c;
   public Iterator iterator() - întoarce un Iterator pentru parcurgerea elementelor acestei colecții; în general, ordinea de parcurgere nu este garantată, dar în mod sigur pot fi parcurse toate elementele;
   public Object[] toArray() - întoarce un tablou de obiecte, care conține toate elementele acestei colecții;
   public Object[] toArray(Object[] a) - întoarce un tablou de obiecte, care conține toate elementele alcestei colecții, care aparțin clasei tabloului a; de exemplu, dacă tabloul a este declarat sub forma String[] a=new String[0], atunci tabloul întors va conține numai acele elemente ale colecției, care aparțin clasei String;
   public boolean equals(Object o) - compară această colecție cu obiectul o și întoarce true dacă ele sunt identice;
   public int hashCode() - întoarce un cod de dispersie pentru această colecție.
Ultimele două metode sunt cele care există și în clasa Object, dar trebuie obligatoriu sa fie redefinite în orice clasă care implementează interfața Collection.

Metodele care realizează operații opționale pentru clasele care implementează interfața Collection sunt următoarele:
   public boolean add(Object o) - adaugă obiectul o la această colecție și întoarce true dacă adaugarea a reușit; motivul pentru care nu s-a facut efectiv adaugarea depinde de modul în care este implementată colecția respectivă: de exemplu ea ar putea să nu accepte decât obiecte dintr-o anumită clasă, sau să nu accepte adaugarea unui obiect deja existent în colecție;
   public boolean remove(Object o) - elimină din această colecție un element identic cu o și întoarce true dacă eliminarea a reușit; dacă nu a reușit, înseamnă că obiectul o nu există în colecție;
   public boolean addAll(Collection c) - adaugă la această colecție toate elementele colecției c și întoarce true dacă această colecție s-a modificat ca rezultat al operației de adăugare;
   public boolean removeAll(Collection c) - elimină din această colecție toate elementele care există și in colecția c; întoarce true dacă această colecție s-a modificat ca rezultat al operației de eliminare;
   public boolean retainAll(Collection c) - reține în această colecție numai acele elemente care există și în colecția c, eliminându-le pe celelalte; întoarce true dacă această colecție s-a modificat în urma operației efectuate;
   public void clear() - elimină toate elementele existente în această colecție;

Remarcăm că metodele opționale trebuie să existe în orice clasă care implementează interfața Collection, la fel ca cele obligatorii; singura deosebire este că, daca o anumită operație optională nu este permisă într-o astfel de clasă, metoda respectivă nu face altceva, decât că întoarce o UnsupportedOperationException.

Interfața java.util.Iterator contine numai trei metode, din care numai primele două sunt operații obligatorii:
   public boolean hasNext() - întoarce true dacă, în colecția căreia îi este asociat acest iterator, mai există cel puțin un element neparcurs (hasNext înseamnă că există un element urmator);
   public Object next() - acest iterator trece la următorul element al colecției și întoarce o referință către elementul respectiv; dacă nu există un element următor, întoarce o exceptie din clasa java.util.NoSuchElementException;
   public void remove() - poate fi invocată o singură dată după fiecare invocare a metodei next() și elimină din colecție elementul indicat de acest iterator. Operația este opțională. Dacă ea nu este permisă pentru o anumită clasă de colecții, trebuie să întoarcă o UnsupportedOperationException. Dacă a fost deja invocată după ultimul next(), întoarce o java.lang.IllegalStateException.

Fiecărei clase care implementează interfața Collection trebuie să i se asocieze în mod obligatoriu cel puțin o clasă cu interfața Iterator, ale cărei instanțe sunt iteratori pentru colecția respectivă.

Clasa AbstractCollection

Clasa java.util.AbstractCollection constituie un prototip de implementare a interfeței Collection. Este o clasă abstractă, din care pot fi derivate diferite clase de colecții.
 
În clasa AbstractCollection sunt definite toate metodele interfeței Collection, cu următoarele excepții, care sunt păstrate ca metode abstracte:
   public abstract Iterator iterator()
   public abstract int size()
Celelalte metode sunt implementate, dar cele care corespund unor operatii opționale întorc o UnsupportedOperationException. În consecință, programatorul care creează o subclasă cu interfața Collection trebuie să definească numai cele două metode abstracte specificate mai sus și - dacă este cazul - să redefinească metodele opționale.

În clasa AbstractCollection este, de asemenea, redefinită metoda moștenită de la clasa Object
   public String toString()
astfel încât să întoarcă reprezentarea ca șir de caractere a colecției.



© Copyright 2001 - Severin BUMBARU, Universitatea "Dunărea de Jos" din Galați