Sunteți pe pagina 1din 9

Colecțiile sunt tipuri de date ce conțin mai multe date de același tip

sau de un tip diferit.

Această definiție este în mod evident similară cu definiția șirului, motiv


pentru care este mai ușor să explicăm conceptul de colecție prin
explicarea diferenței dintre colecție și șir.

Știm că șirul este un tip de dată ce conține un set de alte date în cadrul
său. Șirul poate accepta numai date de același tip și numai numărul de
date specificat în timpul inițializării șirului. Mai precis, dimensiunea
unui șir nu se poate modifica după inițializarea sa și nu se pot stoca
mai multe tipuri de date în cadrul unui șir. Aceste limitări sunt
rezolvate printr-o abordare diferită, ce implică existența unui obiect ce
conține alte obiecte interconectate prin referințe. Acesta permite
manipularea simplă a structurii, fiindcă putem șterge foarte simplu un
obiect din listă prin înlăturarea referinței sale sau putem adăuga un
obiect prin adăugarea unei referințe. În plus, o astfel de structură, dat
fiind faptul că este o structură obiectuală, va fi stocată în partea
dinamică a memoriei (heap) și nu vom fi limitați de dimensiunea
acestei structuri.

Pe lângă stocarea datelor, colecțiile oferă de asemenea posibilitatea de


acces și de manipulare a datelor. Pachetul java.util, ce reprezintă unul
dintre pachetele integrate de bază ale limbajului de programare Java,
conține unul dintre cele mai puternice subsisteme Java: framework-ul
Collection (Java Framework Collection JFC). Acest framework reprezintă
o ierarhie sofisticată de interfețe și clase ce susțin tehnologia de
management al datelor. În cadrul acestui framework, putem efectua
următoarele activități:

adăugarea de obiecte într-o colecție,

înlăturarea obiectelor dintr-o colecție,

căutarea obiectelor,

obținerea (utilizarea) obiectelor,


iterația (trecerea prin) unei colecții.

Framework-ul Collection

Haideți să vedem din ce este alcătuit framework-ul menționat mai sus.


Putem spune că baza acestei ierarhii este alcătuită din două interfețe.
Acestea sunt Collection și Map.

19.1 Structura moștenirii în interfața Collection

Imaginea 22.2 Structura moștenirii în interfața Map


Privind cele două imagini de mai sus, putem vedea că există patru
forme diferite ale colecțiilor:

List

Acestea sunt colecțiile în care putem avea elemente repetitive, în alte


cuvinte, apariții multiple ale aceluiași element. Aceste colecții mai sunt
cunoscute și drept colecții ordonate (respectă ordinea în care
elementele au fost introduse, prin urmare putem accesa un element
dacă suntem familiarizați cu indexul său). Cele mai des utilizate clase
ale acestei colecții sunt ArrayList și LinkedList.

Set

Spre deosebire de tipul de colecție precedent, în colecțiile Set, nu


există o repetiție a elementelor. Dacă introduceți un element care deja
există într-o astfel de colecție, valoarea sa va fi scrisă peste valoarea
veche. De asemenea, aceste colecții nu au nicio ordine în limbajul Java
(există o clasă a acestei colecții ce permite acest lucru, și anume
SortedSet).

Map

O mapă este un container în care elementele se stochează împreună


cu cheile. Astfel de colecții au fost deja menționate ca asociative. Într-o
astfel de structură, elementele unui șir sunt identificate în funcție de o
anumită cheie care le reprezintă. Aceste colecții nu pot avea chei
repetitive. Unele dintre implementările acestei colecții sunt: HashMap,
HashTable, TreeMap și LinkedHashMap.

Queue
Queue reprezintă o structură cunoscută de asemenea ca FIFO (First In
First Out). Primele elemente introduse într-o astfel de colecție sunt de
asemenea primele eliminate. Această structură este identică cu
structura unei cozi din viața reală.

Colecțiile aparțin ariei de cunoștințe avansate despre Java, prin urmare


nu vom discuta decât despre acele colecții pe care le puteți utiliza la
acest nivel din curs.

Am văzut deja ce sunt interfețele și că acestea se folosesc pentru a


obliga o anumită clasă să implementeze funcțiile specificate în
interfață. În esență, este vorba de un acord. Interfețele menționate mai
sus și care există în framework-ul Collection funcționează în același
mod. De exemplu, clasa ArrayList ce reprezintă o colecție va
implementa cu siguranță interfața List. Este clar că putem de
asemenea să creăm propria noastră clasă ce va reprezenta un obiect
pentru stocarea altor obiecte, ceea ce și este scopul unei colecții. Cu
alte cuvinte, noi putem crea o clasă ce va reprezenta o colecție,
precum clasa ArrayList. În partea suplimentară a acestei lecții, veți
vedea cum se poate face acest lucru.

După cum am menționat deja, Java are mai multe clase predefinite și
obiectivul nostru este să aflăm mai multe despre unele dintre aceste
clase de bază.

Lists

Așa cum am mai menționat, cea mai utilizată listă în limbajul de


programare Java este ArryList. În textul de mai jos vom învăța cum
putem utiliza această structură complexă.

Pentru a o putea utiliza, trebuie mai întâi să utilizăm pachetul


java.util.ArrayList sau java.util* (acest pachet este necesar pentru
toate tipurile de liste menționate).

Pentru a crea un obiect de tipul ArrayList, avem nevoie de un


constructor generic. Constructorul generic acceptă tipul de date pe
care clasa îl va manipula. (Modelul generic reprezintă un concept
avansat al programării obiectuale, așadar vom discuta despre acesta
într-unul dintre cursurile următoare.)

În primul rând, pentru această declarație elementele vor fi de tip


