Differences

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

Link to this comparison view

poo-ca-cd:laboratoare:programare-functionala-lambda-si-streamuri [2025/12/08 09:49]
florian_luis.micu created
poo-ca-cd:laboratoare:programare-functionala-lambda-si-streamuri [2025/12/10 01:04] (current)
florian_luis.micu [Obiective]
Line 3: Line 3:
   * Autori: [[miculuis1@gmail.com | Florian-Luis Micu ]], [[sorinabuf@gmail.com | Sorina-Anamaria Buf ]], [[stefancocioran@gmail.com | Ștefan Cocioran ]]   * Autori: [[miculuis1@gmail.com | Florian-Luis Micu ]], [[sorinabuf@gmail.com | Sorina-Anamaria Buf ]], [[stefancocioran@gmail.com | Ștefan Cocioran ]]
   * Data publicării:​ 08.12.2025   * Data publicării:​ 08.12.2025
-  * Data ultimei modificări: ​08.12.2025+  * Data ultimei modificări: ​10.12.2025 
 +    * reordonare secțiuni. 
 +    * introducerea Generic Singleton Factory ca materie [Optional]. 
 +    * introducerea CRTP ca materie [Optional].
  
 ======Obiective====== ======Obiective======
Line 17: Line 20:
   * compilarea cu warning-uri pentru raw types și dangerous casts   * compilarea cu warning-uri pentru raw types și dangerous casts
   * glosar pentru denumirea tipurilor generice.   * glosar pentru denumirea tipurilor generice.
 +  * prezentarea pattern-ului avansat Generic Singleton Factory.
 +  * prezentarea pattern-ului CRTP.
  
 <note warning> <note warning>
Line 23: Line 28:
 </​note>​ </​note>​
  
-======🏷️ ​Genericics======+======🏷️ ​Generics======
  
 Genericitatea este unul dintre cele mai elegante mecanisme introduse în Java pentru a ajuta la scrierea unui cod **general**,​ **sigur** și **reutilizabil**. Genericitatea este unul dintre cele mai elegante mecanisme introduse în Java pentru a ajuta la scrierea unui cod **general**,​ **sigur** și **reutilizabil**.
Line 313: Line 318:
 Vom vedea mai jos ce face exact ''​extends''​ în cadrul generics. Vom vedea mai jos ce face exact ''​extends''​ în cadrul generics.
 </​note>​ </​note>​
-=====Tipuri generice cu limitări===== 
- 
-Există situații în care dorim ca un parametru generic să fie **restricționat** la un anumit tip (sau **subclase** ale acestuia). 
- 
-<code java> 
-public class NumberBox<​T extends Number> { 
-    private T value; 
-} 
-</​code>​ 
- 
-Această constrângere oferă două avantaje: 
-  * garantează că putem apela metodele definite în ''​Number'',​ 
-  * previne utilizarea unor tipuri incompatibile (ex. ''​String''​). 
- 
-<note tip> 
-Vom vedea mai jos ce presupune exact construcția ''​extends''​ în cadrul generics. 
-</​note>​ 
- 
-De asemenea, Java permite **bounded type parameters multiple**: 
- 
-<code java> 
-public <T extends Number & Comparable<​T>>​ void process(T value) { ... } 
-</​code>​ 
- 
-Această combinație este utilă în **algoritmi de sortare** sau **agregare numerică**. 
- 
-Un alt exemplu destul de des folosit cu limitări în tipuri generice este acesta: 
- 
-<code java> 
-public static <T extends Comparable<​T>>​ T max(T a, T b) { 
-    return a.compareTo(b) > 0 ? a : b; 
-} 
-</​code>​ 
- 
-Practic, am făcut o metodă care întoarce maximul dintre două obiecte, doar dacă acel obiect **implementează interfața Comparable** pentru a putea folosi metoda ''​compareTo''​. 
- 
- 
  
 =====Wildcards – flexibilitate în genericitate===== =====Wildcards – flexibilitate în genericitate=====
Line 357: Line 325:
 ====Wildcard neîngrădit (?)==== ====Wildcard neîngrădit (?)====
  
-Folosim ? când tipul nu este relevant, ci doar existența lui:+Folosim ​''​?'' ​când tipul nu este relevant, ci doar existența lui:
  
 <code java> <code java>
