Differences

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

Link to this comparison view

poo:breviare:breviar-07 [2025/11/17 13:00]
george.tudor1906
poo:breviare:breviar-07 [2025/11/19 09:25] (current)
george.tudor1906
Line 2: Line 2:
  
 === Colecții, iteratori, genericitate === === Colecții, iteratori, genericitate ===
- 
---- 
  
 === 1. Colecții === === 1. Colecții ===
  
 == 1.1 Interfața Collection și ierarhia colecțiilor == == 1.1 Interfața Collection și ierarhia colecțiilor ==
 +
 +{{:​poo:​breviare:​collection.png?​600|}}
  
 O **colecție** este un obiect care grupează mai multe elemente într-o singură unitate. Prin intermediul colecțiilor avem acces la diferite structuri de date: vectori dinamici, liste înlănțuite,​ stive, mulțimi, tabele de dispersie ș.a.m.d.. Colecțiile sunt folosite atât pentru **memorarea și manipularea datelor**, cât și pentru **transmiterea informațiilor între metode**. O **colecție** este un obiect care grupează mai multe elemente într-o singură unitate. Prin intermediul colecțiilor avem acces la diferite structuri de date: vectori dinamici, liste înlănțuite,​ stive, mulțimi, tabele de dispersie ș.a.m.d.. Colecțiile sunt folosite atât pentru **memorarea și manipularea datelor**, cât și pentru **transmiterea informațiilor între metode**.
Line 13: Line 13:
 Clasele și interfețele pentru lucrul cu colecții se află în pachetul **java.util**. Ierarhia pornește, pentru colecții propriu-zise,​ de la interfața **Collection**,​ care definește operațiile de bază (adăugare, eliminare, căutare, iterare). Din //​Collection//​ derivă **trei ramuri principale**:​ Clasele și interfețele pentru lucrul cu colecții se află în pachetul **java.util**. Ierarhia pornește, pentru colecții propriu-zise,​ de la interfața **Collection**,​ care definește operațiile de bază (adăugare, eliminare, căutare, iterare). Din //​Collection//​ derivă **trei ramuri principale**:​
  
-  * **List** ​– colecții ordonate și indexate, care permit duplicate; implementările uzuale sunt ArrayList (acces aleator rapid) și LinkedList (inserări/​ștergeri eficiente cu iteratorul). Vector și Stack apar în bibliografie,​ dar sunt considerate tipuri legacy (fac parte din limbaj încă de la primele versiuni); pentru comportament de stivă/​coadă se preferă azi Deque (ex. ArrayDeque).  +  * **List** ​colecții ordonate și indexate, care permit duplicate; implementările uzuale sunt ArrayList (acces aleator rapid) și LinkedList (inserări/​ștergeri eficiente cu iteratorul). Vector și Stack apar în bibliografie,​ dar sunt considerate tipuri legacy (fac parte din limbaj încă de la primele versiuni); pentru comportament de stivă/​coadă se preferă azi Deque (ex. ArrayDeque).  
-  * **Set** ​– mulțimi fără duplicate (în sens matematic); aici întâlnim HashSet (rapid, neordonat), LinkedHashSet (păstrează ordinea inserării) și TreeSet (menține elementele ordonate). Ordonarea formală este surprinsă de interfața SortedSet, care extinde Set și cere o ordine „naturală” sau dată de un Comparator, TreeSet fiind implementarea clasică. +  * **Set** ​mulțimi fără duplicate (în sens matematic); aici întâlnim HashSet (rapid, neordonat), LinkedHashSet (păstrează ordinea inserării) și TreeSet (menține elementele ordonate). Ordonarea formală este surprinsă de interfața SortedSet, care extinde Set și cere o ordine „naturală” sau dată de un Comparator, TreeSet fiind implementarea clasică. 
-  * **Queue** / **Deque** ​– structuri de tip coadă (eventual cu două capete). Implementările standard sunt ArrayDeque (coadă/​stivă eficientă) și PriorityQueue (ordonare după prioritate, nu după inserare).+  * **Queue** / **Deque** ​structuri de tip coadă (eventual cu două capete). Implementările standard sunt ArrayDeque (coadă/​stivă eficientă) și PriorityQueue (ordonare după prioritate, nu după inserare).
  
-Separat de Collection se află ierarhia **Map**, care gestionează perechi cheie - valoare. Cheile sunt unice, iar fiecare cheie mapează exact o valoare. Implementările cele mai folosite sunt **HashMap** (rapid, fără ordine), **LinkedHashMap** (menține ordinea inserării sau a accesului ​– util, de exemplu, pentru cache LRU - Least Recently Used) și **TreeMap** (chei ordonate). Interfața **SortedMap** extinde Map cu operații specifice ordinii - în practică, TreeMap este implementarea reprezentativă. Hashtable este o variantă veche, sincronizată,​ păstrată pentru compatibilitate,​ dar în cod modern se preferă HashMap (sau ConcurrentHashMap pentru acces concurent).+Separat de Collection se află ierarhia **Map**, care gestionează perechi cheie - valoare. Cheile sunt unice, iar fiecare cheie mapează exact o valoare. Implementările cele mai folosite sunt **HashMap** (rapid, fără ordine), **LinkedHashMap** (menține ordinea inserării sau a accesului ​util, de exemplu, pentru cache LRU - Least Recently Used) și **TreeMap** (chei ordonate). Interfața **SortedMap** extinde Map cu operații specifice ordinii - în practică, TreeMap este implementarea reprezentativă. Hashtable este o variantă veche, sincronizată,​ păstrată pentru compatibilitate,​ dar în cod modern se preferă HashMap (sau ConcurrentHashMap pentru acces concurent).
  
 <note important>​ <note important>​