Object. Din acest motiv, pentru exemplele de utilizare a metodei add,
se pot adăuga atât date de tip String cât și numerice.

List myList = new ArrayList();

Adăugăm elemente în ArrayList în felul următor:

myList.add("my");
myList.add("name");
myList.add("is...");

Este evident faptul că putem adăuga elemente într-o listă creată astfel
fără ca mai întâi să fie nevoie să definim dimensiunea listei, ceea ce
înseamnă că o astfel de listă poate avea o dimensiune nelimitată. Cu
toate acestea, acest lucru are un preț, fiindcă această abordare este
mai lentă decât realizarea prin intermediul unui șir. Trebuie observat
că List reprezintă interfaţa, iar ArrayList reprezintă implementarea
acestei interfeţe. O altă clasă ce implementează interfaţa List este
LinkedList, în acest caz obiectul colecţie fiind creat astfel:

List myList = new LinkedList();

Pentru a accesa un element de pe o anumită poziție, utilizăm metoda


get. Elementele sunt numerotate la fel ca într-un șir, așadar, pentru a
accesa stringul name, vom expedia acestei metode numărul 1:

System.out.println(myList.get(1));

Pentru a elimina un element din listă, utilizăm metoda remove:


myList.remove(1);

După execuția acestei comenzi, lista va conține următoarele elemente:


stringurile "my“ și "is...“. Aceste stringuri vor fi sortate din nou și
poziționate în modul următor:

0: my
1: is...

Vă reamintim că, după o astfel de intervenție, un șir ar arăta astfel:

0: my
1:
2: is...

În afară de adăugarea, eliminarea și căutarea elementelor, mai există


și alte funcții pe care fiecare listă le are. Acestea sunt funcțiile cu care
putem vedea dimensiunea și cu care putem verifica elementele.

Pentru a verifica dimensiunea colecției, utilizăm metoda size:

for(int i=0;i<myList.size();i++)
System.out.println(myList.get(i));

O altă metodă de parcurgere a listei este printr-o buclp for each, astfel:

for(String s : myList)
System.out.println(s);

Când discutăm despre iterația prin listă, o putem efectua în modul


următor. Această metodă este eficientă când trebuie să listăm toate
elementele unei liste, dar nu este utilă dacă dorim să efectuăm
intervenții mai serioase asupra sa, fiindcă nu expune iteratorul
(numărătorul):

for(String s : myList)
System.out.println(s);
Listele pot accepta orice tip de date. Așadar, putem scrie în felul
următor:

ArrayList myList = new ArrayList();


myList.add("my");
myList.add("name");
myList.add("is...");
myList.add(123);

for(Object s : myList)
System.out.println(s);

Exemplul va procesa fără probleme toate toate valorile listate, deși


există o diferență în ceea ce privește tipurile. Acest lucru este posibil
deoarece colecția convertește toate elementele într-un obiect în timpul
stocării și le readuce la tipul original în timpul extragerii. Această
acțiune se numește Boxing și Unboxing.

Foarte adesea avem nevoie să verificăm dacă o listă conține o valoare.


Acest lucru se poate face manual:

for(Object s : myList)
if(s.equals("name"))
System.out.println("Value exists");

Însă, interfața List are de asemenea metoda contains care efectuează


această sarcină și care returnează o valoare de tip boolean:

System.out.println(myList.contains("name"));

Putem converti o listă într-un șir în orice moment.

Manual:
String[] arr = new String[myList.size()];

for(int i=0;i<myList.size();i++)

arr[i]=myList.get(i);

Sau cu metoda toArray:

String[] arr = myList.toArray(new String[myList.size()]);

Ștergerea unei liste se face cu metoda clear.

myList.clear();

Trebuie ținut cont că ArrayList funcționează astfel încât conține șirul cu


care manipulează în cadrul clasei. Acesta este motivul pentru care
accesarea elementelor sale este foarte rapidă, însă manipularea este
oarecum mai lentă.

Map

Mai există un tip comun de colecție în Java. Este vorba despre un șir de
perechi de chei și valori, respectiv un șir asociativ. Clasele care permit
utilizarea acestor colecții în Java moștenesc interfața Map. Într-o astfel
de structură, elementele șirului sunt identificate prin intermediul unei
anumite chei care le reprezintă. De exemplu, într-o colecție de
cetățeni, codul numeric personal este cheia, în timp ce datele (nume,
prenume, adresă) reprezintă valoarea pentru fiecare cetățean. Dacă
am dori să găsim un anumit cetățean, este suficient să-i cunoaștem
codul numeric personal, respectiv cheia. Cea mai des utilizată clasă a
acestui tip este HashMap.

Haideți să vedem utilizarea acestei clase într-un exemplu.

HashMap hashMap = new HashMap();

După instanțierea clasei hashMap, adăugăm perechile cu metoda put:

hashMap.put("1234567890123", "John Davidson");


hashMap.put("1234567890124", "Tom Dvorak");

Valoarea care stă lângă cheie o obținem cu metoda get:

System.out.println(hashMap.get("1234567890124"));

Regula generală este că un șir de perechi de chei și valori conține


numai chei unice. În cazul clasei HashMap, introducerea acelorași chei
nu va cauza o eroare, ci, în timpul căutării, sub cheie se va afla ultima
cheie adăugată (vechea cheie va fi suprascrisă).

De exemplu:

myHash.put("1234567890123", "John Davidson");


myHash.put("1234567890124", "Mia Parkinson");
myHash.put("1234567890124", "Tom Dvorak");

Acest cod nu va raporta o eroare, însă după o astfel de implementare,


obiectul HashMap va avea doar 2 elemente, iar valoarea Tom Dvorak
va fi singura sub cheia 1234567890124.

S-ar putea să vă placă și