Differences

This shows you the differences between two versions of the page.

Link to this comparison view

poo-ca-cd:arhiva:laboratoare:2024:colectii [2025/09/27 10:45] (current)
florian_luis.micu created
Line 1: Line 1:
 +===== Laboratorul 9: Colecții =====
  
 +**Video introductiv:​** [[https://​youtu.be/​NrcJpB_XLp0| link ]]
 +==== Obiective ====
 +
 +Pe parcursul laboratoarelor și temelor ați folosit structuri de date oferite de API-ul Java. În cadrul acestui laborator le vom aprofunda.
 +  * lucrul cu cele trei tipuri principale de colecții din Java: List, Set, Map
 +  * cunoașterea diferențelor dintre implementările colecțiilor (eficiență,​ sortare, ordonare etc)
 +  * compararea elementelor unor colecții
 +  * contractul equals-hashcode
 +
 +
 +==== Collections Framework====
 +În pachetul **java.util** (pachet standard din JRE) există o serie de clase pe care le veti găsi folositoare.
 +[[http://​docs.oracle.com/​javase/​tutorial/​collections/​index.html|Collections Framework]] este o arhitectură unificată pentru reprezentarea şi manipularea colecţiilor. Ea conţine:
 +  * **interfeţe**:​ permit colecţiilor să fie folosite independent de implementările lor
 +  * **implementări**
 +  * **algoritmi** metode de prelucrare (căutare, sortare) pe colecţii de obiecte oarecare. Algoritmii sunt polimorfici:​ un astfel de algoritm poate fi folosit pe implementări diferite de colecţii, deoarece le abordează la nivel de interfaţă.
 +Colecţiile oferă implementări pentru următoarele tipuri:
 +  * **Set** (elemente neduplicate)
 +  * **List** ​ (o mulțime de elemente)
 +  * **Map** (perechi cheie-valoare)
 +
 +Există o interfaţă,​ numită [[https://​docs.oracle.com/​javase/​7/​docs/​api/​java/​util/​Collection.html|Collection]],​ pe care o implementează majoritatea claselor ce desemnează colecţii din **java.util**. Explicaţii suplimentare găsiţi pe Java Tutorials - [[http://​docs.oracle.com/​javase/​tutorial/​collections/​interfaces/​collection.html|Collection]]
 +
 +Exemplul de mai jos construieşte o listă populată cu nume de studenţi:
 +<code java>
 +Collection names = new ArrayList();​
 +names.add("​Andrei"​);​
 +names.add("​Matei"​);​
 +</​code>​
 +
 +====Parcurgerea colecţiilor====
 +Colecţiile pot fi parcurse (element cu element) folosind:
 +  * iteratori
 +  * o construcţie **for** specială (cunoscută sub numele de **for-each**)
 +
 +====Iteratori====
 +Un iterator este un obiect care permite traversarea unei colecţii şi modificarea acesteia (ex: ştergere de elemente) în mod selectiv. Puteţi obţine un iterator pentru o colecţie, apelând metoda sa **iterator()**. Interfaţa [[https://​docs.oracle.com/​javase/​8/​docs/​api/​java/​util/​Iterator.html|Iterator]] este următoarea:​
 +<code java>
 +public interface Iterator<​E>​ {
 +    boolean hasNext();
 +    E next();
 +    void remove(); // optional
 +}
 +</​code>​
 +
 +Exemplu de folosire a unui iterator:
 +<code java>
 +Collection<​Double>​ col  = new ArrayList<​Double>​();​
 +Iterator<​Double>​ it = col.iterator();​
 +
 +while (it.hasNext()) {
 +    Double backup = it.next();
 +    // apelul it.next() trebuie realizat înainte de apelul it.remove()
 +    if (backup < 5.0) {
 +        it.remove();​
 +    }
 +}
 +</​code>​
 +
 +Apelul metodei [[http://​docs.oracle.com/​javase/​7/​docs/​api/​java/​util/​Iterator.html#​remove()|remove()]] a unui iterator face posibilă eliminarea elementului din colecţie care a fost întors la ultimul apel al metodei **next()** din acelaşi iterator.
 +În exemplul anterior, toate elementele din colecţie mai mici decât 5 for fi şterse la ieşirea din bucla ''​while''​.
 +====For-each====
 +Această construcţie permite (într-o manieră expeditivă) traversarea unei colecţii. **for-each** este foarte similar cu ''​for''​. Următorul exemplu parcurge elementele unei colecţii şi le afişează.
 +<code java>
 +Collection collection = new ArrayList();​
 +for (Object o : collection)
 +    System.out.println(o);​
 +</​code>​
 +Construcţia **for-each** se bazează, în spate, pe un iterator, pe care îl ascunde. Prin urmare **nu** putem şterge elemente în timpul iterării.
 +În această manieră pot fi parcurşi şi **vectori** oarecare. De exemplu, ''​collection''​ ar fi putut fi definit ca ''​Object[]''​. ​
 +
 +====Genericitate====
 +Fie următoarea porţiune de cod:
 +<code java>
 +Collection c = new ArrayList();​
 +c.add("​Test"​);​
 +               
 +Iterator it = c.iterator();​
 +               
 +while (it.hasNext()) {   
 +    String s = it.next(); ​        // ERROR: next() returns an Object and it's needed an explicit cast to String
 +    String s = (String)it.next();​ // OK
 +}
 +</​code>​
 +Am definit o colecţie ''​c'',​ de tipul ''​ArrayList''​ (pe care îl vom examina într-o secţiune următoare). Apoi, am adăugat în colecţie un element de tipul ''​String''​. Am realizat o parcurgere folosind un iterator, şi am încercat obţinerea elementului nostru folosind apelul: ''​String s = it.next()'';​. Funcţia ''​next''​ însă întoarce un obiect de tip ''​Object''​. Prin urmare apelul va eşua. Varianta corectă este ''​String s = (String)it.next()'';​.
 +Am fi putut preciza, din start, ce tipuri de date dorim într-o colecţie:
 +<code java>
 +Collection<​String>​ c = new ArrayList<​String>​();​
 +c.add("​Test"​);​
 +c.add(2); ​     // ERROR!
 +Iterator<​String>​ it = c.iterator();​
 +               
 +while (it.hasNext()) {   
 +     ​String s = it.next();
 +}
 +</​code>​
 +
 +Mai multe detalii despre acest subiect găsiți in laboratorul de [[:​poo-ca-cd:​laboratoare:​genericitate|Genericitate]]
 +====Interfaţa List====
 +O listă este o colecţie care poate fi **ordonată**. Listele **pot** conţine elemente **duplicate**. Pe lângă operaţiile moştenite de la ''​Collection'',​ interfaţa [[https://​docs.oracle.com/​javase/​8/​docs/​api/​java/​util/​List.html|List]] conţine operaţii bazate pe poziţie (index), de exemplu: //set//, //get//, //add// la un index, //remove// de la un index.
 +
 +<code java>
 +List<​String>​ fruits = new ArrayList<>​(Arrays.asList("​Apple",​ "​Orange",​ "​Grape"​));​
 +fruits.add("​Apple"​); ​              // metodă moștenită din Collection ​
 +fruits.add(2,​ "​Pear"​); ​            // [Apple, Orange, Pear, Grape, Apple]
 +System.out.println(fruits.get(3));​ // Grape
 +fruits.set(1,​ "​Cherry"​); ​          // [Apple, Cherry, Pear, Grape, Apple]
 +fruits.remove(2);​
 +System.out.println(fruits); ​       // [Apple, Cherry, Grape, Apple]
 +</​code>​
 +
 +Alături de ''​List'',​ este definită interfaţa [[http://​docs.oracle.com/​javase/​7/​docs/​api/​java/​util/​ListIterator.html|ListIterator]],​ ce extinde interfaţa ''​Iterator''​ cu metode de parcurgere în ordine inversă.
 +''​List''​ posedă două implementări standard:
 +  * ''​ArrayList''​ - implementare sub formă de vector. Accesul la elemente se face în timp constant: ''​O(1)''​
 +  * ''​LinkedList''​ - implementare sub formă de listă dublu înlănţuită. Prin urmare, accesul la un element nu se face în timp constant, fiind necesară o parcurgere a listei: ''​O(n)''​.
 +Printre algoritmii implementaţi se numără:
 +  * ''​sort''​ - realizează sortarea unei liste
 +  * ''​binarySearch''​ - realizează o căutare binară a unei valori într-o listă sortată
 +În general, algoritmii pe colecţii sunt implementaţi ca metode statice în clasa [[http://​docs.oracle.com/​javase/​7/​docs/​api/​java/​util/​Collections.html|Collections]].
 +<note important>​
 +**Atenţie**:​ Nu confundaţi interfaţa ''​Collection''​ cu clasa ''​Collections''​. Spre deosebire de prima, a doua este o clasă ce conţine exclusiv metode statice. Aici sunt implementate diverse operaţii asupra colecţiilor.
 +</​note>​
 +Iată un exemplu de folosire a sortării:
 +<code java>
 +List<​Integer>​ l = new ArrayList<​Integer>​();​
 +l.add(5);
 +l.add(7);
 +l.add(9);
 +l.add(2);
 +l.add(4);
 +               
 +Collections.sort(l);​
 +System.out.println(l);​
 +</​code>​
 +Mai multe detalii despre algoritmi pe colecţii găsiţi pe Java Tutorials - [[http://​docs.oracle.com/​javase/​tutorial/​collections/​algorithms/​index.html|Algoritmi pe liste]]
 +
 +====Compararea elementelor====
 +Rularea exemplului de sortare ilustrat mai sus arată că elementele din ''​ArrayList''​ se sortează crescator. Ce se întâmplă când dorim să realizăm o sortare particulară pentru un tip de date complex? Spre exemplu, dorim să sortăm o listă ''​ArrayList<​Student>''​ după media anilor. Să presupunem că ''​Student''​ este o clasă ce conţine printre membrii săi o variabilă ce reţine media anilor.
 +Acest lucru poate fi realizat folosind interfeţele:​
 +  * [[https://​docs.oracle.com/​javase/​8/​docs/​api/​java/​lang/​Comparable.html|Comparable]]
 +  * [[https://​docs.oracle.com/​javase/​8/​docs/​api/​java/​util/​Comparator.html|Comparator]]
 +
 +| |  **Comparable**| ​ **Comparator**|
 +|  **Logica de sortare**| ​ Logica de sortare trebuie să fie în clasa ale cărei obiecte sunt sortate. Din acest motiv, această metodă se numeşte //sortare naturală//​. ​ |  Logica de sortare se află într-o **clasă separată**. Astfel, putem defini mai multe metode de sortare, bazate pe diverse câmpuri ale obiectelor de sortat. ​ |
 +|  **Implementare**| ​ Clasa ale cărei instanţe se doresc a fi sortate trebuie să **implementeze această interfaţă** şi, evident, să suprascrie metoda ''​compareTo()''​. ​ |  Clasa ale cărei instanţe se doresc a fi sortate nu trebuie să implementeze această interfaţă. Este nevoie de o alta clasă (poate fi şi internă) care să implementeze interfaţa ''​Comparator''​. ​ |
 +|  **Metoda de comparare**| ​ ''​int compareTo(Object o1)''​ \\ Această metodă compară obiectul curent (this) cu obiectul o1 şi întoarce un întreg. Valoarea întoarsă este interpretată astfel: \\ 1. pozitiv – obiectul este mai mare decât o1 \\ 2. zero – obiectul este egal cu o1 \\ 3. negativ – obiectul este mai mic decât o1  |  ''​int compare(Object o1,Object o2)''​ \\ Această metodă compară obiectele o1 and o2 şi întoarce un întreg. Valoarea întoarsă este interpretată astfel: \\ 1. pozitiv – o2 este mai mare decât o1 \\ 2. zero – o2 este egal cu o1 \\ 3. negativ – o2 este mai mic decât o1  |
 +|  **Metoda de sortare**| ​ ''​Collections.sort(List)''​ \\ Aici obiectele sunt sortate pe baza metodei ''​compareTo()''​. ​ |  ''​Collections.sort(List,​ Comparator)''​ \\ Aici obiectele sunt sortate pe baza metodei ''​compare()''​ din Comparator. ​ |
 +|  **Pachet**| ​ Java.lang.Comparable  |  Java.util.Comparator ​ |
 +
 +Exemplu Comparable:
 +  * implementare:​
 +<code java>
 +public class Student implements Comparable<​Student>​ {
 +    private String name;
 +    private String surname;
 +
 +    public Student(String name, String surname) {
 +        this.name = name;
 +        this.surname = surname;
 +    }
 +
 +    public String getName() {
 +        return name;
 +    }
 +
 +    public void setName(String name) {
 +        this.name = name;
 +    }
 +
 +    public String getSurname() {
 +        return surname;
 +    }
 +
 +    public void setSurname(String surname) {
 +        this.surname = surname;
 +    }
 +
 +    @Override
 +    public int compareTo(Student o) {
 +        if (surname.equals(o.surname)) {
 +            return name.compareTo(o.name);​
 +        } else {
 +            return surname.compareTo(o.surname);​
 +        }
 +    }
 +}
 +</​code>​
 +  * folosire:
 +<code java>
 +ArrayList<​Student>​ students = new ArrayList<>​();​
 +// populate ArrayList with Student objects
 +Collections.sort(students);​
 +</​code>​
 +
 +Exemplu implementare și folosire Comparator:
 +<code java>
 +ArrayList<​Integer>​ numbers = new ArrayList<>​();​
 +numbers.add(5);​
 +numbers.add(1);​
 +numbers.add(3623);​
 +numbers.add(13);​
 +numbers.add(7);​
 +Collections.sort(numbers,​ new Comparator<​Integer>​() {
 +     ​@Override
 +     ​public int compare(Integer o1, Integer o2) {
 +          return o2 - o1;
 +     }
 +});
 +System.out.println(numbers);​ // se afișează [3623, 13, 7, 5, 1]
 +
 +// alternativ, putem sorta o colecție, folosind metoda sort() din interfața List, în acest mod:
 +numbers.sort(new Comparator<​Integer>​() {
 +      @Override
 +      public int compare(Integer o1, Integer o2) {
 +           ​return o2 - o1;
 +      }
 +});
 +
 +</​code>​
 +
 +====Interfaţa Set====
 +Un [[http://​docs.oracle.com/​javase/​7/​docs/​api/​java/​util/​Set.html|Set]] (mulţime) este o colecţie ce nu poate conţine elemente duplicate. Interfaţa ''​Set''​ conţine doar metodele moştenite din ''​Collection'',​ la care adaugă restricţii astfel încât elementele duplicate să nu poată fi adăugate.
 +Avem trei implementări utile pentru Set:
 +  * [[http://​docs.oracle.com/​javase/​7/​docs/​api/​java/​util/​HashSet.html|HashSet]]:​ memorează elementele sale într-o **tabelă de dispersie** ''​(hash table)'';​ este implementarea cea mai performantă,​ însă nu avem garanţii asupra **ordinii** de parcurgere. Doi iteratori **diferiţi** pot parcurge elementele mulţimii în ordine **diferită**.
 +  * [[http://​docs.oracle.com/​javase/​7/​docs/​api/​java/​util/​TreeSet.html|TreeSet]]:​ memorează elementele sale sub formă de [[http://​en.wikipedia.org/​wiki/​Red-black_tree|arbore roşu-negru]];​ elementele sunt ordonate pe baza valorilor sale. Implementarea este mai **lentă** decat ''​HashSet''​.
 +  * [[http://​docs.oracle.com/​javase/​7/​docs/​api/​java/​util/​LinkedHashSet.html|LinkedHashSet]]:​ este implementat ca o **tabelă de dispersie**. Diferenţa faţă de ''​HashSet''​ este că ''​LinkedHashSet''​ menţine o listă dublu-înlănţuită peste toate elementele sale. Prin urmare (şi spre deosebire de ''​HashSet''​),​ elementele rămân în **ordinea** în care au fost inserate. O parcurgere a ''​LinkedHashSet''​ va găsi elementele mereu în această ordine.
 +<note important>​
 +**Atenţie**:​ Implementarea ''​HashSet'',​ care se bazează pe o **tabelă de dispersie**,​ calculează codul de dispersie al elementelor pe baza metodei [[http://​docs.oracle.com/​javase/​7/​docs/​api/​java/​lang/​Object.html#​hashCode()|hashCode]],​ definită în clasa ''​Object''​. De aceea, două obiecte **egale**, conform funcţiei ''​equals'',​ trebuie să întoarcă **acelaşi** rezultat din ''​hashCode''​.
 +</​note>​
 +| | **HashSet** | **LinkedHashSet** | **TreeSet** |
 +| **Funcționarea internă** | Elementele se memorează într-o tabelă de dispersie | Elementele sunt păstrate cu ajutorul unei liste înlănțuite | Elementele se memorează într-un arbore de căutare |
 +| **Utilizarea** | Se folosește când dorești să stochezi o listă de elemente fără a fi interesat de ordinea acestei memorări | Se folosește atunci când se dorește conservarea ordinii de la inserare | Se folosește când se dorește păstrarea elementelor într-o ordine stabilită cu ajutorul unui Comparator |
 +| **Ordinea** | Ordinea elementelor este total aleatoare | Se conservă ordinea în care au fost introduse elementele | Se folosește ordinea stabilită cu ajutorul unui Comparator. Daca acesta nu este menționat, implicit elementele vor fi sortate crescător |
 +| **Complexitatea operațiilor**| O(1) pentru toate operațiile de bază (inserare, ștergere, căutare) | O(1) pentru toate operațiile de bază (inserare, ștergere, căutare) | Deoarece este folosit un arbore în spate, operațiile se execută in O(log(N)) |
 +| **Performanța** | Cel mai performant dintre cele 3 menționate | Performanța se află între cea a unui HashSet și a unui TreeSet deoarece în ciuda faptului că are complexitate O(1) la operațiile principale, folosește intern și liste înlănțuite pentru păstrarea ordinii de la inserare | Din cauza faptului că după fiecare operație de adăugare și ștergere trebuie să conserve ordinea elementelor,​ are cea mai proastă performanță dintre cele 3 menționate|
 +|**Compararea**| Folosește //​equals()//​ și //​hashCode()//​ pentru a compara obiectele|Folosește //​equals()//​ și //​hashCode()//​ pentru a compara obiectele| Folosește //​compare()//​ și //​compareTo()//​ pentru a compara obiectele| ​
 +
 +
 +Explicaţii suplimentare găsiti pe Java Tutorials - [[http://​docs.oracle.com/​javase/​tutorial/​collections/​interfaces/​set.html|Set]].
 +
 +====Interfaţa Map====
 +Un [[http://​docs.oracle.com/​javase/​7/​docs/​api/​java/​util/​Map.html|Map]] ​ este un obiect care mapează **chei** pe **valori**. Într-o astfel de structură **nu** pot exista chei duplicate. Fiecare cheie este mapată la exact o valoare. ''​Map''​ reprezintă o modelare a conceptului de funcţie: ''​primeşte''​ o entitate ca parametru (cheia), şi întoarce o altă entitate (valoarea).
 +Trei implementări pentru ''​Map''​ sunt:
 +  * [[http://​docs.oracle.com/​javase/​7/​docs/​api/​java/​util/​HashMap.html|HashMap]]
 +  * [[http://​docs.oracle.com/​javase/​7/​docs/​api/​java/​util/​TreeMap.html|TreeMap]]
 +  * [[http://​docs.oracle.com/​javase/​7/​docs/​api/​java/​util/​LinkedHashMap.html|LinkedHashMap]]
 +Particularităţile de implementare corespund celor de la ''​Set''​.
 +Exemplu de folosire: ​
 +<code java>
 +class Student {
 +    String name;
 +    float avg;
 +
 +    public Student(String name, float avg) {
 +        this.name = name;
 +        this.avg ​ = avg;
 +    }
 +
 +    public String toString() {
 +        return "​["​ + name + ", " + avg + "​]";​
 +    }
 +}
 +
 +public class Test {
 +    public static void main(String[] args) {
 +        ​
 +        Map<​String,​Student>​ students = new HashMap<​String,​ Student>​();​
 +        ​
 +        students.put("​Matei", ​ new Student("​Matei", ​ 4.90F));
 +        students.put("​Andrei",​ new Student("​Andrei",​ 6.80F));
 +        students.put("​Mihai", ​ new Student("​Mihai", ​ 9.90F));
 +        ​
 +        System.out.println(students.get("​Mihai"​));​
 +       
 +        // adaugăm un element cu aceeași cheie
 +        System.out.println(students.put("​Andrei",​ new Student("",​ 0.0F))); ​
 +        // put(...) întoarce elementul vechi
 +        ​
 +        // si îl suprascrie
 +        System.out.println(students.get("​Andrei"​));​
 +        ​
 +        // remove(...) returnează elementul șters
 +        System.out.println(students.remove("​Matei"​));​
 +    ​
 +        // afișăm structura de date
 +        System.out.println(students);​
 +    }
 +}
 +</​code>​
 +Interfaţa [[http://​docs.oracle.com/​javase/​7/​docs/​api/​java/​util/​Map.Entry.html|Map.Entry]] desemnează o pereche (cheie, valoare) din map. Metodele caracteristice sunt:
 +  * **getKey**: întoarce cheia
 +  * **getValue**:​ întoarce valoarea
 +  * **setValue**:​ permite stabilirea valorii asociată cu această cheie
 +O **iterare** obişnuită pe un map se va face în felul următor:
 +<code java>
 +for (Map.Entry<​String,​ Student> entry : students.entrySet())
 +    System.out.println(entry.getKey() + " has the following average grade: " + entry.getValue().getAverage());​
 +</​code>​
 +În bucla ''​for-each''​ de mai sus se ascunde, de fapt, iteratorul mulţimii de perechi, întoarse de ''​entrySet''​.
 +Explicaţii suplimentare găsiţi pe Java Tutorials - [[http://​docs.oracle.com/​javase/​tutorial/​collections/​interfaces/​map.html|Map]].
 +
 +====Alte interfeţe====
 +[[http://​docs.oracle.com/​javase/​8/​docs/​api/​java/​util/​Queue.html|Queue]] este o interfaţă ce defineşte operaţii specifice pentru **cozi**:
 +  * inserţia unui element
 +  * ştergerea unui element
 +  * operaţii de "​inspecţie"​ a cozii
 +Implementări utilizate frecvente pentru ''​Queue'':​
 +  * ''​PriorityQueue'':​ coadă cu priorităţi / heap
 +[[http://​docs.oracle.com/​javase/​8/​docs/​api/​java/​util/​Queue.html|Deque]] este o interfaţă,​ care extinde interfața ''​Queue'',​ ce defineşte operaţii specifice pentru **cozi cu două capete**, unul la început și celălalt la final. Având operații pentru ambele capete, rezultă faptul că o colecție de tip Deque poate fi folosită atât ca **stivă**, cât și drept **coadă**. ​
 +
 +Operații specifice:
 +  * inserţia unui element
 +  * ştergerea unui element
 +  * operaţii de "​inspecţie"​ a cozii / a stivei
 +Implementări utilizate frecvente pentru ''​Deque'':​
 +  * ''​LinkedList'':​ pe lângă ''​List'',​ ''​LinkedList''​ implementează şi ''​Deque''​ (deci şi ''​Queue''​)
 +  * ''​ArrayDeque'':​ este mai rapidă decât ''​LinkedList'',​ în caz ca este folosită drept coadă
 +
 +
 +
 +Explicaţii suplimentare găsiţi pe Java Tutorials - [[http://​docs.oracle.com/​javase/​tutorial/​collections/​interfaces/​queue.html|Queue]],​ [[https://​docs.oracle.com/​javase/​tutorial/​collections/​interfaces/​deque.html|Deque]] ​
 +
 +<note important>​
 +În Java, există colecții care sunt marcate ca fiind //​obsolete//,​ adică nu mai sunt recomandate să fie folosite. Exemple de astfel de colecții:
 +  * ''​Vector''​ - operațiile prin care colecția este modificată (adăugare, ștergere) sunt sincronizate (detalii legate de sincronizări veți studia la [[https://​ocw.cs.pub.ro/​courses/​apd/​laboratoare/​06 | APD]], în anul 3), în timp ce operațiile la ArrayList (care este recomandat în locul lui ''​Vector''​) nu sunt sincronizate,​ permițând astfel programatorului să aibă mai mult control asupra operațiilor în cod
 +  * ''​Hashtable''​ - operațiile ​ prin care colecția este modificată (adăugare, ștergere) sunt sincronizate,​ în timp aceste operatiile la HashMap (care este recomandat în locul lui ''​Hashtable''​) nu sunt sincronizate
 +  * ''​Stack''​ - acesta reprezintă implementarea de operații specifice pentru stivă și extinde clasa ''​Vector'',​ despre care am vorbit anterior. Colecția recomandată în locul acesteia este ''​ArrayDeque''​.
 +</​note>​
 +====TL;​DR====
 +
 +  * Pachetul [[https://​docs.oracle.com/​javase/​8/​docs/​api/​java/​util/​package-summary.html|java.util]] oferă implementări ale unor stucturi de date și algoritmi pentru manipularea lor: ierarhiile [[https://​docs.oracle.com/​javase/​8/​docs/​api/​java/​util/​Collection.html|Collection]] și [[https://​docs.oracle.com/​javase/​8/​docs/​api/​java/​util/​Map.html|Map]] și clasa cu metode statice [[https://​docs.oracle.com/​javase/​8/​docs/​api/​java/​util/​Collections.html|Collections]].
 +  * **Parcurgerea** colecţiilor se face în două moduri: ​
 +    * folosind iteratori (obiecte ce permit traversarea unei colecţii şi modificarea acesteia)
 +    * folosind construcţia specială **for each** (care nu permite modificarea colecţiei în timpul parcurgerii sale)
 +  * Interfaţa **List** - colecţie ordonată ce **poate** conţine elemente **duplicate**.
 +  * Interfaţa **Set** - colecţie ce **nu poate** conţine elemente **duplicate**. Există trei implementări utile pentru Set: [[http://​docs.oracle.com/​javase/​8/​docs/​api/​java/​util/​HashSet.html|HashSet]] (neordonat, nesortat), [[http://​docs.oracle.com/​javase/​8/​docs/​api/​java/​util/​TreeSet.html|TreeSet]] (set sortat) și [[http://​docs.oracle.com/​javase/​8/​docs/​api/​java/​util/​LinkedHashSet.html|LinkedHashSet]] (set ordonat)
 +  * Interfaţa **Map** - colecţie care mapează **chei** pe **valori**. Într-o astfel de structură nu pot exista chei duplicate. Cele trei implementări pentru ''​Map''​ sunt [[http://​docs.oracle.com/​javase/​8/​docs/​api/​java/​util/​HashMap.html|HashMap]] (neordonat, nesortat), [[http://​docs.oracle.com/​javase/​8/​docs/​api/​java/​util/​TreeMap.html|TreeMap]] (map sortat) și [[http://​docs.oracle.com/​javase/​8/​docs/​api/​java/​util/​LinkedHashMap.html|LinkedHashMap]] (map ordonat)
 +  * **Contractul equals - hashcode**: dacă //obj1 equals obj2 atunci hashcode obj1 == hashcode obj2//. Dacă implementați equals, implementați și hashcode dacă doriți să folosiți acele obiecte în colecții bazate pe hash-uri (e.g. HashMap, HashSet).
 +
 +====Exerciţii====
 +1. În cadrul acestui exercițiu, veți implementa o clasă numită Student, care are patru membri:
 +    - name (String)
 +    - surname (String)
 +    - id (long)
 +    - averageGrade (double) - media unui student.
 +Clasa Student va implementa interfața Comparable<​Student>,​ folosită la sortări, prin implementarea metodei compareTo. În metoda compareTo, studenții vor fi comparați mai întâi după medie, apoi după numele de familie, apoi după prenume.
 +După implementarea clasei, sortați elementele listei "​students"​ din metoda main folosind metoda Collections.sort().
 +
 +2. Adăugați lista "​copyStudents"​ într-un PriorityQueue (cu ajutorul metodei Collection.addAll),​ care folosește un Comparator (utilizați constructorul PriorityQueue) sau o funcție anonimă. Elementele vor fi sortate crescător după id.
 +
 +3. Suprascrieți metodele equals și hashCode în clasa Student (puteți folosi generatorul de cod din IntelliJ). După aceasta, adăugați în lista asociată studentilor din "​studentMap"​ patru materii aleatorii. Pentru a obține materiile aleatorii, urmăriți indicațiile din codul din funcția main.
 +
 +4. Extindeți clasa LinkedHashSet<​Integer>​ cu o clasă în care se vor putea adăuga doar numere pare. Metoda add va fi suprascrisă astfel încât să nu permită adăugarea de numere impare în colecție. Efectuați aceeași operațiune și pentru clasele TreeSet și HashSet. Observați diferențele privind ordinea de inserare a elementelor între cele trei clase menționate.
 +
 +Scheletul il puteți gasi pe [[https://​github.com/​oop-pub/​oop-labs/​blob/​master/​src/​lab8/​Main.java|github]]. Soluția trebuie încărcată pe [[https://​code.devmind.ro|devmind]].
 +==== Resurse ====
 +  * [[:​poo-ca-cd:​laboratoare:​old-exercises#​colectii|Exerciții din alți ani]]
 +
 +==== Linkuri utile ====
 +  * [[https://​www.baeldung.com/​java-8-streams|Streams]],​ introduse din Java 8, pot fi folosite și pentru a aplica operații pe colecții. Nu le folosim momentan la laborator însă le puteți utiliza la teme:
 +     * [[https://​www.geeksforgeeks.org/​stream-in-java/​|Java streams]]
 +     * [[https://​www.geeksforgeeks.org/​stream-filter-java-examples/​| Filter streams examples]]
poo-ca-cd/arhiva/laboratoare/2024/colectii.txt · Last modified: 2025/09/27 10:45 by florian_luis.micu
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0