This shows you the differences between two versions of the page.
poo-ca-cd:laboratoare:genericitate [2020/10/04 16:04] maria.leoveanu [Bounded Wildcards] |
poo-ca-cd:laboratoare:genericitate [2023/12/17 19:13] (current) florin.subtirica [Exerciții] |
||
---|---|---|---|
Line 1: | Line 1: | ||
- | ===== Genericitate ===== | + | ===== Laboratorul 10: Genericitate ===== |
==== Obiective ==== | ==== Obiective ==== | ||
Line 170: | Line 170: | ||
</code> | </code> | ||
- | Sintaxa ''List<? extends Pizza>'' ([[https://docs.oracle.com/javase/tutorial/java/generics/upperBounded.html|Upper Bounded Wildcards]]) impune ca tipul elementelor listei să fie ''Pizza'' sau o subclasă a acesteia. Astfel, ''pList'' ar fi putut avea, la fel de bine, tipul ''List<HamPizza>'' sau ''List<CheesePizza>''. În mod similar, putem imprima constrângerea ca tipul elementelor listei să fie ''Pizza'' sau o superclasă a acesteia, utilizând sintaxa ''List<? super Pizza>'' ([[:poo-ca-cd:https://docs.oracle.com/javase/tutorial/java/generics/lowerBounded.html|Lower Bounded Wildcards]]). | + | Sintaxa ''List<? extends Pizza>'' ([[https://docs.oracle.com/javase/tutorial/java/generics/upperBounded.html|Upper Bounded Wildcards]]) impune ca tipul elementelor listei să fie ''Pizza'' sau o subclasă a acesteia. Astfel, ''pList'' ar fi putut avea, la fel de bine, tipul ''List<HamPizza>'' sau ''List<CheesePizza>''. În mod similar, putem imprima constrângerea ca tipul elementelor listei să fie ''Pizza'' sau o superclasă a acesteia, utilizând sintaxa ''List<? super Pizza>'' ([[https://docs.oracle.com/javase/tutorial/java/generics/lowerBounded.html|Lower Bounded Wildcards]]). |
<note> | <note> | ||
Utilizarea bounded wildcards se manifestă în următoarele 2 situații : | Utilizarea bounded wildcards se manifestă în următoarele 2 situații : | ||
- | * lower bounded wildcards se folosesc atunci când vrem să **modificăm** o colecție generică | + | * lower bounded wildcards se folosesc atunci când vrem să **modificăm** o colecție generică |
- | * upper bounded wildcards se folosesc atunci când vrem să **parcurgem fără să modificăm** o colecție generică | + | * upper bounded wildcards se folosesc atunci când vrem să **parcurgem fără să modificăm** o colecție generică |
</note> | </note> | ||
==== Type Erasure ==== | ==== Type Erasure ==== | ||
- | [[https://docs.oracle.com/javase/tutorial/java/generics/erasure.html|Type Erasure]] este un mecanism prin care compilatorul Java înlocuieşte la **compile time** parametrii de genericitate ai unei clase generice cu prima lor apariţie (ţinând cont de restricţii în cazul Bounded Wildcards) sau cu ''Object'' dacǎ parametrii nu apar (Raw Type). De exemplu, următorul cod: | + | [[https://docs.oracle.com/javase/tutorial/java/generics/erasure.html|Type Erasure]] este un mecanism prin care compilatorul Java înlocuieşte la **compile time** parametrii de genericitate ai unei clase generice cu prima lor apariţie (ţinând cont de restricţii în cazul Bounded Wildcards) sau cu ''Object'' dacă parametrii nu apar (Raw Type). De exemplu, următorul cod: |
<code java> | <code java> | ||
Line 188: | Line 188: | ||
</code> | </code> | ||
- | se va transforma dupǎ acest pas al compilării în: | + | se va transforma după acest pas al compilării în: |
<code java> | <code java> | ||
Line 196: | Line 196: | ||
</code> | </code> | ||
- | Sǎ urmǎrim urmǎtorul fragment de cod: | + | Să urmărim următorul fragment de cod: |
<code java> | <code java> | ||
Line 260: | Line 260: | ||
</code> | </code> | ||
+ | ==== Exemple genericitate ==== | ||
+ | Probabil nu sunteți familiari încă cu termenul de “GPU Computing” (utilizarea unui procesor grafic pentru accelerarea calculelor), dar probabil ați exploatat una dintre întrebuințările ei, mai exact jocurile video. | ||
+ | |||
+ | Jocurile video sunt create cu ajutorul unor engine-uri grafice, care în esență nu reprezintă altceva decât aplicații care realizează o multitudine de operații matematice: plotări de grafice, interpolări, operații matriceale/vectoriale, derivări etc. | ||
+ | |||
+ | Aceste operații matematice pot fi făcute pe diferite tipuri de date. O matrice poate acceptă int-uri (exemplu: camera jucătorului), float-uri / double-uri (exemplu: setarea opacității unei texturi), char-uri (exemplu: reprezentarea text box-urilor pentru dialog) etc. În loc să creem câte o clasă care să adere fiecărui tip, putem scrie o singură dată o clasă care să reprezinte o matrice și care să accepte mai multe tipuri de date prin genericitate. Acest lucru devine foarte util dacă dorim să creem o bibliotecă întreagă pentru operații matematice avansate (exemplu: Jscience), fără să ne repetăm codul doar pentru a crea clase și metode specifice unor tipuri de date. | ||
==== Exerciții ==== | ==== Exerciții ==== | ||
+ | Scheletul laboratorului poate fi descărcat de aici: {{:poo-ca-cd:laboratoare:oop_lab10.zip|}} | ||
+ | |||
+ | Laboratorul trebuie rezolvat pe platforma LambdaChecker, fiind găsit [[https://beta.lambdachecker.io/contest/21 | aici]]. | ||
+ | |||
+ | - **(6 puncte)** Implementați o structură de date de tipul ''MultiMapValue<K, V>'', pe baza scheletului, care reprezintă un ''HashMap<K, ArrayList<V>>'', unde o cheie este asociată cu mai multe valori. Modalitatea de stocare a datelor este la alegere (moștenire sau agregare) și să folosiți funcționalitățile din HashMap. În schelet aveți următoarele metode de implementat: | ||
+ | - **(1 punct)** ''add(K key, V value)'' - adaugă o valoare la o cheie dată (valoarea este adăugate în lista de valori asociate cheii, dacă cheia și lista nu există, atunci lista va fi creată și asociată cheii. | ||
+ | - **(1 puncte)** ''void addAll(K key, List<V> values)'' - adaugă valorile din lista de valori dată ca parametru la lista asociată cheii. | ||
+ | - **(1 puncte)** ''void addAll(MultiMapValue<K, V> map)'' - adaugă intrările din obiectul MultiMapValue dat ca parametru în obiectul curent (this). | ||
+ | - **(0.5 puncte)** ''V getFirst(K key)'' - întoarce prima valoare asociată cheii (dacă nu există, se întoarce null). | ||
+ | - **(0.5 puncte)** ''List<V> getValues(K key)'' - se întoarce lista de valori asociată cheii. | ||
+ | - **(0.5 puncte)** ''boolean containsKey(K key)'' - se verifică faptul dacă este prezentă cheia în MultiMapValue. | ||
+ | - **(0.5 puncte)** ''boolean isEmpty()'' - se verifică dacă MultiMapValue este gol. | ||
+ | - **(0.5 puncte)** ''List<V> remove(K key)'' - se șterge cheia, împreună cu valorile asociate ei, din MultiMapValue. | ||
+ | - **(0.5 puncte)** ''int size()'' - se întoarce mărimea MultiMapValue. | ||
- | - (**6p**) Implementați o **tabelă de dispersie** generică care va permite să stocaţi perechi de tip cheie-valoare. | + | - **(4 puncte)** Implementați o structură de date de tipul Tree<T> (Arbore binar de căutare) pe baza scheletului. Analizați modalitatea de utilizare a bounded wildcards, explicați necesitatea lor laborantului (fie în cadrul orei de laborator, fie la nivel de comentariu în cod). În schelet aveți următoarele metode de implementat: |
- | * (**2p**) Scrieţi antetul clasei ''MyHashMap'' şi prototipul funcţiilor **put** şi **get**. Aveţi grijă la parametrizarea tipurilor. | + | - **(1 puncte)** ''void addValue(T value)'' - adaugă o valoare în arborele binar de căutare. |
- | * (**2p**) Implementaţi metoda **put**. Vă puteți crea o clasă internă cu rol de //entry// şi puteţi stoca //entry-urile// într-o colecţie generică existentă în Java. | + | - **(0.5 puncte)** ''void addAll(List<T> values)'' - adaugă valorile dintr-o listă în arborele binar de căutare. |
- | * (**1p**) Implementaţi metoda **get**. | + | - **(1.5 puncte)** ''HashSet<T> getValues(T inf, T sup)'' - colectează valorile din arbore între o limită inferioară și superioară într-o colecție de tipul HashSet. |
- | * (**1p**) Testaţi implementarea voastră folosind o clasă definită de voi, care suprascrie metoda **hashCode** din ''Object''. | + | - **(0.5 puncte)** ''int size()'' - se întoarce numărul de elemente inserate în arbore. |
- | - (**4p**) Să considerăm interfața ''Sumabil'', ce conține metoda ''void addValue(Sumabil value)''. Această metodă adună la valoarea curentă (stocată în instanța ce apelează metoda) o altă valoare, aflată într-o instanță cu același tip. Pornind de la această interfață, va trebui să: | + | - **(0.5 puncte)** ''boolean isEmpty()'' - se întoarce dacă există vreun element inserat în arborele binar sau nu. |
- | * Definiți clasele ''MyVector3'' și ''MyMatrix'' (ce reprezintă un vector cu 3 coordonate și o matrice de dimensiune 4 x 4), ce implementează Sumabil | + | |
- | * Scrieți **o metodă generică** ce primește o colecție generică cu elemente de tipul ''Sumabil'' și returnează suma tuturor elementelor din colecție. Trebuie să utilizați //bounded types//. Care trebuie să fie, deci, antetul metodei? | + | |
- | ==== Resurse ==== | ||
- | * <html><a class="media mediafile mf_pdf" href="/poo/laboratoare/genericitate?do=export_pdf">PDF laborator</a></html> | ||
====Referinţe==== | ====Referinţe==== | ||