Line 36: Line 36:
 public class Main { public class Main {
     public static void main(String[] args) {     public static void main(String[] args) {
-        // 1) Corect și sigur – generics+        // 1) Corect și sigur generics
         List<​String>​ nume = new ArrayList<>​();​         List<​String>​ nume = new ArrayList<>​();​
         nume.add("​Ana"​);​         nume.add("​Ana"​);​
Line 42: Line 42:
         String s1 = nume.get(0);​ // fără cast, sigur         String s1 = nume.get(0);​ // fără cast, sigur
  
-        // 2) Permis, dar nerecomandat ​– raw type (fără <T>)+        // 2) Permis, dar nerecomandat ​raw type (fără <T>)
         List nespecificata = new ArrayList();​ // WARNING: unchecked/​unsafe         List nespecificata = new ArrayList();​ // WARNING: unchecked/​unsafe
         nespecificata.add("​Ana"​);​         nespecificata.add("​Ana"​);​
Line 59: Line 59:
 } }
 </​code>​ </​code>​
- 
---- 
  
 == 1.2 Liste (List) == == 1.2 Liste (List) ==
  
-Interfața **List**, pe lângă metodele moștenite din `Collection`, definește colecții:+Interfața **List**, pe lângă metodele moștenite din //Collection//, definește colecții ​**ordonate** și **indexate**,​ care **permit duplicate** și ale căror elemente pot fi accesate după **poziție** (index). În practică, cele mai folosite implementări sunt **ArrayList** și **LinkedList**. ​
  
-* **ordonate** și **indexate**;​ +ArrayList oferă **acces aleator ​foarte ​rapid** ​la elementecu cost mai mare pentru ​inserări/​ștergeri în interiorul listeiLinkedList ​stochează elementele într-o ​listă înlănțuită, ceea ce face **inserările și ștergerile** ​locale mai eficiente (folosind iteratorul), dar accesul ​la un element "din mijloc" este mai lent. LinkedList ​implementează și Deque, astfel că poate lucra comod cu elementele de la ambele capete ​(ex. addFirst, addLast). Pentru stivă/​coadă se preferă ArrayDeque, iar pentru liste obișnuite ArrayList/​LinkedList.
-* care **permit duplicate**;​ +
-* ale căror elemente pot fi accesate după **poziție** (index). +
- +
-Cele mai folosite implementări:​ +
- +
-* **ArrayList** – vector dinamic; ​acces aleator ​**rapid**, inserări/​ștergeri în interiorul listei ​mai costisitoare;​ +
-* **LinkedList** – listă înlănțuităinserări/ștergeri ​locale mai eficiente (cu iterator), acces mai lent la elementele ​din mijloc”; implementează și `Deque` (operare ​la ambele capete). +
- +
-Pentru ​comportament de **stivă/​coadă** se preferă ​azi `ArrayDeque`, iar pentru liste obișnuite ​`ArrayList`/`LinkedList`.+
  
 <code java> <code java>
Line 81: Line 70:
  
 class Liste { class Liste {
-private final List<​String>​ list1 = new ArrayList<>​(); ​       // ordonată, acces aleator rapid +    ​private final List<​String>​ list1 = new ArrayList<>​(); ​       // ordonată, acces aleator rapid 
-private final LinkedList<​Integer>​ list2 = new LinkedList<>​();​ // listă + deque+    private final LinkedList<​Integer>​ list2 = new LinkedList<>​();​ // listă + deque
  
-``` +    ​public static void main(String[] args) { 
-public static void main(String[] args) { +        Liste obj = new Liste();
-    Liste obj = new Liste();+
  
-    ​// Operații de bază pe ArrayList<​String>​ +        ​// Operații de bază pe ArrayList<​String>​ 
-    obj.list1.add("​Lab POO"​);​ +        obj.list1.add("​Lab POO"​);​ 
-    obj.list1.add("​Colectii"​);​ +        obj.list1.add("​Colectii"​);​ 
-    obj.list1.add("​Structuri de date"​);​ +        obj.list1.add("​Structuri de date"​);​ 
-    if (obj.list1.contains("​Colectii"​)) { +        if (obj.list1.contains("​Colectii"​)) { 
-        System.out.println("​Lista contine cuvantul"​);​ +            System.out.println("​Lista contine cuvantul"​);​ 
-    }+        }
  
-    ​// Parcurgere și ștergere în siguranță (fără ConcurrentModificationException) +        ​// Parcurgere și ștergere în siguranță (fără ConcurrentModificationException) 
-    Iterator<​String>​ it = obj.list1.iterator();​ +        Iterator<​String>​ it = obj.list1.iterator();​ 
-    while (it.hasNext()) { +        while (it.hasNext()) { 
-        String s = it.next();​ +            String s = it.next();​ 
-        System.out.println(s);​ +            System.out.println(s);​ 
-        it.remove();​ // șterge elementul tocmai citit +            it.remove();​ // șterge elementul tocmai citit 
-    }+        }
  
-    ​// LinkedList<​Integer>​ ca listă + deque (ambele capete) +        ​// LinkedList<​Integer>​ ca listă + deque (ambele capete) 
-    obj.list2.addAll(Arrays.asList(1,​ 10, 20)); +        obj.list2.addAll(Arrays.asList(1,​ 10, 20)); 
-    obj.list2.addFirst(50);​ // capătul din stânga +        obj.list2.addFirst(50);​ // capătul din stânga 
-    obj.list2.addLast(17); ​ // capătul din dreapta+        obj.list2.addLast(17); ​ // capătul din dreapta
  
-    ​// Modificare „pe loc” cu ListIterator (ex.: înmulțește numerele pare cu 10) +        ​// Modificare „pe loc” cu ListIterator (ex.: înmulțește numerele pare cu 10) 
-    ListIterator<​Integer>​ li = obj.list2.listIterator();​ +        ListIterator<​Integer>​ li = obj.list2.listIterator();​ 
-    while (li.hasNext()) { +        while (li.hasNext()) { 
-        int x = li.next();​ +            int x = li.next();​ 
-        if (x % 2 == 0) li.set(x * 10); +            if (x % 2 == 0) li.set(x * 10); 
-    }+        } 
 + 
 +        // Afișare elemente (for-each) 
 +        for (Integer i : obj.list2) { 
 +            System.out.println(i);​ 
 +        ​}
  
-    ​// Afișare elemente ​(for-each+        ​// Sortare naturală ​(echivalent cu Collections.sort(list2)
-    for (Integer i : obj.list2) ​{ +        obj.list2.sort(Comparator.naturalOrder()); 
-        System.out.println(i);+        System.out.println(obj.list2);
     }     }
- 
-    // Sortare naturală (echivalent cu Collections.sort(list2)) 
-    obj.list2.sort(Comparator.naturalOrder());​ 
-    System.out.println(obj.list2);​ 
 } }
-``` +</​code>​
- +
-</​code>​+
  
 <note tip> <note tip>
-* Declarați mereu tipul elementelor: ​`List<​String>​``List<​Integer>​`.   +  ​* Declarați mereu tipul elementelor: ​//List<​String>​////List<​Integer>​//.   
-* Pentru eliminări în timpul parcurgerii folosiți ​`Iterator.remove()sau `removeIf(...)`.   +  * Pentru eliminări în timpul parcurgerii folosiți ​//Iterator.remove()// sau //removeIf(...)//.   
-* Alegeți **ArrayList** când accentul este pe citire după index și **LinkedList** când aveți inserări/​ștergeri locale cu iteratorul sau operații la ambele capete.+  * Alegeți **ArrayList** când accentul este pe citire după index și **LinkedList** când aveți inserări/​ștergeri locale cu iteratorul sau operații la ambele capete.
 </​note>  ​ </​note>  ​
- 
---- 
  
 == 1.3 Mulțimi (Set și SortedSet) == == 1.3 Mulțimi (Set și SortedSet) ==
  
-`Setmodelează noțiunea de **mulțime** în sens matematic: +**Set** modelează noțiunea de **mulțime** în sens matematic: ​nu pot exista două elemente ​//o1////o2// într-un Set pentru care //o1.equals(o2)// este //true//.
- +
-<note important>​ +
-Nu pot exista două elemente ​`o1``o2într-un ​`Setpentru care `o1.equals(o2)este `true`.+
 </​note>  ​ </​note>  ​
  
-`Setmoștenește operațiile de bază din `Collection`, fără a introduce metode proprii. +Set moștenește operațiile de bază din Collection, fără a introduce metode proprii. Implementări uzuale:
-Implementări uzuale:+
  
-* **HashSet** ​– rapid, *neordonat*;​ +  ​* **HashSet** ​rapid, ​**neordonat**; 
-* **LinkedHashSet** ​– păstrează ordinea inserării;​ +  * **LinkedHashSet** ​păstrează ordinea inserării;​ 
-* **TreeSet** ​– menține elementele **ordonate**.+  * **TreeSet** ​menține elementele **ordonate**.
  
-`SortedSetreprezintă un `Setîn care elementele sunt păstrate în **ordine crescătoare**:​+**SortedSet** reprezintă un Set în care elementele sunt păstrate în **ordine crescătoare**:​
  
-* fie după **ordinea naturală** (`Comparable`), +  ​* fie după **ordinea naturală** (//Comparable//), 
-* fie după un `Comparatorfurnizat la crearea colecției.+  * fie după un //Comparator// furnizat la crearea colecției.
  
 Implementarea standard de `SortedSet` este **TreeSet**. Implementarea standard de `SortedSet` este **TreeSet**.
  
 <note warning> <note warning>
-Într-un ​`SortedSet`, pentru orice două obiecte ​`o1``o2ale colecției+Într-un ​**SortedSet**, pentru orice două obiecte o1, o2 ale colecției, //o1.compareTo(o2)// sau //comparator.compare(o1,​ o2)// trebuie să fie **valid** (fără excepții), ​iar pentru ordinea naturală, elementele ​//null// **nu sunt permise**.
-  * `o1.compareTo(o2)sau `comparator.compare(o1,​ o2)trebuie să fie **valid** (fără excepții), ​  +
-  * pentru ordinea naturală, elementele ​`null**nu sunt permise** ​(`NullPointerException`).+
 </​note>  ​ </​note>  ​
- 
-Începând cu Java 9 există mulțimi **imutabile** prin `Set.of(...)` și `Set.copyOf(...)`. 
- 
-* `Set.of(...)` – creează direct o mulțime nemodificabilă (aruncă excepție dacă are duplicate); 
-* `Set.copyOf(...)` – copiază un set existent într-o versiune nemodificabilă. 
  
 <code java> <code java>
Line 174: Line 148:
  
 class Example { class Example {
-public static void main(String[] args) { +    ​public static void main(String[] args) { 
-// 1) HashSet ​– fără ordine, elimină duplicatele pe baza equals()/​hashCode() +        // 1) HashSet ​fără ordine, elimină duplicatele pe baza equals()/​hashCode() 
-Set<​String>​ hs = new HashSet<>​();​ +        Set<​String>​ hs = new HashSet<>​();​ 
-Collections.addAll(hs,​ "​Ana",​ "​Ana",​ "​Ion"​);​ +        Collections.addAll(hs,​ "​Ana",​ "​Ana",​ "​Ion"​);​ 
-System.out.println("​HashSet:​ " + hs); // ex.: [Ana, Ion+        System.out.println("​HashSet:​ " + hs); // ex.: [Ana, Ion]
- +
-``` +
-    // 2) LinkedHashSet – păstrează ordinea inserării +
-    Set<​Integer>​ lhs = new LinkedHashSet<>​(List.of(3,​ 1, 2, 1)); +
-    System.out.println("​LinkedHashSet:​ " + lhs); // [3, 1, 2]+
  
-    ​// 3TreeSet – comparator: lungime, apoi lexicografic +        ​// 2LinkedHashSet - păstrează ordinea inserării 
-    ​SortedSet<Stringgood = new TreeSet<>+        Set<Integerlhs = new LinkedHashSet<>​(List.of(312, 1)); 
-            Comparator.comparingInt(String::​length) +        System.out.println("​LinkedHashSet: " + lhs); // [312]
-                      .thenComparing(Comparator.naturalOrder()) +
-    ); +
-    good.addAll(List.of("​aa"​"​b"​"​bb"​)); +
-    System.out.println("​TreeSet ok: " + good); // [baabb]+
  
-    ​// Comparator problematic:​ compară DOAR lungimea ​-> unele elemente sunt excluse +        ​// 3) TreeSet ​comparator: lungime, apoi lexicografic 
-    SortedSet<​String> ​bad = new TreeSet<>​(Comparator.comparingInt(String::​length));​ +        SortedSet<​String> ​good = new TreeSet<>​( 
-    bad.addAll(List.of("​aa",​ "bb")); // "​bb"​ e ignorat: compare("​aa","​bb"​) ​== 0 +                ​Comparator.comparingInt(String::​length) 
-    System.out.println("​TreeSet ​problematic: " + bad); // [aa]+                          .thenComparing(Comparator.naturalOrder()) 
 +        ​); 
 +        good.addAll(List.of("​aa",​ "b", "​bb"​)); 
 +        System.out.println("​TreeSet ​ok: " + good); // [b, aa, bb]
  
-    ​// 4) Set imutabil (Java 9+) +        ​// Comparator problematic:​ compară DOAR lungimea -> unele elemente sunt excluse 
-    Set<​String> ​roles Set.of("ADMIN", "USER"); // nemodificabil +        ​SortedSet<​String> ​bad new TreeSet<>​(Comparator.comparingInt(String::​length));​ 
-    System.out.println("​Set.of: " + roles); +        bad.addAll(List.of("aa", "bb")); // "​bb"​ e ignorat: compare("​aa","​bb"​) == 0 
-    ​// roles.add("​GUEST"​); ​     // -> UnsupportedOperationException +        System.out.println("​TreeSet problematic: " + bad); // [aa] 
-    ​// Set.of("​A",​ "​A"​); ​       // -> IllegalArgumentException (duplicate la creare)+    ​}
 } }
-``` +</​code>​
- +
-</​code>​+
  
---- 
  
 == 1.4 Dicționare (Map și SortedMap) == == 1.4 Dicționare (Map și SortedMap) ==
  
-`Mapdescrie structuri care asociază fiecărei **chei** o **valoare**:​+**Map** descrie structuri care asociază fiecărei **chei** o **valoare**:​
  
-* **cheile sunt unice**; +  ​* **cheile sunt unice**; 
-* valorile pot fi duplicate.+  * valorile pot fi duplicate.
  
-Ierarhia ​`Mapeste separată de `Collection`. Operații tipice:+Ierarhia ​**Map** este separată de //Collection//. Operații tipice: 
 +  * inserare: //put(k, v)//; 
 +  * citire: //get(k)//, //​getOrDefault(k,​ valoareImplicita)//;​ 
 +  * test de apartenență:​ //​containsKey//,​ //​containsValue//;​ 
 +  * eliminare: //​remove(k)//;​ 
 +  * parcurgere: //​entrySet()//,​ //​keySet()//,​ //​values()//​.
  
-* inserare: `put(kv)`; +În practicăcele mai folosite implementări sunt:
-* citire: `get(k)`, `getOrDefault(k,​ valoareImplicită)`;​ +
-* test de apartenență: `containsKey`,​ `containsValue`;​ +
-* eliminare: `remove(k)`;​ +
-* parcurgere: `entrySet()`,​ `keySet()`, `values()`.+
  
-Implementări uzuale:+  * **HashMap** - rapid, fără ordine de iterare; permite o cheie //null// și valori //null//; 
 +  * **LinkedHashMap** - ca //​HashMap//,​ dar păstrează ordinea inserării;​ 
 +  * **TreeMap** - menține cheile **ordonate** (natural sau prin //​Comparator//​);​ nu acceptă chei //null//; 
 +  * **Hashtable** - tip vechi; se preferă //HashMap// sau //​ConcurrentHashMap//​.
  
-* **HashMap** – rapid, fără ordine de iterare; permite o cheie `null` și valori `null`; +**SortedMap** este un Map cu chei păstrate în **ordine crescătoare**;​ implementarea clasică este **TreeMap**.
-* **LinkedHashMap** – ca `HashMap`, dar păstrează ordinea inserării (sau a accesului – util pentru cache LRU); +
-* **TreeMap** – menține cheile **ordonate** (natural sau prin `Comparator`);​ nu acceptă chei `null`; +
-* **Hashtable** – tip vechi, sincronizat;​ în cod modern se preferă `HashMap` sau `ConcurrentHashMap`. +
- +
-`SortedMap` ​este un `Mapcu chei păstrate în **ordine crescătoare**;​ implementarea clasică este `TreeMap`. +
- +
-În Java 9+, `Map.of(...)` și `Map.copyOf(...)` creează hărți ​**imutabile**.+
  
 <code java> <code java>
Line 240: Line 202:
  
 class MiniMapDemo { class MiniMapDemo {
-public static void main(String[] args) { +    ​public static void main(String[] args) { 
-// 1) HashMap ​– fără ordine +        // 1) HashMap ​fără ordine 
-Map<​String,​ Integer> freq = new HashMap<>​();​ +        Map<​String,​ Integer> freq = new HashMap<>​();​ 
-for (String w : List.of("​ana",​ "​are",​ "​ana",​ "​mere"​)) { +        for (String w : List.of("​ana",​ "​are",​ "​ana",​ "​mere"​)) { 
-freq.merge(w,​ 1, Integer::​sum);​ // new = 1, altfel +1 +            freq.merge(w,​ 1, Integer::​sum);​ // new = 1, altfel +1 
-+        
-System.out.println("​HashMap (fara ordine): " + freq); +        System.out.println("​HashMap (fara ordine): " + freq); 
-System.out.println("​getOrDefault('​banane',​ 0) = " +        System.out.println("​getOrDefault('​banane',​ 0) = " 
-+ freq.getOrDefault("​banane",​ 0));+            + freq.getOrDefault("​banane",​ 0));
  
-``` +        ​// 2) LinkedHashMap ​păstrează ordinea inserării 
-    ​// 2) LinkedHashMap ​– păstrează ordinea inserării +        Map<​Integer,​ String> lhm = new LinkedHashMap<>​();​ 
-    Map<​Integer,​ String> lhm = new LinkedHashMap<>​();​ +        lhm.put(2, "​B"​);​ 
-    lhm.put(2, "​B"​);​ +        lhm.put(1, "​A"​);​ 
-    lhm.put(1, "​A"​);​ +        lhm.put(3, "​C"​);​ 
-    lhm.put(3, "​C"​);​ +        System.out.println("​LinkedHashMap (ordine inserare): " + lhm.keySet());​ // [2, 1, 3]
-    System.out.println("​LinkedHashMap (ordine inserare): " + lhm.keySet());​ // [2, 1, 3]+
  
-    ​// 3) TreeMap ​– chei ordonate (natural) +        ​// 3) TreeMap ​chei ordonate (natural) 
-    Map<​String,​ Integer> sorted = new TreeMap<>​(freq);​ // sortează după cheia String +        Map<​String,​ Integer> sorted = new TreeMap<>​(freq);​ // sortează după cheia String 
-    System.out.println("​TreeMap (chei ordonate): " + sorted);+        System.out.println("​TreeMap (chei ordonate): " + sorted);
  
-    ​// 4) Map imutabil (Java 9+) +        ​// 4) Parcurgere eficientă cu entrySet() 
-    Map<​String,​ Integer> roles = Map.of("​ADMIN",​ 1, "​USER",​ 2); // nemodificabil +        for (Map.Entry<​String,​ Integer> e : sorted.entrySet()) { 
-    System.out.println("​Map.of:​ " + roles); +            System.out.println(e.getKey() + " => " + e.getValue());​ 
-    // roles.put("​GUEST",​ 3); // -> UnsupportedOperationException +        }
- +
-    // 5) Parcurgere eficientă cu entrySet() +
-    for (Map.Entry<​String,​ Integer> e : sorted.entrySet()) { +
-        System.out.println(e.getKey() + " => " + e.getValue());​+
     }     }
 } }
-``` +</​code>​
- +
-</​code>​ +
- +
----+
  
 === 2. Iteratori și enumerări === === 2. Iteratori și enumerări ===
  
-Enumerările și iteratorii descriu modalități de **parcurgere secvențială** a unei colecții, indiferent dacă este indexată sau nu.+Enumerările și iteratorii descriu modalități de **parcurgere secvențială** a unei colecții. ​În Java, parcurgerea se face în principal cu:
  
-În Java modern, parcurgerea se face în principal cu: +  * **Iterator** (și pentru liste, ​//ListIterator//), 
- +  * sintaxa ​**for-each**//for (T e : colectie) { ... }//.
-`Iterator(și pentru liste, ​`ListIterator`), +
-sau cu sintaxa ​`for-each``for (T e : colectie) { ... }`. +
- +
-`Enumeration` și `Vector` sunt considerate tipuri **legacy** (istorice). +
- +
----+
  
 == 2.1 Enumeration == == 2.1 Enumeration ==
  
-`Enumerationeste o interfață veche pentru parcurgere. +**Enumeration** este o interfață veche pentru parcurgere. O mai întâlnim la //Vector// sau o putem obține din orice colecție prin //Collections.enumeration(...)//. În cod modern, se preferă ​//Iterator//.
- +
-O mai întâlnim la `Vectorsau o putem obține din orice colecție prin `Collections.enumeration(...)`. În cod modern, se preferă ​`Iterator`.+
  
 <code java> <code java>
Line 301: Line 246:
  
 class DemoEnumeration { class DemoEnumeration {
-public static void main(String[] args) { +    ​public static void main(String[] args) { 
-List<​Integer>​ list = List.of(3, 7, 0, 5); +        List<​Integer>​ list = List.of(3, 7, 0, 5); 
-Enumeration<​Integer>​ en = Collections.enumeration(list);​ // din orice Collection+        Enumeration<​Integer>​ en = Collections.enumeration(list);​ // din orice Collection
  
-``` +        ​while (en.hasMoreElements()) { 
-    ​while (en.hasMoreElements()) { +            int x = en.nextElement();​ // Integer, nu Object (datorită generics) 
-        int x = en.nextElement();​ // Integer, nu Object (datorită generics) +            System.out.println(x);​ 
-        System.out.println(x);​+        }
     }     }
-} 
-``` 
  
-} </​code>​+ 
 +</​code>​
  
---- 
  
 == 2.2 Iterator == == 2.2 Iterator ==
  
-`Iteratoroferă metodele: +**Iterator** oferă metodele: 
- +  * **hasNext()** - mai există elemente?; 
-`hasNext()` – mai există elemente? +  * **next()** - returnează elementul următor; 
-`next()` – returnează elementul următor; +  * **remove()** - șterge ultimul element returnat de next().
-`remove()` – șterge ultimul element returnat de `next()`.+
  
 <note important>​ <note important>​
-Dacă modificați colecția în timpul parcurgerii,​ folosiți **`iterator.remove()`** (sau, mai simplu, ​`removeIf(...)pe colecție). ​  +Dacă modificați colecția în timpul parcurgerii,​ folosiți **iterator.remove()** (sau, mai simplu, ​//removeIf(...)// pe colecție). ​  
- +</​note>​
-Apeluri de tipul `list.remove(e)` direct într-un `for-each` pot produce `ConcurrentModificationException`. ​</​note>​+
  
 <code java> <code java>
Line 334: Line 275:
  
 class DemoIterator { class DemoIterator {
-public static void main(String[] args) { +    ​public static void main(String[] args) { 
-List<​String>​ l = new ArrayList<>​(List.of("​ana",​ "​bad",​ "​ion",​ "​bogdan"​));​+        List<​String>​ l = new ArrayList<>​(List.of("​ana",​ "​bad",​ "​ion",​ "​bogdan"​));​
  
-``` +        ​// Variantă modernă: removeIf 
-    ​// Variantă modernă: removeIf +        l.removeIf(s -> s.length() == 4); // șterge elementele cu 4 litere
-    l.removeIf(s -> s.length() == 4); // șterge elementele cu 4 litere+
  
-    ​// Echivalent cu iterator.remove() +        ​// Echivalent cu iterator.remove() 
-    Iterator<​String>​ it = l.iterator();​ +        Iterator<​String>​ it = l.iterator();​ 
-    while (it.hasNext()) { +        while (it.hasNext()) { 
-        String s = it.next();​ +            String s = it.next();​ 
-        if (s.startsWith("​b"​)) it.remove();​ // sigur +            if (s.startsWith("​b"​)) it.remove();​ // sigur 
-    }+        }
  
-    ​System.out.println(l);​+        ​System.out.println(l);​ 
 +    }
 } }
-``` +</​code>​
- +
-</​code>​ +
- +
----+
  
 == 2.3 ListIterator (liste, ambele sensuri) == == 2.3 ListIterator (liste, ambele sensuri) ==
  
-`ListIteratorextinde ​`Iteratorși oferă în plus:+//ListIterator// extinde Iterator și oferă în plus:
  
-* navigare înapoi: ​`previous()`+  ​* navigare înapoi: ​//previous()//
-* poziții: ​`nextIndex()``previousIndex()`+  * poziții: ​//nextIndex()////previousIndex()//
-* inserare: ​`add(...)`+  * inserare: ​//add(...)//
-* înlocuire: ​`set(...)`.+  * înlocuire: ​//set(...)//.
  
-Este util când trebuie să modificați lista pe loc” sau să o parcurgeți bidirecțional.+Este util când trebuie să modificați lista "pe loc" ​sau să o parcurgeți bidirecțional.
  
 <code java> <code java>
Line 371: Line 308:
  
 class DemoListIterator { class DemoListIterator {
-public static void main(String[] args) { +    ​public static void main(String[] args) { 
-List<​Integer>​ l = new ArrayList<>​(List.of(0,​ 1, 2, 0, 3));+        List<​Integer>​ l = new ArrayList<>​(List.of(0,​ 1, 2, 0, 3));
  
-``` +        ​// 1) Înlocuire „pe loc”: 0 -> 10 
-    ​// 1) Înlocuire „pe loc”: 0 -> 10 +        ListIterator<​Integer>​ it = l.listIterator();​ 
-    ListIterator<​Integer>​ it = l.listIterator();​ +        while (it.hasNext()) { 
-    while (it.hasNext()) { +            if (it.next() == 0) it.set(10);​ 
-        if (it.next() == 0) it.set(10);​ +        }
-    }+
  
-    ​// 2) Inserare după 1 +        ​// 2) Inserare după 1 
-    ListIterator<​Integer>​ it2 = l.listIterator();​ +        ListIterator<​Integer>​ it2 = l.listIterator();​ 
-    while (it2.hasNext()) { +        while (it2.hasNext()) { 
-        if (it2.next() == 1) {  // elementul curent 1; cursorul este după 1 (între 1 și 2) +            if (it2.next() == 1) {  // elementul curent 1; cursorul este după 1 (între 1 și 2) 
-            it2.add(99); ​       // inserează între 1 și 2 +                it2.add(99); ​       // inserează între 1 și 2 
-            break;+                break; 
 +            }
         }         }
-    } 
  
-    ​System.out.println(l);​ // [10, 1, 99, 2, 10, 3]+        ​System.out.println(l);​ // [10, 1, 99, 2, 10, 3] 
 +    }
 } }
-``` +</​code>​
- +
-</​code>​+
  
 <note warning> <note warning>
-Dacă parametrizăm colecția/​iteratorul (ex. `List<​String>​``Iterator<​String>​`), metodele ​`next()`/`previous()întorc direct **tipul elementului** și nu mai avem nevoie de cast.  ​+Dacă parametrizăm colecția/​iteratorul (ex. //List<​String>​////Iterator<​String>​//), metodele next()/​previous() întorc direct **tipul elementului** și nu mai avem nevoie de cast.  ​
  
-Dacă folosim raw types (ex. `List``Iterator`), `next()`/`previous()întorc ​`Objectși conversia devine responsabilitatea programatorului ​– cu risc de `ClassCastExceptionla rulare. </​note>​+Dacă folosim raw types (ex. //List////Iterator//), next()/​previous() întorc ​**Object** și conversia devine responsabilitatea programatorului ​cu risc de //ClassCastException// la rulare. </​note>​
  
 <code java> <code java>
Line 405: Line 340:
  
 class ObservatieIterator { class ObservatieIterator {
-public static void main(String[] args) { +    ​public static void main(String[] args) { 
-// 1) Parametrizat (recomandat):​ fără cast, sigur +        // 1) Parametrizat (recomandat):​ fără cast, sigur 
-List<​String>​ l = new ArrayList<>​(List.of("​ana",​ "​ion"​));​ +        List<​String>​ l = new ArrayList<>​(List.of("​ana",​ "​ion"​));​ 
-Iterator<​String>​ it = l.iterator();​ +        Iterator<​String>​ it = l.iterator();​ 
-String s1 = it.next(); // String, nu Object +        String s1 = it.next(); // String, nu Object 
-ListIterator<​String>​ li = l.listIterator(l.size());​ +        ListIterator<​String>​ li = l.listIterator(l.size());​ 
-String last = li.previous();​ // tot String +        String last = li.previous();​ // tot String 
-System.out.println("​OK (generic): " + s1 + ", " + last);+        System.out.println("​OK (generic): " + s1 + ", " + last);
  
-``` +        ​// 2) Neparametrizat (raw type): next()/​previous() -> Object, necesită cast 
-    ​// 2) Neparametrizat (raw type): next()/​previous() -> Object, necesită cast +        List raw = new ArrayList();​ // WARNING: unchecked/​raw type 
-    List raw = new ArrayList();​ // WARNING: unchecked/​raw type +        raw.add("​text"​);​ // compilează 
-    raw.add("​text"​);​ // compilează +        raw.add(10); ​    // compilează (amestec de tipuri!) 
-    raw.add(10); ​    // compilează (amestec de tipuri!) +        Iterator itr = raw.iterator();​ // WARNING: raw 
-    Iterator itr = raw.iterator();​ // WARNING: raw +        Object o1 = itr.next(); // "​text"​ ca Object 
-    Object o1 = itr.next(); // "​text"​ ca Object +        Object o2 = itr.next(); // 10 ca Object
-    Object o2 = itr.next(); // 10 ca Object+
  
-    ​// Castul e responsabilitatea ta; poate eșua la rulare: +        ​// Castul e responsabilitatea ta; poate eșua la rulare: 
-    try { +        try { 
-        String s2 = (String) o2; // ClassCastException (Integer -> String) +            String s2 = (String) o2; // ClassCastException (Integer -> String) 
-        System.out.println(s2);​ +            System.out.println(s2);​ 
-    } catch (ClassCastException ex) { +        } catch (ClassCastException ex) { 
-        System.out.println("​Eroare la rulare (raw type): " + ex);+            System.out.println("​Eroare la rulare (raw type): " + ex); 
 +        }
     }     }
 } }