Line 466: Line 434:
   - Metoda publică primește orice listă (''​List<?>''​).   - Metoda publică primește orice listă (''​List<?>''​).
   - Metoda privată capturează wildcard-ul ca T și permite operații sigure.   - Metoda privată capturează wildcard-ul ca T și permite operații sigure.
 +
 +=====Tipuri generice cu limitări=====
 +
 +Există situații în care dorim ca un parametru generic să fie **restricționat** la un anumit tip (sau **subclase** ale acestuia). ​
 +
 +Pentru a limita un tip putem folosi keyword-ul ''​extends'',​ astfel doar o clasă moștenită de clasa extinsă poate fi folosită. În acest caz, această noțiune se cheamă **bounded generics**.
 +
 +<code java>
 +public class NumberBox<​T extends Number> {
 +    private T value;
 +}
 +</​code>​
 +
 +Această constrângere oferă două avantaje:
 +  * garantează că putem apela metodele definite în ''​Number'',​
 +  * previne utilizarea unor tipuri incompatibile:​
 +    * ''​NumberBox<​Integer>''​ - valid
 +    * ''​NumberBox<​Double>''​ - valid
 +    * ''​NumberBox<​String>''​ - invalid
 +
 +====Limitări multiple====
 +
 +De asemenea, Java permite **multiple bounded type parameters**:​
 +
 +<code java>
 +public <T extends Number & Comparable<​T>>​ void process(T value) { ... }
 +</​code>​
 +
 +Ordinea este importantă:​
 +  - prima limitare trebuie să fie o clasă
 +  - restul pot fi interfețe
 +
 +Combinația de mai sus este utilă în **algoritmi de sortare** sau **agregare numerică**.
 +
 +Un alt exemplu destul de des folosit cu limitări în tipuri generice este acesta:
 +
 +<code java>
 +public static <T extends Comparable<​T>>​ T max(T a, T b) {
 +    return a.compareTo(b) > 0 ? a : b;
 +}
 +</​code>​
 +
 +Practic, am făcut o metodă care întoarce maximul dintre două obiecte, doar dacă acel obiect **implementează interfața Comparable** pentru a putea folosi metoda ''​compareTo''​.
 +
 +
 +
  
 =====Type erasure – cum funcționează generics sub capotă===== =====Type erasure – cum funcționează generics sub capotă=====
Line 552: Line 566:
 =====Invarianță,​ Covarianță și Contravarianță===== =====Invarianță,​ Covarianță și Contravarianță=====
  
-Java are trei moduri principale de a trata relațiile dintre tipurile generice.+Java are **trei moduri principale** de a trata relațiile dintre tipurile generice.
  
 ====Invarianță (comportamentul implicit)==== ====Invarianță (comportamentul implicit)====
Line 582: Line 596:
 ====Contravarianță (? super T)==== ====Contravarianță (? super T)====
  
-Pentru a defini un scenariu de moștenire ca în exemplul despre invarianță,​ putem folosi bounded wildcards, astfel listelor li se poate permite să accepte **tipuri părinte**.+Pentru a defini un scenariu de moștenire ca în exemplul despre invarianță,​ putem folosi ​**bounded wildcards**, astfel listelor li se poate permite să accepte **tipuri părinte**.
  
 <code java> <code java>
Line 590: Line 604:
 Aceasta permite scrierea în colecție (''​add(Integer)''​),​ dar **nu permite** citirea unui tip specific. Aceasta permite scrierea în colecție (''​add(Integer)''​),​ dar **nu permite** citirea unui tip specific.
  
-====De ce List<​String>​ nu este List<​Object>​====+====De ce List<​String>​ nu este List<​Object>​?====
  
 În mod natural, ai putea crede că dacă ''​String''​ este un subtip al lui ''​Object'',​ atunci și ''​List<​String>''​ ar trebui să fie un subtip al lui ''​List<​Object>''​. Dar nu este așa. În mod natural, ai putea crede că dacă ''​String''​ este un subtip al lui ''​Object'',​ atunci și ''​List<​String>''​ ar trebui să fie un subtip al lui ''​List<​Object>''​. Dar nu este așa.
Line 642: Line 656:
  
 <note tip> <note tip>
