Differences

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

Link to this comparison view

poo-ca-cd:laboratoare:static-final [2021/09/20 22:28]
florin.mihalache [Singleton Pattern]
poo-ca-cd:laboratoare:static-final [2023/10/29 16:03] (current)
calin.precupetu
Line 338: Line 338:
 O clasă de tip Singleton poate fi extinsă, iar metodele ei suprascrise,​ însă într-o clasă cu metode statice acestea nu pot fi suprascrise (//​overriden//​) (o discuție pe aceasta temă puteți găsi [[http://​geekexplains.blogspot.ro/​2008/​06/​can-you-override-static-methods-in-java.html | aici]], și o comparație între static și dynamic binding [[http://​geekexplains.blogspot.ro/​2008/​06/​dynamic-binding-vs-static-binding-in.html | aici]]). O clasă de tip Singleton poate fi extinsă, iar metodele ei suprascrise,​ însă într-o clasă cu metode statice acestea nu pot fi suprascrise (//​overriden//​) (o discuție pe aceasta temă puteți găsi [[http://​geekexplains.blogspot.ro/​2008/​06/​can-you-override-static-methods-in-java.html | aici]], și o comparație între static și dynamic binding [[http://​geekexplains.blogspot.ro/​2008/​06/​dynamic-binding-vs-static-binding-in.html | aici]]).
  
-=== Tutorial debugging în IntelliJ ===+==== Deep copy. Shallow copy ==== 
 + 
 +Pentru început, ne propunem să ne familiarizăm cu noțiunea de copie în Java.  
 + 
 +Noțiunea de //reference copy// implică copierea unei **referințe** care pointeaza către un obiect. 
 +Exemplu: Dacă avem un obiect de tipul Car, iar variabila myCar pointeaza către acesta, prin crearea unei copii de referință vom obține două variabile myCar ce pointeaza către același obiect de tipul Car.  
 +{{ :​poo-ca-cd:​laboratoare:​shallow.jpg?​300 |}} 
 + 
 +Noțiunea de //object copy// creează însă o copie a obiectului în sine. Deci, dacă am copia din nou obiectul Car, am crea o copie a obiectului în sine, precum și o a doua variabilă de referință ce face referire la acel obiect copiat. 
 +{{ :​poo-ca-cd:​laboratoare:​deep.jpg?​300 |}} 
 + 
 +**//Shallow copy//** se referă la copierea obiectului „principal”,​ dar nu copiază obiectele "​interioare",​ acestea fiind "​împărtășite"​ doar de obiectul original și copia acestuia. De exemplu, dacă pentru un obiect de tip Person, am crea un al doilea obiect Person, ambele obiecte ar avea aceleași obiecte Name și Address întrucât schimbarea unuia dintre acestea implică modificarea peste tot unde se regăsește referința obiectului modificat.  
 + 
 +Putem spune astfel că cele două obiecte Person nu sunt independente - dacă este modificat obiectul Name al unui obiect Person, schimbarea se va reflecta și în celălat obiect de acest tip. 
 + 
 +<code java> 
 +public class Person { 
 +    private Name name; 
 +    private Address address; 
 + 
 +    public Person(Person firstPerson) { 
 +         ​this.name = firstPerson.name;​ 
 +         ​this.address = firstPerson.address;​ 
 +    } 
 +
 +</​code>​ 
 + 
 +Spre deosebire de shallow copy, **//deep copy//** este o copie complet independentă a unui obiect. Dacă am copia obiectul Person, am copia întreaga structură a obiectului. În acest caz, o modificare a obiectului Adress nu va fi reflectată în cealalt obiect. Dacă aruncăm o privire asupra codului din exemplul următor, se observă că nu este folosit doar un //copy constructor//​ pentru obiectul Person, dar și //copy constructors//​ pentru obiectele interioare. 
 + 
 +<code java> 
 +public class Person { 
 +    private Name name; 
 +    private Address address; 
 + 
 +    public Person(Person otherPerson) { 
 +         ​this.name ​   =  new Name(otherPerson.name);​ 
 +         ​this.address =  new Address(otherPerson.address);​ 
 +    } 
 +
 +</​code>​ 
 + 
 +==== Tutorial debugging în IntelliJ ​====
  
 Luând în considerare următorul scenariu: Luând în considerare următorul scenariu:
Line 386: Line 427:
   * Set Value - putem modifica comportamentul programului fară să schimbăm codul sursă, pentru orice variabilă din caseta de Variables click dreapta -> Set Value și putem observa cum se modifică programul cu noua valoare dată   * Set Value - putem modifica comportamentul programului fară să schimbăm codul sursă, pentru orice variabilă din caseta de Variables click dreapta -> Set Value și putem observa cum se modifică programul cu noua valoare dată
  
-==== Utilizarea clasei HashMap ====+==== Utilizarea clasei HashMap. Exemple ​====
 Clasa HashMap este un dicționar (tabelă de dispersie / hashtable), o colecție de perechi cheie-valoare unde avem o mapare între cheia unică în colecție și valoarea asociată acesteia, iar această clasă poate fi găsită în pachetul java.util. Principalele metode ale acestei clase sunt: Clasa HashMap este un dicționar (tabelă de dispersie / hashtable), o colecție de perechi cheie-valoare unde avem o mapare între cheia unică în colecție și valoarea asociată acesteia, iar această clasă poate fi găsită în pachetul java.util. Principalele metode ale acestei clase sunt:
-  * put(K key, V value) - adaugă o pereche cheie-valoare sau înlocuiește valoarea asociată unei chei deja existente în HashMap. +  * ''​put(K key, V value)'' ​- adaugă o pereche cheie-valoare sau înlocuiește valoarea asociată unei chei deja existente în HashMap. 
-  * get(Object key) - accesează valoarea asociată unei chei din HashMap. +  * ''​get(Object key)'' ​- accesează valoarea asociată unei chei din HashMap. 
-  * size() - returnează numărul de elemente din HashMap. +  * ''​size()'' ​- returnează numărul de elemente din HashMap. 
-  * containsKey(Object key) - verifică dacă cheia există în HashMap. +  * ''​containsKey(Object key)'' ​- verifică dacă cheia există în HashMap. 
-  * remove(Object key) - șterge o pereche cu cheia respectivă din HashMap. +  * ''​remove(Object key)'' ​- șterge o pereche cu cheia respectivă din HashMap. 
-  * clear() - șterge toate elementele din HashMap.+  * ''​clear()'' ​- șterge toate elementele din HashMap.
  
 Pentru a putea parcurge elementele unui HashMap se poate folosi for-each. Un exemplu de utilizare a metodelor clasei HashMap și de parcurgere a elementelor stocate de această clasă este următorul: Pentru a putea parcurge elementele unui HashMap se poate folosi for-each. Un exemplu de utilizare a metodelor clasei HashMap și de parcurgere a elementelor stocate de această clasă este următorul:
 <code java5> <code java5>
 +import java.util.HashMap;​
 +import java.util.Map;​
  
-</code>+public class Main { 
 +    public static void main(String[] args) { 
 +        HashMap<String, Integergrades = new HashMap<>​();​ 
 +        grades.put("​Celentano",​ 5); 
 +        grades.put("​Firicel",​ 8); 
 +        grades.put("​Brinzoi",​ 9); 
 +        grades.put("​Bobita",​ 10);
  
 +        System.out.println("​Firicel'​s grade: "+ grades.get("​Firicel"​));​
 +
 +        grades.put("​Firicel",​ 10);
 +        System.out.println("​Firicel'​s grade: "+ grades.get("​Firicel"​));​
 +
 +        for (Map.Entry<​String,​ Integer> entry: grades.entrySet()) {
 +            System.out.println(entry.getKey() + ": " + entry.getValue());​
 +        }
 +    }
 +}
 +</​code>​
  
  
 ==== Exerciții ==== ==== Exerciții ====
-  - **(1 punct)** Folosind ​de pașii și de debugger, reparați codul din pachetul ''​vault''​ din cadrul scheletului laboratorului (același care este prezentat în cadrul tutorialului de debug). +  ​- Pentru a rezolva laboratorul aveti urmatorul contest pe LambdaChecker : [[https://​beta.lambdachecker.io/​contest/​55/​problems?​page=1 | contest]] 
-  - Aveți de implementat o mini aplicație de tip queries dintr-o bază de date cu studenți ​și cu profesori. Fiecare ​student ​are o colecție de asocieri dintre ​materiile sale și notele la materiile respective ​de tip dicționar, iar fiecare ​profesor ​are o listă de materii ​pe care le predă. Studenții pot executa operații care sunt doar read-only (acestea nu pot avea efecte de tip write în baza de date - hint: imutabilitate) și profesorii pot executa operații de tip read-write+  ​- **(0 puncte)** Folosind pașii ​de mai sus și debugger-ul, reparați codul din pachetul ''​vault''​ din cadrul ​[[https://​github.com/​oop-pub/​oop-labs/​tree/​master/​src/​lab4 | scheletului laboratorului]] (același care este prezentat în cadrul tutorialului de debug). 
-      - **(1 punct)** Având la bază scheletul de cod, faceți clasa Database, care se ocupă cu gestionarea bazei de date a studenților ​și a profesorilor, o clasă de tip Singleton ​(tipul ​de Singleton este la alegerea voastră). Această clasă va conține o listă de profesori ​și o listă de studenți. Faceți aceste liste de tip final. +  -  Aveți de implementat o mini aplicație de tip queries dintr-o bază de date cu dealershipuri ​și selleri de masini. Fiecare ​dealership ​are o colecție de asocieri dintre ​brandurile de masini vandute ​și pretul lor, de tip dicționar, iar fiecare ​seller ​are o listă de branduri de masina ​pe care le vinde.  
-      - **(1 punct)** Clasa ''​Student''​ are trei câmpuri: nume, prenume ​și un dicționar unde sunt stocate ​materiile unui student, fiecare ​materie ​fiind asociată cu nota studentului ​la materia ​respectivă. În această clasă, implementați următoarele:​ +      - **(2 puncte)** Având la bază scheletul de cod, faceți clasa Database, care se ocupă cu gestionarea bazei de date a dealershipurilor ​și a sellerilor, o clasă de tip Singleton ​cu implementare ​de tip lazy. Această clasă va conține o listă de dealershipuri ​și o listă de selleri. Faceți aceste liste de tip final. 
-          - metoda ''​averageGrade'',​ care calculează media generală a studentului (media tuturor materiile pe care acesta le are)+      - **(1 punct)** Clasa ''​Dealership''​ are doua câmpuri: nume și un dicționar unde sunt stocate ​brandurile de masini, fiecare ​brand fiind asociat cu pretul sau la dealershipul ​respectiv. În această clasă, implementați următoarele:​ 
-          - copy constructor-ul ​clasei +          - metoda ''​averagePrice'',​ care calculează media pretului masinilor din Dealership
-          - metoda ''​getGradeForSubject'',​ care primește ca parametru de intrare numele ​unei materii ​și întoarce ​nota studentului la materia respectivă+          - copy constructorul ​clasei 
-      - **(1 punct)** Clasa ''​Teacher''​ are trei câmpuri: nume, prenume și lista materiilor ​pe care ei le predau. În această clasa implementați copy constructor.+          - metoda ''​getPriceForBrand'',​ care primește ca parametru de intrare numele ​unui brand și întoarce ​pretul acestuia
 +      - **(1 punct)** Clasa ''​Seller''​ are doua câmpuri: nume si lista brandurilor ​pe care acesta ​le vinde. În această clasa implementați copy constructor.
       - **(2 puncte)** În clasa ''​Database''​ implementați următoarele metode:       - **(2 puncte)** În clasa ''​Database''​ implementați următoarele metode:
-          - ''​findAllStudents''​ - întoarce lista de studenți +          - ''​getAllDealerships''​ - întoarce lista de delaershipuri 
-          - ''​findAllTeachers''​ - întoarce ​lista de profesori +          - ''​getAllSellers''​ - intoarce ​lista de selleri 
-          - ''​getStudentsBySubject''​ - primește ca parametru numele ​unei materii ​și întoarce lista cu studenții ​care au materia ​respectivă +          - ''​getDealershipByBrand''​ - primește ca parametru numele ​unui brand și întoarce lista cu dealershipurile ​care detin brandul ​respectiv 
-          - ''​findTeachersBySubject''​ - primește ca parametru numele ​unei materii ​și întoarce lista cu profesorii ​care predau materia ​respectivă+          - ''​getSellerByBrand''​ - primește ca parametru numele ​unui brand și întoarce lista cu sellerii ​care vand brandul ​respectiv. 
-          - ''​getStudentsByAverageGrade''​ - întoarce lista cu studenții sortați ​crescător în funcție de media lor generală +          - ''​getDealershipsByAveragePrice''​ - întoarce lista cu dealershipuri sortate ​crescător în funcție de pretul ​lor mediu. 
-          - ''​getStudentsByGradeForSubject''​ - primește ca parametru numele ​unei materii ​și întoarce lista cu studenții ​care au materia respectivăsortați ​după nota pe care au ei la materia respectivă ​în ordinea ​crescătoare. +          - ''​getDealershipsByPriceForBrand''​ - primește ca parametru numele ​unui brand și întoarce lista cu dealershipurile ​care detin acel brandsortate ​după pretul acestuia ​în ordine ​crescătoare. 
-      -  **(1 punct)** În clasa ''​Teacher''​ implementați următoarele metode, care vor apela metodele corespunzătoare din clasa ''​Database'':​ +      -  **(1 punct)** În clasa ''​Seller''​ implementați următoarele metode, care vor apela metodele corespunzătoare din clasa ''​Database'':​ 
-          - ''​getAllTeachers''​ +          - ''​getAllSellers''​ 
-          - ''​getTeachersBySubject''​ +          - ''​getAllDealerships''​ 
-          - ''​getAllStudents''​ +          - ''​getSellersByBrand''​ 
-          - ''​getStudentsBySubject''​ +          - ''​getDealershipsByBrand''​ 
-          - ''​getStudentsByAverageGrade''​ +          - ''​getDealershipsByAveragePrice''​ 
-          - ''​getStudentsByGradeForSubject''​ +          - ''​getDealershipsByPriceForBrand''​ 
-      - **(1 punct)** În clasa Student ​implementați următoarele metode, care vor apela metodele corespunzătoare din clasa ''​Database''​ (atenție, aici metodele trebuie să întoarcă rezultate imutabile, sub forma de deep copy, folosind modalitatea prezentată în laborator, folosind [[https://​docs.oracle.com/​javase/​8/​docs/​api/​java/​util/​Collections.html | Collections.unmodifiableList()]] pentru ca evita posibilitatea de a modifica rezultatele,​ care sunt read-only):​ +      - **(2 puncte)** În clasa Dealership ​implementați următoarele metode, care vor apela metodele corespunzătoare din clasa ''​Database''​ (atenție, aici metodele trebuie să întoarcă rezultate imutabile, sub forma de deep copy, folosind modalitatea prezentată în laborator, folosind [[https://​docs.oracle.com/​javase/​8/​docs/​api/​java/​util/​Collections.html | Collections.unmodifiableList()]] pentru ca evita posibilitatea de a modifica rezultatele,​ care sunt read-only):​ 
-          - ''​getAllTeachers''​ +          - ''​getAllSellers''​ 
-          - ''​getTeachersBySubject''​ +          - ''​getAllDealerships''​ 
-          - ''​getAllStudents''​ +          - ''​getSellersByBrand''​ 
-          - ''​getStudentsBySubject''​ +          - ''​getDealershipsByBrand''​ 
-          - ''​getStudentsByAverageGrade''​ +          - ''​getDealershipsByAveragePrice''​ 
-          - ''​getStudentsByGradeForSubject''​ +          - ''​getDealershipsByPriceForBrand''​ 
-      - **(1 punct)** În clasa ''​Database'',​ adăugați un contor drept câmp al clasei, de tip static, care va număra instanțierile clasei în cadrul metodei ''​getDatabase'',​ unde se face instanțierea clasei. Implementați metoda ''​getNumberOfInstances()''​ din ''​Database'',​ care întoarce numărul de instanțieri. ​   ​+      - **(1 punct)** În clasa ''​Database'',​ adăugați un contor drept câmp al clasei, de tip static, care va număra instanțierile clasei în cadrul metodei ''​getDatabase'',​ unde se face instanțierea clasei. Implementați metoda ''​getNumberOfInstances()''​ din ''​Database'',​ care întoarce numărul de instanțieri. 
 +     
 + 
 +<note tip> 
 +Pentru sortarea unui ArrayList (despre care am discutat în cadrul [[poo-ca-cd:​laboratoare:​agregare-mostenire|laboratorului trecut]], ​ puteți folosi metoda sort() din cadrul clasei ArrayList:​ 
 +<code java> 
 +ArrayList<​String>​ animals = new ArrayList<>​();​ 
 +animals.add("​Dog"​);​ 
 +animals.add("​Cat"​);​ 
 +animals.add("​Sheep"​);​ 
 + 
 +animals.sort(new Comparator<​String>​() { 
 +    @Override 
 +        public int compare(String o1, String o2) { 
 +            return o1.compareTo(o2);​ 
 +        } 
 +}); 
 +</​code>​ 
 +</​note>​ 
 + 
 +<note tip> 
 +Pentru shallow copy și deep copy la ArrayList avem în felul următor: 
 +  * shallow copy: 
 +  <code java> 
 +  List<​Student>​ shallowCopy = new ArrayList<>​(list);​ 
 +  </​code>​ 
 +  * deep copy: 
 +  <code java> 
 +  List<​Student>​ deepCopy = new ArrayList<>​();​ 
 +  for (var student: list) { 
 +      // folosind constructor cu deep copy 
 +      deepCopy.add(new Student(student));​ 
 +  } 
 +  return deepCopy; 
 +  </​code>​ 
 +</​note>​
  
poo-ca-cd/laboratoare/static-final.txt · Last modified: 2023/10/29 16:03 by calin.precupetu
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