-``` +</​code>​
- +
-</​code>​ +
- +
----+
  
 === 3. Genericitate (generics) === === 3. Genericitate (generics) ===
  
-Fără generics, o colecție **raw** acceptă obiecte de orice fel, iar la citire trebuie să facem conversii (`cast`). Codul devine greu de urmărit, iar amestecul de tipuri poate produce ușor `ClassCastExceptionla rulare.+Fără ​**generics**, o colecție **raw** acceptă obiecte de orice fel, iar la citire trebuie să facem conversii (//cast//). Codul devine greu de urmărit, iar amestecul de tipuri poate produce ușor //ClassCastException// la rulare.
  
 Genericitatea rezolvă exact aceste probleme: Genericitatea rezolvă exact aceste probleme:
- +  ​* declarăm de la început **tipul elementelor**;​ 
-* declarăm de la început **tipul elementelor**;​ +  * compilatorul verifică și **interzice** inserarea altor tipuri.
-* compilatorul verifică și **interzice** inserarea altor tipuri.+
  
 <code java> <code java>
Line 454: Line 384:
 int y = list.get(1); ​           // tot fără cast int y = list.get(1); ​           // tot fără cast
  
-// list.add("​Text"​);​ // eroare de compilare: tip incompatibil </​code>​+// list.add("​Text"​);​ // eroare de compilare: tip incompatibil 
 +</​code>​
  
 <note warning> <note warning>
-Dacă aveți un caz real în care elementele pot fi de mai multe tipuri, NU reveniți la raw types. ​  +Dacă aveți un caz real în care elementele pot fi de mai multe tipuri, ​**NU** reveniți la raw types. Folosiți:​ 
-Folosiți:​ +  * **List<​Object>​** și verificați cu `instanceof` înainte de cast,  ​
-  * `List<​Object>​și verificați cu `instanceof` înainte de cast,  ​+
   * sau proiectați o ierarhie comună (o interfață,​ o clasă părinte) și parametrizați lista cu acest **supertip**.  ​   * sau proiectați o ierarhie comună (o interfață,​ o clasă părinte) și parametrizați lista cu acest **supertip**.  ​
  
-În toate celelalte situații folosiți colecții parametrizate (`List<​Student>​``Map<​String,​ Integer>`) pentru **siguranță și claritate**. </​note>​+În toate celelalte situații folosiți colecții parametrizate (//List<​Student>​////Map<​String,​ Integer>//) pentru **siguranță și claritate**. </​note>​
  
---- 
  
 === 4. equals() vs hashCode() === === 4. equals() vs hashCode() ===
  
-Metoda ​`equals(Object)stabilește **egalitatea logică** dintre două instanțe. Definiția egalității aparține modelului de date (ex.: doi studenți pot fi considerați egali prin CNP, sau prin combinație de câmpuri).+Metoda ​**equals(Object)** stabilește **egalitatea logică** dintre două instanțe. Definiția egalității aparține modelului de date (ex.: doi studenți pot fi considerați egali prin CNP, sau prin combinație de câmpuri).
  
-Compararea unei instanțe non-null cu referința `null` produce întotdeauna rezultat de inegalitate. Pentru tipuri numerice în virgulă mobilă se recomandă `Double.compare` / `Float.compare`. +Metoda ​**hashCode()** returnează un **rezumat numeric** (int) al obiectului. Colecțiile pe bază de dispersie (//HashSet////HashMap//) folosesc acest rezumat pentru localizare rapidă.
- +
-Metoda ​`hashCode()returnează un **rezumat numeric** (`int`) al obiectului. Colecțiile pe bază de dispersie (`HashSet``HashMap`) folosesc acest rezumat pentru localizare rapidă.+
  
 <note important>​ <note important>​
-* Dacă două obiecte sunt **egale** prin `equals`, atunci **trebuie** să aibă același ​`hashCode()`.   +  ​* Dacă două obiecte sunt **egale** prin //equals//, atunci **trebuie** să aibă același ​//hashCode()//.
-* Inversul nu este obligatoriu (două obiecte diferite pot avea același hashCode).+
 </​note>  ​ </​note>  ​
  
-În `HashSetși `HashMap`, operațiile de apartenență și unicitate funcționează astfel:+În **HashSet** și **HashMap**, operațiile de apartenență și unicitate funcționează astfel:
  
-1. colecția calculează ​`hashCode()și alege „bucket-ul”+  - colecția calculează ​**hashCode()** și alege locul elementului
-2. confirmă prezența prin `equals()`.+  ​- ​confirmă prezența prin **equals()**.
  
 <code java> <code java>
Line 489: Line 415:
 class EqualsHashDemo { class EqualsHashDemo {
  
-``` +    ​// Varianta corectă: equals și hashCode folosesc ACELEAȘI câmpuri 
-// Varianta corectă: equals și hashCode folosesc ACELEAȘI câmpuri +    static final class GoodStudent { 
-static final class GoodStudent { +        private final String id; 
-    private final String id; +        GoodStudent(String id) { this.id = id; }
-    GoodStudent(String id) { this.id = id; }+
  
-    ​@Override public boolean equals(Object o) { +        ​@Override 
-        if (this == o) return true; +        ​public boolean equals(Object o) { 
-        if (!(o instanceof GoodStudent g)) return false; +            if (this == o) return true; 
-        return Objects.equals(id,​ g.id); +            if (!(o instanceof GoodStudent g)) return false; 
-    }+            return Objects.equals(id,​ g.id); 
 +        }
  
-    ​@Override public int hashCode() { +        ​@Override 
-        return Objects.hash(id);​+        ​public int hashCode() { 
 +            return Objects.hash(id);​ 
 +        }
     }     }
-} 
  
-// Varianta greșită: equals suprascris, hashCode NU +    ​// Varianta greșită: equals suprascris, hashCode NU 
-static final class BadStudent { +    static final class BadStudent { 
-    private final String id; +        private final String id; 
-    BadStudent(String id) { this.id = id; }+        BadStudent(String id) { this.id = id; }
  
-    ​@Override public boolean equals(Object o) { +        ​@Override 
-        if (this == o) return true; +        ​public boolean equals(Object o) { 
-        if (!(o instanceof BadStudent b)) return false; +            if (this == o) return true; 
-        return Objects.equals(id,​ b.id);+            if (!(o instanceof BadStudent b)) return false; 
 +            return Objects.equals(id,​ b.id); 
 +        } 
 +        // (fără hashCode) -> folosește Object.hashCode(),​ diferit pentru instanțe diferite
     }     }
-    // (fără hashCode) -> folosește Object.hashCode(),​ diferit pentru instanțe diferite 
-} 
  
-public static void main(String[] args) { +    ​public static void main(String[] args) { 
-    // Caz corect +        // Caz corect 
-    GoodStudent a1 = new GoodStudent("​42"​);​ +        GoodStudent a1 = new GoodStudent("​42"​);​ 
-    GoodStudent a2 = new GoodStudent("​42"​);​+        GoodStudent a2 = new GoodStudent("​42"​);​
  
-    ​System.out.println("​a1.equals(a2) = " + a1.equals(a2));​ // true +        ​System.out.println("​a1.equals(a2) = " + a1.equals(a2));​ // true 
-    System.out.println("​a1.hashCode = " + a1.hashCode() +        System.out.println("​a1.hashCode = " + a1.hashCode() 
-            + " | a2.hashCode = " + a2.hashCode());​ // egale+                + " | a2.hashCode = " + a2.hashCode());​ // egale
  
-    ​Set<​GoodStudent>​ good = new HashSet<>​();​ +        ​Set<​GoodStudent>​ good = new HashSet<>​();​ 
-    good.add(a1);​ +        good.add(a1);​ 
-    good.add(a2);​ +        good.add(a2);​ 
-    System.out.println("​HashSet<​GoodStudent>​.size = " + good.size());​ // 1+        System.out.println("​HashSet<​GoodStudent>​.size = " + good.size());​ // 1
  
-    ​// Caz greșit +        ​// Caz greșit 
-    BadStudent b1 = new BadStudent("​42"​);​ +        BadStudent b1 = new BadStudent("​42"​);​ 
-    BadStudent b2 = new BadStudent("​42"​);​+        BadStudent b2 = new BadStudent("​42"​);​
  
-    ​System.out.println("​b1.equals(b2) = " + b1.equals(b2));​ // true +        ​System.out.println("​b1.equals(b2) = " + b1.equals(b2));​ // true 
-    System.out.println("​b1.hashCode = " + b1.hashCode() +        System.out.println("​b1.hashCode = " + b1.hashCode() 
-            + " | b2.hashCode = " + b2.hashCode());​ // diferite+                + " | b2.hashCode = " + b2.hashCode());​ // diferite
  
-    ​Set<​BadStudent>​ bad = new HashSet<>​();​ +        ​Set<​BadStudent>​ bad = new HashSet<>​();​ 
-    bad.add(b1);​ +        bad.add(b1);​ 
-    bad.add(b2);​ +        bad.add(b2);​ 
-    System.out.println("​HashSet<​BadStudent>​.size = " + bad.size());​ // 2 (duplicate)+        System.out.println("​HashSet<​BadStudent>​.size = " + bad.size());​ // 2 (duplicate)
  
-    ​System.out.println("​bad.contains(new BadStudent(\"​42\"​)) = " +        ​System.out.println("​bad.contains(new BadStudent(\"​42\"​)) = " 
-            + bad.contains(new BadStudent("​42"​)));​ // false+                + bad.contains(new BadStudent("​42"​)));​ // false 
 +    }
 } }
-``` +</​code>​
- +
-</​code>​+
  
  
  
poo/breviare/breviar-07.1763377226.txt.gz · Last modified: 2025/11/17 13:00 by george.tudor1906
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