-Arrays verifică tipurile la runtime, în schimb generics nu o fac.+  * **Reified** înseamnă că informația despre **tip** există și este păstrată la **runtime**. 
 +  * Arrays verifică tipurile la **runtime**, în schimb generics nu o fac.
 </​note>​ </​note>​
 +
 +=====[Nice to know] Glosar – Litere folosite în Generics=====
 +
 +^Literă ^ Semnificație^
 +|T | Type|
 +|E | Element (în special în colecții)|
 +|K | Key|
 +|V | Value|
 +|R | Result|
 +|? | wildcard, tip necunoscut|
 +
  
 =====[Optional] Warning-uri de compilare===== =====[Optional] Warning-uri de compilare=====
Line 658: Line 684:
 IntelliJ va rula automat această comandă pentru voi. IntelliJ va rula automat această comandă pentru voi.
 </​note>​ </​note>​
-=====[Nice to know] Glosar – Litere folosite în Generics===== 
  
-^Literă ^ Semnificație^ +=====[Optional] Generic Singleton Factory===== 
-|| Type| + 
-|E | Element ​(în special în colecții)| +Acesta este un pattern foarte elegant, folosit intern în **JDK**, mai ales în ''​Collections''​. 
-|K | Key| + 
-|V | Value| +O singură instanță poate fi folosită pentru **toate tipurile**, iar generics asigură siguranța. 
-|R | Result| + 
-|| wildcard, ​tip necunoscut|+<code java> 
 +public class SingletonFactory { 
 +    private static final Box<​Object>​ INSTANCE = new Box<>​();​ 
 + 
 +    @SuppressWarnings("​unchecked"​) 
 +    ​public static <T> Box<​T>​ getInstance() { 
 +        ​return ​(Box<​T>​) INSTANCE; 
 +    } 
 +
 +</​code>​ 
 + 
 +Utilizare:​ 
 + 
 +<code java> 
 +Box<​String>​ a = SingletonFactory.getInstance();​ 
 +Box<​Integer>​ b = SingletonFactory.getInstance();​ 
 +</​code>​ 
 + 
 + 
 +Observație: 
 +  * Instanța din spate e aceeași (''​Box<​Object>''​). 
 +  * Dar fiecare apelant primește o versiune tipizată în siguranță. 
 + 
 +<note important>​ 
 +De ce funcționează codul de mai sus? 
 +  - instanța este imutabilă sau fără stare 
 +  - cast-ul este sigur 
 +  - comportamentul este identic pentru orice tip 
 +</​note>​ 
 + 
 +<note tip> 
 +Acest pattern apare în: 
 +  * ''​Collections.emptyList()''​ 
 +  * ''​Collections.emptyMap()''​ 
 +  * ''​Optional.empty()''​ 
 +  * ''​Stream.empty()''​ 
 +</​note>​ 
 + 
 +=====[Optional] Self-bounded Generics (Curiously Recurring Template Pattern — CRTP)===== 
 + 
 +Este un pattern avansat unde un **tip generic** se referă la el **însuși**. 
 + 
 +<code java> 
 +class ComparableSelf<​T extends ComparableSelf<​T>>​ { } 
 +</​code>​ 
 + 
 +Scopul acestui pattern este de a asigura că **subclasele** folosesc un **tip compatibil cu ele însele**. 
 + 
 +De exemplu: 
 +<code java> 
 +class Person extends ComparableSelf<​Person>​ { } 
 +</​code>​ 
 + 
 +Beneficiul major este că putem scrie algoritmi care impun **tipuri consistente**. 
 + 
 +Exemplu tipic: 
 +<code java> 
 +interface SelfComparable<​T extends SelfComparable<​T>>​ { 
 +    int compareTo(T other); 
 +
 +</​code>​ 
 + 
 +Implementare corectă: 
 +<code java> 
 +class Car implements SelfComparable<​Car>​ { 
 +    public int compareTo(Car other) { ... } 
 +
 +</​code>​ 
 + 
 +Implementare incorectă (interzisă de self-bounding):​ 
 +<code java> 
 +class Car implements SelfComparable<​Object>​ { ... } 
 +</​code>​ 
 + 
 +Self-bounded generics **împiedică** astfel de erori de design. 
 + 
 ======Exerciții====== ======Exerciții======
  
poo-ca-cd/laboratoare/programare-functionala-lambda-si-streamuri.1765180186.txt.gz · Last modified: 2025/12/08 09:49 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