Documente Academic
Documente Profesional
Documente Cultură
Cuprins curs
CLASA Object
COLECII
Algoritmi
CLASA Object
n Java nu este permis motenirea multipl. Mai mult, clasele formeaz o structur de
arbore n care rdcina este clasa Object, a crei definiie apare n pachetul java.lang. Orice
clas extinde direct (implicit sau explicit) sau indirect clasa Object. Astfel, orice clas din Java
motenete metodele din clasa Object.
Cele mai importante dintre acestea sunt:
Compar obiectul curent cu cel primit ca parametru i returneaz true dac sunt egale. n
clasa Object metoda testeaz egalitatea referinelor la obiecte (ntoarce valoarea true numai
dac cele dou obiecte comparate sunt cu adevrat identice, adic au aceeai adres n
memorie)
Metoda equals trebuie s implementeze o relaie de echivalen (reflexiv, simetric,
tranzitiv). Este recomandabil ca la comparare unui obiect cu null sau cu un obiect de alt
tip metoda equals s ntoarc false.
Observaie. Metoda equals este folosit de metodele de cutare n colecii pentru testarea
egalitii.
Returneaz codul (de dispersie) asociat obiectului curent. Pentru clasa Object acesta se
calculeaz pornind de la adresa de memorie a obiectului.
Astfel, prin metoda hashCode fiecrui obiect i este asociat un numr ntreg (numit cod de
dispersie, valoare hash sau hash code ). Aceast metod trebuie s respecte urmtoarele
reguli:
- valoarea asociat de hashCode unui obiect nu se poate schimba dac obiectul nu se
modific
- metoda hashCode apelat pentru dou obiecte egale conform metodei equals trebuie
s ntoarc aceeai valoare (dou obiecte egale trebuie s aib aceeai valoare hash)
- este recomandabil ca dou obiecte diferite s aib valori hash diferite (n acest fel putnd
fi mbuntit performana tabelelor de dispersie) sau cel puin ca valorile s fie
uniform distribuite ntr-o plaj de valori
Observaie. Este necesar ca suprascrierea metodei equals s fie nsoit de suprascrierea
metodei hashCode, necesitate ce se observ cel mai bine n lucrul cu dicionare (Map)
Un posibil algoritm de generare a valorii hash a unui obiect este dat, spre exemplu, n cartea
Joshua Bloch Effective Java, Second Edition, Addison-Wesley, 2008
Astfel, se pornete calculul valorii de la o valoare ntreag nenegativ:
int val = 17;
Pentru fiecare cmp f care intervine n metoda equals se calculeaz o valoare hash c a sa
i se modific valoarea val calculat astfel:
val = val * 31 + c
Numrul 31 a fost ales pentru ca este numr prim impar i pentru c nmulirea cu 31 se
poate optimiza folosind shiftarea pe bii:
val * 31 == (val << 5) val
Se putea alege orice numr prim, chiar diferite la fiecare modificare a lui val.
Returneaz reprezentarea obiectului curent sub form de ir de caractere (de obiect din clasa
String). n clasa Object metoda returneaz un ir de forma
java.lang.Object@<hash_code>
Returneaz un obiect din clasa Class, care conine informaii despre clasa din care face
parte obiectului curent.
this.y=y; }
Observaii.
1. Dac vom comenta metoda equals din clasa Pereche, atunci metoda indexOf va returna -1
2. Dac vom comenta metoda hashCode din clasa Pereche, atunci metoda get va returna null
COLECII
O colecie este un obiect care grupeaz mai multe obiecte ntr-o singur unitate, aceste
obiecte fiind organizate n anumite forme.
Prin intermediul coleciilor avem acces la diferite tipuri de date cum ar fi vectori, liste
nlnuite, stive, mulimi matematice, tabele de dispersie, etc.
Coleciile sunt folosite att pentru memorarea i manipularea datelor, ct i pentru
transmiterea unor informaii de la o metod la alta.
Menionm c interfeele reprezint nucleul mecanismului de lucru cu colecii, scopul lor
fiind de a permite utilizarea structurilor de date independent de modul lor de implementare
(stabilesc metodele pe care trebuie s le pun la dispoziie fiecare tip de colecie). Vom nelege mai
bine acest mecanism cnd vom discuta despre interfee.
Iterable
Map
Collection
SortedMap
Set
List
SortedSet
Queue
NavigableMap
Deque
NavigableSet
Majoritatea tipurilor care fac parte din categoria colecii puse la dispoziie de Java se afl n
pachetul java.util.
Exist mai multe tipuri de colecii, corespunztoare interfeelor amintite:
mulime (HashSet, TreeSet) - este o colecie care nu conine duplicate i este menit s
abstractizeze noiunea matematic de mulime
list
LinkedList
ArrayList (nesincronizat), Vector (sincronizat)
Stack
PriorityQueue
ArrayDeque (coad dubl)
Din versiunea 5 au fost introduse tipuri generice sau tipuri parametrizate. Astfel,
programatorii pot specifica tipul obiectelor cu care o anumit clas lucreaz prin intermediul
parametrilor de tip.
ArrayList<String> a=new ArrayList<String>();
ArrayList<String> a=new ArrayList<>();//din versiunea 7
Pentru a compila o sursa cu o versiune mai veche a JDK-ului pentru a vedea ce era permis i ce nu
n versiunile mai vechi putei folosi opiunea -source a comenzii javac, de exemplu:
javac source 1.4 ExpVector.java
Exemplu
import java.util.*;
class ExpColectii5{
public static void main(String[] args) {
ArrayList<String> a=new ArrayList<String>();
a.add("abcd");
//a.add(new Integer(2));//eroare la COMPILARE
a.add("xyz");
String s=a.get(0);//nu mai trebuie cast
System.out.println(s);
System.out.print("Elementele sunt: ");
for(int i=0;i<a.size();i++)
System.out.print(a.get(i)+" ");
System.out.print("\nElementele afisate cu for-each: ");
for(String v:a)
System.out.print(v+" ");
System.out.println();
System.out.println("Direct "+a);// toString pentru colectie
//autoboxing/unboxing - tipuri primitive, clase infasuratoare
ArrayList<Integer> ai=new ArrayList<Integer>();
// ! Nu exist ArrayList<int>
ai.add(3); //autoboxing int-> Integer
ai.add(5);
ai.add(7);
int x=ai.get(1); //unboxing Integer -> int
System.out.println(x);
System.out.print("Elementele afisate cu for-each sunt: ");
for(int vi:ai)
System.out.print(vi+" ");
}
}
Observaii.
1. Preciznd tipul obiectelor care vor fi introduse n colecie nu mai este necesar conversia
explicit la extragerea unui element.
2. n cazul folosirii tipurilor generice, ncercarea de a utiliza n cadrul unei colecii a unui
element necorespunztor ca tip va produce o eroare la compilare, spre deosebire de
varianta anterioar ce permitea doar aruncarea unei excepii la execuie de tipul
ClassCastException n cazul folosirii incorecte a tipurilor
3. Faptul c anumite clase sunt parametrizate este utilizat doar de compilatorul Java nu i de
maina virtual, codul generat de compilatorul Java putnd fi executat i de versiunea 1.4 a
platformei.
i LinkedList sunt dou implementri ale unei liste n Java. Alegerea coleciei folosite
ntr-un program depinde de natura problemei ce trebuie rezolvat.
ArrayList
ArrayList
LinkedList
get
1
n
add
1
1
contains
n
n
next
1
1
remove
n
1
Accesarea unui element este mai rapid (timp constant) pentru ArrayList, n timp ce pentru
LinkedList este lent, accesarea unui element ntr-o list nlnuit necesitnd parcurgerea
secvenial a listei pna la elementul respectiv.
La eliminarea unui elemente din list, pentru ArrayList este necesar un proces de reindexare (shift
la stnga) a elementelor, n timp ce pentru LinkedList este rapid, presupunnd doar simpla
schimbare a unor legturi.
Astfel, vom folosi ArrayList dac avem nevoie de regsirea unor elemente la poziii diferite n
list, i LinkedList dac facem multe operaii de editare (tergeri, inserri) n list. De asemenea,
ArrayList foloseste mai eficient spaiul de memorie dect LinkedList, deoarece aceasta din urm
are nevoie de o structur de date auxiliar pentru memorarea unui nod.
Metodele principale ale clasei sunt ilustrate n exemplul urmtor.
Exemplu
import java.util.*;
class MetodeArrayList{
public static void main(String[] args) {
ArrayList<String> a=new ArrayList<String>();
//adaugare
a.add("abcd");
a.add("mn");
a.add(1,"xyz");//adaugare pe pozitia
a.add("bcde");
a.add("abcd");//se pot repeta
Amintim: n ceea ce privete cutarea unui obiect n colecie, pentru compararea a dou referine se
folosete metoda equals. n clasa Object exist metoda equals i, cum toate clasele extind direct
sau indirect Object, ele motenesc aceast metod. Metoda equals a clasei Object verific dac
obiectul specificat ca parametru este acelai cu cel curent. ntr-o clas putem suprascrie aceast
metod pentru a defini modul n care se face testul de egalitate pentru obiecte aparinnd acestei
clase.
Algoritmi
Coleciile pun la dispoziie metode care efectueaz diverse operaii utile cum ar fi: cutarea,
sortarea definite pentru colecii (pentru obiecte ce implementeaz interfee ce descriu colecii).
Aceti algoritmi se numesc i polimorfici deoarece aceeai metod poate fi folosit pe implementri
diferite ale unei colecii.
Cei mai importani algoritmi sunt metode statice definite n clasa Collections i permit efectuarea
unor operaii utile cum ar fi cutarea, sortarea etc.
Observaie: Algoritmi similari pentru tablouri se gsesc n clasa java.util.Arrays
Exemplu S adugm n finalul exemplului anterior secvena de cod
Collections.sort(a);
System.out.println(a);
class ExpPereche{
public static void main(String arg[]){
Pereche<Integer,String> p=new Pereche<Integer,String>(new
Integer(2),"abc");
System.out.println(p);
Pereche<String,String> p1=new Pereche<String,String>("abc","d");
System.out.println(p1);
Pereche<Double,Integer> p2=new Pereche<Double,Integer>(5.0,4); //nu 5,
trebuie 5.0 - autoboxing
System.out.println(p2);
//se poate folosi si fara parametri de tip, ca la colectii
Pereche pOrice=new Pereche(4,"abc");
System.out.println(pOrice);
}
}
ARBORI OARECARE
Primele probleme care se pun sunt aceleai ca pentru arborii binari: modalitile de
reprezentare i de parcurgere.
Considerm de exemplu urmtorul arbore
1
0
3
1
9
3
10 11
12
13
Se consider c arborele este aezat pe niveluri i c pentru fiecare vrf exist o ordine ntre
descendenii si.
Modul standard de reprezentare al unui arbore oarecare const n a memora rdcina, iar
pentru fiecare vrf i informaiile:
- info(i) = informaia ataat vrfului;
- fiu(i) = primul vrf dintre descendenii lui i;
- frate(i) = acel descendent al tatlui lui i, care urmez imediat dup i.
Lipsa unei legturi ctre un vrf este indicat prin .
Pentru arborele din exemplul considerat avem :
fiu
=(2,5,7,8,10,11,,,,, , ,);
frate =(,3,4,, 6, ,,9,,,12,13,).
Observaie. Prin aceast reprezentare fiecrui arbore oarecare i se poate asocia un arbore
binar, identificnd fiu cu st i frate cu dr. Aceast coresponden este biunivoc.
O alta reprezentare pentru arborii oarecare sunt listele de descendeni, reprezentare ce include:
- rdcina rad
- pentru fiecare vrf i: lista Li a fiilor vrfului i.
O a treia modalitate de reprezentare const n a memora pentru fiecare vrf tatl su. Aceast
modalitate este incomod pentru parcurgerea arborilor, dar se dovedete util n alte situaii (ca de
exemplu determinarea de lanuri, reprezentarea mulimilor disjuncte).
n unele cazuri este util s memorm pentru fiecare vrf att fiul i fratele su, ct i tatl
su.
Parcurgerea n preordine
Se parcurg recursiv n ordine rdcina i apoi subarborii care au drept rdcin descendenii
si.
Pentru exemplul considerat avem
1
1,2,3,4
1,2,5,6,3,7,4,8,9
1,2,5,10,6,11,12,13,3,7,4,8,9.
Concret, executm apelul Apreord(rad) pentru procedura:
procedure Apreord(x)
if x!=
vizit(x); Apreord(fiu(x)); Apreord(frate(x))
end
Parcurgerea n postordine
Se parcurg recursiv n ordine subarborii rdcinii i apoi rdcina.
Pentru exemplul considerat:
1
2,3,4,1
5,6,2,7,3,8,9,4,1
10,5,11,12,13,6,2,7,3,8,9,4,1.
Concret, executm apelul Apostord(rad) pentru procedura:
procedure Apostord(x)
if x!=
yfiu(x);
while y<>
Apostord(y); yfrate(y)
vizit(x)
end
void pre(Varf x) {
if( x != null ) {
System.out.print(x.info + "
pre(x.fiu);
pre(x.frate);
}
}
");
void post(){
post(rad);
}
void post(Varf x) {
Varf y = x.fiu;
while (y != null) {
post(y);
y = y.frate;
}
System.out.print(x.info + " ");
}
}
class ExpArbOarecareFF {
public static void main(String[] args) {
ArbOarecareFF ob = new ArbOarecareFF();
ob.creare();
System.out.print("Preordine :\t");
ob.pre();
System.out.print("\nPostordine :\t");
ob.post();
}
}
Parcurgerea pe niveluri
Se parcurg vrfurile n ordinea distanei lor fa de rdcin, innd cont de ordinea n care
apar descendenii fiecrui vrf. Pentru exemplul considerat:
1,2,3,4,5,6,7,8,9,10,11,12,13.
Pentru implementare vom folosi o coad C, n care iniial apare numai rdcina. Atta timp
ct coada este nevid, vom extrage primul element, l vom vizita i vom introduce n coad
descendenii si:
C ; C rad
while C
x C; vizit(x);
y fiu(x);
while y
y C; y frate(y)
end
Parcurgerea pe niveluri este n general util atunci cnd se caut vrful care este cel mai
apropiat de rdcin i care are o anumit proprietate/informaie.
Observaie. Folosirea clasei ArrayList este pur demonstrativ i nu neaprat necesar. Cum
fiecare vrf este nscris exact o dat n coad, puteam folosi un tablou cu n elemente i memora
indicii primului i ultimului element.