Differences

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

Link to this comparison view

poo:breviare:breviar-07 [2025/11/17 20:32]
george.tudor1906
poo:breviare:breviar-07 [2025/11/19 09:25] (current)
george.tudor1906
Line 6: Line 6:
  
 == 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 231: Line 233:
 === 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 252: 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 285: 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 322: 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 356: 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 405: 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 440: 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.1763404357.txt.gz · Last modified: 2025/11/17 20:32 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