Differences

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

Link to this comparison view

poo:breviare:breviar-07 [2017/11/08 10:40]
mihai.nan created
poo:breviare:breviar-07 [2025/11/19 09:25] (current)
george.tudor1906
Line 1: Line 1:
 ====== Breviar 7 ====== ====== Breviar 7 ======
  
 +=== Colecții, iteratori, genericitate ===
  
 +=== 1. Colecții ===
 +
 +== 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**.
 +
 +Clasele și interfețele pentru lucrul cu colecții se află în pachetul **java.util**. Ierarhia pornește, pentru colecții propriu-zise,​ de la interfața **Collection**,​ care definește operațiile de bază (adăugare, eliminare, căutare, iterare). Din //​Collection//​ derivă **trei ramuri principale**:​
 +
 +  * **List** - colecții ordonate și indexate, care permit duplicate; implementările uzuale sunt ArrayList (acces aleator rapid) și LinkedList (inserări/​ștergeri eficiente cu iteratorul). Vector și Stack apar în bibliografie,​ dar sunt considerate tipuri legacy (fac parte din limbaj încă de la primele versiuni); pentru comportament de stivă/​coadă se preferă azi Deque (ex. ArrayDeque). ​
 +  * **Set** - mulțimi fără duplicate (în sens matematic); aici întâlnim HashSet (rapid, neordonat), LinkedHashSet (păstrează ordinea inserării) și TreeSet (menține elementele ordonate). Ordonarea formală este surprinsă de interfața SortedSet, care extinde Set și cere o ordine „naturală” sau dată de un Comparator, TreeSet fiind implementarea clasică.
 +  * **Queue** / **Deque** - structuri de tip coadă (eventual cu două capete). Implementările standard sunt ArrayDeque (coadă/​stivă eficientă) și PriorityQueue (ordonare după prioritate, nu după inserare).
 +
 +Separat de Collection se află ierarhia **Map**, care gestionează perechi cheie - valoare. Cheile sunt unice, iar fiecare cheie mapează exact o valoare. Implementările cele mai folosite sunt **HashMap** (rapid, fără ordine), **LinkedHashMap** (menține ordinea inserării sau a accesului - util, de exemplu, pentru cache LRU - Least Recently Used) și **TreeMap** (chei ordonate). Interfața **SortedMap** extinde Map cu operații specifice ordinii - în practică, TreeMap este implementarea reprezentativă. Hashtable este o variantă veche, sincronizată,​ păstrată pentru compatibilitate,​ dar în cod modern se preferă HashMap (sau ConcurrentHashMap pentru acces concurent).
 +
 +<note important>​
 +În Java modern, colecțiile sunt **parametrizate**:​ după numele colecției se declară, între //<​…>//,​ tipul elementelor. ​ De exemplu, //​List<​String>//​ înseamnă o listă care conține doar șiruri de caractere.
 +
 +Dacă tipul este declarat astfel, compilatorul verifică la compilare să nu introducem alt tip (de ex. un //Integer// într-o //​List<​String>//​). Orice încercare greșită este o **eroare de compilare**,​ deci problema se oprește înainte de rulare.
 +</​note>  ​
 +
 +<note warning>
 +Colecțiile **eterogene** (elemente de orice fel) apar doar dacă:
 +  * folosim intenționat un tip general (ex. //​List<​Object>//​),​ sau  ​
 +  * folosim un **raw type** (ex. //List// fără parametrul de tip).  ​
 +
 +**Raw types** sunt permise, dar nerecomandate:​ dezactivează verificarea de tip la compilare și pot duce la //​ClassCastException//​ la rulare. Dacă aveți un caz real în care elementele pot fi de tipuri diferite, folosiți List<​Object>​ sau un tip comun (o interfață,​ o clasă părinte). </​note>​
 +<code java>
 +import java.util.*;​
 +
 +public class Main {
 +    public static void main(String[] args) {
 +        // 1) Corect și sigur - generics
 +        List<​String>​ nume = new ArrayList<>​();​
 +        nume.add("​Ana"​);​
 +        // nume.add(10);​ // EROARE de compilare: 10 nu este String
 +        String s1 = nume.get(0);​ // fără cast, sigur
 +
 +        // 2) Permis, dar nerecomandat - raw type (fără <T>)
 +        List nespecificata = new ArrayList();​ // WARNING: unchecked/​unsafe
 +        nespecificata.add("​Ana"​);​
 +        nespecificata.add(10);​
 +        String s2 = (String) nespecificata.get(1);​ // EXCEPȚIE la rulare: ClassCastException
 +
 +        // 3) Colecție heterogenă (intenționat)
 +        List<​Object>​ mix = new ArrayList<>​();​
 +        mix.add("​Ana"​);​
 +        mix.add(10);​
 +        Object o = mix.get(1);
 +        if (o instanceof Integer n) {
 +            System.out.println(n + 5); // sigur
 +        }
 +    }
 +}
 +</​code>​
 +
 +== 1.2 Liste (List) ==
 +
 +Interfața **List**, pe lângă metodele moștenite din //​Collection//,​ definește colecții **ordonate** și **indexate**,​ care **permit duplicate** și ale căror elemente pot fi accesate după **poziție** (index). În practică, cele mai folosite implementări sunt **ArrayList** și **LinkedList**. ​
 +
 +ArrayList oferă **acces aleator foarte rapid** la elemente, cu cost mai mare pentru inserări/​ștergeri în interiorul listei. LinkedList stochează elementele într-o listă înlănțuită,​ ceea ce face **inserările și ștergerile** locale mai eficiente (folosind iteratorul),​ dar accesul la un element "din mijloc"​ este mai lent. LinkedList implementează și Deque, astfel că poate lucra comod cu elementele de la ambele capete (ex. addFirst, addLast). Pentru stivă/​coadă se preferă ArrayDeque, iar pentru liste obișnuite ArrayList/​LinkedList.
 +
 +<code java>
 +import java.util.*;​
 +
 +class Liste {
 +    private final List<​String>​ list1 = new ArrayList<>​(); ​       // ordonată, acces aleator rapid
 +    private final LinkedList<​Integer>​ list2 = new LinkedList<>​();​ // listă + deque
 +
 +    public static void main(String[] args) {
 +        Liste obj = new Liste();
 +
 +        // Operații de bază pe ArrayList<​String>​
 +        obj.list1.add("​Lab POO");
 +        obj.list1.add("​Colectii"​);​
 +        obj.list1.add("​Structuri de date"​);​
 +        if (obj.list1.contains("​Colectii"​)) {
 +            System.out.println("​Lista contine cuvantul"​);​
 +        }
 +
 +        // Parcurgere și ștergere în siguranță (fără ConcurrentModificationException)
 +        Iterator<​String>​ it = obj.list1.iterator();​
 +        while (it.hasNext()) {
 +            String s = it.next();
 +            System.out.println(s);​
 +            it.remove();​ // șterge elementul tocmai citit
 +        }
 +
 +        // LinkedList<​Integer>​ ca listă + deque (ambele capete)
 +        obj.list2.addAll(Arrays.asList(1,​ 10, 20));
 +        obj.list2.addFirst(50);​ // capătul din stânga
 +        obj.list2.addLast(17); ​ // capătul din dreapta
 +
 +        // Modificare „pe loc” cu ListIterator (ex.: înmulțește numerele pare cu 10)
 +        ListIterator<​Integer>​ li = obj.list2.listIterator();​
 +        while (li.hasNext()) {
 +            int x = li.next();
 +            if (x % 2 == 0) li.set(x * 10);
 +        }
 +
 +        // Afișare elemente (for-each)
 +        for (Integer i : obj.list2) {
 +            System.out.println(i);​
 +        }
 +
 +        // Sortare naturală (echivalent cu Collections.sort(list2))
 +        obj.list2.sort(Comparator.naturalOrder());​
 +        System.out.println(obj.list2);​
 +    }
 +}
 +</​code>​
 +
 +<note tip>
 +  * Declarați mereu tipul elementelor:​ //​List<​String>//,​ //​List<​Integer>//​.  ​
 +  * Pentru eliminări în timpul parcurgerii folosiți //​Iterator.remove()//​ sau //​removeIf(...)//​.  ​
 +  * Alegeți **ArrayList** când accentul este pe citire după index și **LinkedList** când aveți inserări/​ștergeri locale cu iteratorul sau operații la ambele capete.
 +</​note>  ​
 +
 +== 1.3 Mulțimi (Set și SortedSet) ==
 +
 +**Set** modelează noțiunea de **mulțime** în sens matematic: nu pot exista două elemente //o1//, //o2// într-un Set pentru care //​o1.equals(o2)//​ este //true//.
 +</​note>  ​
 +
 +Set moștenește operațiile de bază din Collection, fără a introduce metode proprii. Implementări uzuale:
 +
 +  * **HashSet** - rapid, **neordonat**;​
 +  * **LinkedHashSet** - păstrează ordinea inserării;
 +  * **TreeSet** - menține elementele **ordonate**.
 +
 +**SortedSet** reprezintă un Set în care elementele sunt păstrate în **ordine crescătoare**:​
 +
 +  * fie după **ordinea naturală** (//​Comparable//​),​
 +  * fie după un //​Comparator//​ furnizat la crearea colecției.
 +
 +Implementarea standard de `SortedSet` este **TreeSet**.
 +
 +<note warning>
 +Într-un **SortedSet**,​ pentru orice două obiecte o1, o2 ale colecției, //​o1.compareTo(o2)//​ sau //​comparator.compare(o1,​ o2)// trebuie să fie **valid** (fără excepții), iar pentru ordinea naturală, elementele //null// **nu sunt permise**.
 +</​note>  ​
 +
 +<code java>
 +import java.util.*;​
 +
 +class Example {
 +    public static void main(String[] args) {
 +        // 1) HashSet - fără ordine, elimină duplicatele pe baza equals()/​hashCode()
 +        Set<​String>​ hs = new HashSet<>​();​
 +        Collections.addAll(hs,​ "​Ana",​ "​Ana",​ "​Ion"​);​
 +        System.out.println("​HashSet:​ " + hs); // ex.: [Ana, Ion]
 +
 +        // 2) LinkedHashSet - păstrează ordinea inserării
 +        Set<​Integer>​ lhs = new LinkedHashSet<>​(List.of(3,​ 1, 2, 1));
 +        System.out.println("​LinkedHashSet:​ " + lhs); // [3, 1, 2]
 +
 +        // 3) TreeSet - comparator: lungime, apoi lexicografic
 +        SortedSet<​String>​ good = new TreeSet<>​(
 +                Comparator.comparingInt(String::​length)
 +                          .thenComparing(Comparator.naturalOrder())
 +        );
 +        good.addAll(List.of("​aa",​ "​b",​ "​bb"​));​
 +        System.out.println("​TreeSet ok: " + good); // [b, aa, bb]
 +
 +        // Comparator problematic:​ compară DOAR lungimea -> unele elemente sunt excluse
 +        SortedSet<​String>​ bad = new TreeSet<>​(Comparator.comparingInt(String::​length));​
 +        bad.addAll(List.of("​aa",​ "​bb"​));​ // "​bb"​ e ignorat: compare("​aa","​bb"​) == 0
 +        System.out.println("​TreeSet problematic:​ " + bad); // [aa]
 +    }
 +}
 +</​code>​
 +
 +
 +== 1.4 Dicționare (Map și SortedMap) ==
 +
 +**Map** descrie structuri care asociază fiecărei **chei** o **valoare**:​
 +
 +  * **cheile sunt unice**;
 +  * valorile pot fi duplicate.
 +
 +Ierarhia **Map** este separată de //​Collection//​. Operații tipice:
 +  * inserare: //put(k, v)//;
 +  * citire: //get(k)//, //​getOrDefault(k,​ valoareImplicita)//;​
 +  * test de apartenență:​ //​containsKey//,​ //​containsValue//;​
 +  * eliminare: //​remove(k)//;​
 +  * parcurgere: //​entrySet()//,​ //​keySet()//,​ //​values()//​.
 +
 +În practică, cele mai folosite implementări sunt:
 +
 +  * **HashMap** - rapid, fără ordine de iterare; permite o cheie //null// și valori //null//;
 +  * **LinkedHashMap** - ca //​HashMap//,​ dar păstrează ordinea inserării;
 +  * **TreeMap** - menține cheile **ordonate** (natural sau prin //​Comparator//​);​ nu acceptă chei //null//;
 +  * **Hashtable** - tip vechi; se preferă //HashMap// sau //​ConcurrentHashMap//​.
 +
 +**SortedMap** este un Map cu chei păstrate în **ordine crescătoare**;​ implementarea clasică este **TreeMap**.
 +
 +<code java>
 +import java.util.*;​
 +
 +class MiniMapDemo {
 +    public static void main(String[] args) {
 +        // 1) HashMap - fără ordine
 +        Map<​String,​ Integer> freq = new HashMap<>​();​
 +        for (String w : List.of("​ana",​ "​are",​ "​ana",​ "​mere"​)) {
 +            freq.merge(w,​ 1, Integer::​sum);​ // new = 1, altfel +1
 +        }
 +        System.out.println("​HashMap (fara ordine): " + freq);
 +        System.out.println("​getOrDefault('​banane',​ 0) = "
 +            + freq.getOrDefault("​banane",​ 0));
 +
 +        // 2) LinkedHashMap - păstrează ordinea inserării
 +        Map<​Integer,​ String> lhm = new LinkedHashMap<>​();​
 +        lhm.put(2, "​B"​);​
 +        lhm.put(1, "​A"​);​
 +        lhm.put(3, "​C"​);​
 +        System.out.println("​LinkedHashMap (ordine inserare): " + lhm.keySet());​ // [2, 1, 3]
 +
 +        // 3) TreeMap - chei ordonate (natural)
 +        Map<​String,​ Integer> sorted = new TreeMap<>​(freq);​ // sortează după cheia String
 +        System.out.println("​TreeMap (chei ordonate): " + sorted);
 +
 +        // 4) Parcurgere eficientă cu entrySet()
 +        for (Map.Entry<​String,​ Integer> e : sorted.entrySet()) {
 +            System.out.println(e.getKey() + " => " + e.getValue());​
 +        }
 +    }
 +}
 +</​code>​
 +
 +=== 2. Iteratori și enumerări ===
 +
 +Enumerările și iteratorii descriu modalități de **parcurgere secvențială** a unei colecții. În Java, parcurgerea se face în principal cu:
 +
 +  * **Iterator** (și pentru liste, //​ListIterator//​),​
 +  * sintaxa **for-each**:​ //for (T e : colectie) { ... }//.
 +
 +== 2.1 Enumeration ==
 +
 +**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//​.
 +
 +<code java>
 +import java.util.*;​
 +
 +class DemoEnumeration {
 +    public static void main(String[] args) {
 +        List<​Integer>​ list = List.of(3, 7, 0, 5);
 +        Enumeration<​Integer>​ en = Collections.enumeration(list);​ // din orice Collection
 +
 +        while (en.hasMoreElements()) {
 +            int x = en.nextElement();​ // Integer, nu Object (datorită generics)
 +            System.out.println(x);​
 +        }
 +    }
 +
 +
 +</​code>​
 +
 +
 +== 2.2 Iterator ==
 +
 +**Iterator** oferă metodele:
 +  * **hasNext()** - mai există elemente?;
 +  * **next()** - returnează elementul următor;
 +  * **remove()** - șterge ultimul element returnat de next().
 +
 +<note important>​
 +Dacă modificați colecția în timpul parcurgerii,​ folosiți **iterator.remove()** (sau, mai simplu, //​removeIf(...)//​ pe colecție).  ​
 +</​note>​
 +
 +<code java>
 +import java.util.*;​
 +
 +class DemoIterator {
 +    public static void main(String[] args) {
 +        List<​String>​ l = new ArrayList<>​(List.of("​ana",​ "​bad",​ "​ion",​ "​bogdan"​));​
 +
 +        // Variantă modernă: removeIf
 +        l.removeIf(s -> s.length() == 4); // șterge elementele cu 4 litere
 +
 +        // Echivalent cu iterator.remove()
 +        Iterator<​String>​ it = l.iterator();​
 +        while (it.hasNext()) {
 +            String s = it.next();
 +            if (s.startsWith("​b"​)) it.remove();​ // sigur
 +        }
 +
 +        System.out.println(l);​
 +    }
 +}
 +</​code>​
 +
 +== 2.3 ListIterator (liste, ambele sensuri) ==
 +
 +//​ListIterator//​ extinde Iterator și oferă în plus:
 +
 +  * navigare înapoi: //​previous()//;​
 +  * poziții: //​nextIndex()//,​ //​previousIndex()//;​
 +  * inserare: //​add(...)//;​
 +  * înlocuire: //​set(...)//​.
 +
 +Este util când trebuie să modificați lista "pe loc" sau să o parcurgeți bidirecțional.
 +
 +<code java>
 +import java.util.*;​
 +
 +class DemoListIterator {
 +    public static void main(String[] args) {
 +        List<​Integer>​ l = new ArrayList<>​(List.of(0,​ 1, 2, 0, 3));
 +
 +        // 1) Înlocuire „pe loc”: 0 -> 10
 +        ListIterator<​Integer>​ it = l.listIterator();​
 +        while (it.hasNext()) {
 +            if (it.next() == 0) it.set(10);
 +        }
 +
 +        // 2) Inserare după 1
 +        ListIterator<​Integer>​ it2 = l.listIterator();​
 +        while (it2.hasNext()) {
 +            if (it2.next() == 1) {  // elementul curent 1; cursorul este după 1 (între 1 și 2)
 +                it2.add(99); ​       // inserează între 1 și 2
 +                break;
 +            }
 +        }
 +
 +        System.out.println(l);​ // [10, 1, 99, 2, 10, 3]
 +    }
 +}
 +</​code>​
 +
 +<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ă folosim raw types (ex. //List//, //​Iterator//​),​ next()/​previous() întorc **Object** și conversia devine responsabilitatea programatorului - cu risc de //​ClassCastException//​ la rulare. </​note>​
 +
 +<code java>
 +import java.util.*;​
 +
 +class ObservatieIterator {
 +    public static void main(String[] args) {
 +        // 1) Parametrizat (recomandat):​ fără cast, sigur
 +        List<​String>​ l = new ArrayList<>​(List.of("​ana",​ "​ion"​));​
 +        Iterator<​String>​ it = l.iterator();​
 +        String s1 = it.next(); // String, nu Object
 +        ListIterator<​String>​ li = l.listIterator(l.size());​
 +        String last = li.previous();​ // tot String
 +        System.out.println("​OK (generic): " + s1 + ", " + last);
 +
 +        // 2) Neparametrizat (raw type): next()/​previous() -> Object, necesită cast
 +        List raw = new ArrayList();​ // WARNING: unchecked/​raw type
 +        raw.add("​text"​);​ // compilează
 +        raw.add(10); ​    // compilează (amestec de tipuri!)
 +        Iterator itr = raw.iterator();​ // WARNING: raw
 +        Object o1 = itr.next(); // "​text"​ ca Object
 +        Object o2 = itr.next(); // 10 ca Object
 +
 +        // Castul e responsabilitatea ta; poate eșua la rulare:
 +        try {
 +            String s2 = (String) o2; // ClassCastException (Integer -> String)
 +            System.out.println(s2);​
 +        } catch (ClassCastException ex) {
 +            System.out.println("​Eroare la rulare (raw type): " + ex);
 +        }
 +    }
 +}
 +</​code>​
 +
 +=== 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 //​ClassCastException//​ la rulare.
 +
 +Genericitatea rezolvă exact aceste probleme:
 +  * declarăm de la început **tipul elementelor**;​
 +  * compilatorul verifică și **interzice** inserarea altor tipuri.
 +
 +<code java>
 +List<​Integer>​ list = new ArrayList<>​();​ // parametrizare:​ lista conține DOAR Integer
 +list.add(5);​
 +list.add(7);​
 +
 +int x = list.iterator().next();​ // fără cast; auto-unboxing (Integer -> int)
 +int y = list.get(1); ​           // tot fără cast
 +
 +// list.add("​Text"​);​ // eroare de compilare: tip incompatibil
 +</​code>​
 +
 +<note warning>
 +Dacă aveți un caz real în care elementele pot fi de mai multe tipuri, **NU** reveniți la raw types. Folosiți:
 +  * **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**.  ​
 +
 +În toate celelalte situații folosiți colecții parametrizate (//​List<​Student>//,​ //​Map<​String,​ Integer>//​) pentru **siguranță și claritate**. </​note>​
 +
 +
 +=== 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 **hashCode()** returnează un **rezumat numeric** (int) al obiectului. Colecțiile pe bază de dispersie (//​HashSet//,​ //​HashMap//​) folosesc acest rezumat pentru localizare rapidă.
 +
 +<note important>​
 +  * Dacă două obiecte sunt **egale** prin //equals//, atunci **trebuie** să aibă același //​hashCode()//​.
 +</​note>  ​
 +
 +În **HashSet** și **HashMap**,​ operațiile de apartenență și unicitate funcționează astfel:
 +
 +  - colecția calculează **hashCode()** și alege locul elementului;​
 +  - confirmă prezența prin **equals()**.
 +
 +<code java>
 +import java.util.*;​
 +
 +class EqualsHashDemo {
 +
 +    // Varianta corectă: equals și hashCode folosesc ACELEAȘI câmpuri
 +    static final class GoodStudent {
 +        private final String id;
 +        GoodStudent(String id) { this.id = id; }
 +
 +        @Override
 +        public boolean equals(Object o) {
 +            if (this == o) return true;
 +            if (!(o instanceof GoodStudent g)) return false;
 +            return Objects.equals(id,​ g.id);
 +        }
 +
 +        @Override
 +        public int hashCode() {
 +            return Objects.hash(id);​
 +        }
 +    }
 +
 +    // Varianta greșită: equals suprascris, hashCode NU
 +    static final class BadStudent {
 +        private final String id;
 +        BadStudent(String id) { this.id = id; }
 +
 +        @Override
 +        public boolean equals(Object o) {
 +            if (this == o) return true;
 +            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
 +    }
 +
 +    public static void main(String[] args) {
 +        // Caz corect
 +        GoodStudent a1 = new GoodStudent("​42"​);​
 +        GoodStudent a2 = new GoodStudent("​42"​);​
 +
 +        System.out.println("​a1.equals(a2) = " + a1.equals(a2));​ // true
 +        System.out.println("​a1.hashCode = " + a1.hashCode()
 +                + " | a2.hashCode = " + a2.hashCode());​ // egale
 +
 +        Set<​GoodStudent>​ good = new HashSet<>​();​
 +        good.add(a1);​
 +        good.add(a2);​
 +        System.out.println("​HashSet<​GoodStudent>​.size = " + good.size());​ // 1
 +
 +        // Caz greșit
 +        BadStudent b1 = new BadStudent("​42"​);​
 +        BadStudent b2 = new BadStudent("​42"​);​
 +
 +        System.out.println("​b1.equals(b2) = " + b1.equals(b2));​ // true
 +        System.out.println("​b1.hashCode = " + b1.hashCode()
 +                + " | b2.hashCode = " + b2.hashCode());​ // diferite
 +
 +        Set<​BadStudent>​ bad = new HashSet<>​();​
 +        bad.add(b1);​
 +        bad.add(b2);​
 +        System.out.println("​HashSet<​BadStudent>​.size = " + bad.size());​ // 2 (duplicate)
 +
 +        System.out.println("​bad.contains(new BadStudent(\"​42\"​)) = "
 +                + bad.contains(new BadStudent("​42"​)));​ // false
 +    }
 +}
 +</​code>​
  
-<​HTML>​ 
-  <iframe src="​https://​docs.google.com/​file/​d/​19UNC9y5uSZ2xtG7HMVzABuX_ut26iURI/​preview"​ width="​640"​ height="​720"></​iframe>​ 
-</​HTML>​ 
  
  
poo/breviare/breviar-07.1510130450.txt.gz · Last modified: 2017/11/08 10:40 by mihai.nan
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