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/19 20:52]
florin.mihalache [Exerciții]
poo-ca-cd:laboratoare:static-final [2022/10/30 18:50] (current)
teodora.stroe2210 [Exerciții]
Line 250: Line 250:
  
 {{ :​poo-ca-cd:​laboratoare:​singleton2.png?​500 |}} {{ :​poo-ca-cd:​laboratoare:​singleton2.png?​500 |}}
-               ​Clients may not even realize that they’re working with the same object all the time. 
  
 Exemple din API-ul Java: [[http://​docs.oracle.com/​javase/​8/​docs/​api/​java/​lang/​Runtime.html | java.lang.Runtime]],​ [[http://​docs.oracle.com/​javase/​8/​docs/​api/​java/​awt/​Toolkit.html | java.awt.Toolkit]] Exemple din API-ul Java: [[http://​docs.oracle.com/​javase/​8/​docs/​api/​java/​lang/​Runtime.html | java.lang.Runtime]],​ [[http://​docs.oracle.com/​javase/​8/​docs/​api/​java/​awt/​Toolkit.html | java.awt.Toolkit]]
Line 339: 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 426:
   * Watch expression - în caseta de Variables apoi + se poate inițializa o variabilă nouă sau una deja existentă care să fie urmărită pe parcursul sesiunii de debug   * Watch expression - în caseta de Variables apoi + se poate inițializa o variabilă nouă sau una deja existentă care să fie urmărită pe parcursul sesiunii de debug
   * 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. 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:
 +  * ''​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.
 +  * ''​size()''​ - returnează numărul de elemente din HashMap.
 +  * ''​containsKey(Object key)''​ - verifică dacă cheia există în HashMap.
 +  * ''​remove(Object key)''​ - șterge o pereche cu cheia respectivă 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:
 +<code java5>
 +import java.util.HashMap;​
 +import java.util.Map;​
 +
 +public class Main {
 +    public static void main(String[] args) {
 +        HashMap<​String,​ Integer> grades = 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 ====
-  - 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).+  - **(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).
   - 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.   - 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.
-      - 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. +      - **(2 puncte)** ​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 ​cu implementare ​de tip lazy. Această clasă va conține o listă de profesori și o listă de studenți. Faceți aceste liste de tip final. 
-      - 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:​+      - **(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:​
           - metoda ''​averageGrade'',​ care calculează media generală a studentului (media tuturor materiile pe care acesta le are).           - metoda ''​averageGrade'',​ care calculează media generală a studentului (media tuturor materiile pe care acesta le are).
           - copy constructor-ul clasei           - copy constructor-ul clasei
           - metoda ''​getGradeForSubject'',​ care primește ca parametru de intrare numele unei materii și întoarce nota studentului la materia respectivă.           - metoda ''​getGradeForSubject'',​ care primește ca parametru de intrare numele unei materii și întoarce nota studentului la materia respectivă.
-      - Clasa ''​Teacher''​ are trei câmpuri: nume, prenume și lista materiilor pe care ei le predau. În această clasa implementați copy constructor. +      - **(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. 
-      - În clasa ''​Database''​ implementați următoarele metode:+      - **(2 puncte)** ​În clasa ''​Database''​ implementați următoarele metode:
           - ''​findAllStudents''​ - întoarce lista de studenți           - ''​findAllStudents''​ - întoarce lista de studenți
           - ''​findAllTeachers''​ - întoarce lista de profesori           - ''​findAllTeachers''​ - întoarce lista de profesori
Line 403: Line 479:
           - ''​getStudentsByAverageGrade''​ - întoarce lista cu studenții sortați crescător în funcție de media lor generală           - ''​getStudentsByAverageGrade''​ - întoarce lista cu studenții sortați crescător în funcție de media lor generală
           - ''​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.           - ''​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.
-      -  În clasa ''​Teacher''​ implementați următoarele metode, care vor apela metodele corespunzătoare din clasa ''​Database'':​+      -  ​**(1 punct)** ​În clasa ''​Teacher''​ implementați următoarele metode, care vor apela metodele corespunzătoare din clasa ''​Database'':​
           - ''​getAllTeachers''​           - ''​getAllTeachers''​
           - ''​getTeachersBySubject''​           - ''​getTeachersBySubject''​
Line 410: Line 486:
           - ''​getStudentsByAverageGrade''​           - ''​getStudentsByAverageGrade''​
           - ''​getStudentsByGradeForSubject''​           - ''​getStudentsByGradeForSubject''​
-      - Î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 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):
           - ''​getAllTeachers''​           - ''​getAllTeachers''​
           - ''​getTeachersBySubject''​           - ''​getTeachersBySubject''​
Line 417: Line 493:
           - ''​getStudentsByAverageGrade''​           - ''​getStudentsByAverageGrade''​
           - ''​getStudentsByGradeForSubject''​           - ''​getStudentsByGradeForSubject''​
-      - Î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. ​    
-==== Resurse ==== + 
-  * {{:poo-ca-cd:​laboratoare:​static-final-singleton:schelet_lab4.zip|Arhiva zip cu clasa RandomStringGenerator.java}}+<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.1632073920.txt.gz · Last modified: 2021/09/19 20:52 by florin.mihalache
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