Sunteți pe pagina 1din 15

Autoboxing si Unboxing

Simplifica sintaxa si produc cod mai curat si usor de citit.


Integer intObject = new Integer(1);
int intPrimitive = 2;
Integer tempInteger;
int tempPrimitive;
tempInteger = new Integer(intPrimitive);
tempPrimitive = intObject.intValue();
tempInteger = intPrimitive; // Auto box
tempPrimitive = intObject; // Auto unbox

Autoboxing si unboxing sunt facilitati Java ce permit sa facem atribuiri fara o sintaxa
explicita de cast. Java va face cast-ul la rulare.
Observatie: folosirea autoboxing-ului in cicluri trebuie facuta cu grija pentru ca atrage dupa
sine costuri de performanta.
Colectii Java
In Java colectiile inmagazineaza, grupeaza si sorteaza obiecte. Putem implementa interfete si
extinde clase colectie pentru a defini colectii utilizator. JCF (Java Collection Framework) este
o arhitectura ce pune la dispozitie clase si interfete pentru crearea si manipularea colectiilor.
Asadar, JFC contine:
interfete, unele interfete sunt goale si functioneaza ca markere
implementari, ce asigura dezvoltarea colectiilor utilizator
algoritmi, sunt folositi pentru a rezolva anumite probleme cum ar fi sortarea sau
cautarea intr-o colectie. Algoritmii sunt polimorfici.
O colectie este un obiect destinat sa gestioneze un grup de obiecte:
- un obiect din colectie se numeste element
- primitivele nu sunt permise intr-o colectie
Avantajele folosirii JCF:
ofera colectii predefinite cum ar fi multimile, tabelele de distributie si hartile
faciliteaza referirea cu ajutorul interfetelor
reduce efortul de design si implementare
Avem colectii de diferite tipuri ce implementeaza multe structuri de date comune: stive, cozi,
siruri dinamice, tabele de distributie.

Interfetele colectie formeaza o ierarhie. Radacina este formata din Collection. Elementele
unei Collection pot fi sortate sau nu si pot contine duplicari. Nu exista implementari directe
ale acestei interfete. Toate colectiile pot fi traversate folosind sintaxa foreach. Subinterfete
derivate sunt:
Set, este o colectie ce nu poate contine duplicari si poate contine cel mult un element
null. Set-ul nu are index.
o interfata direct derivata din Set este SortedSet in care elementele sunt, in plus,
ordonate natural (dupa codurile caracterelor). TreeSet furnizeaza o implementare
sortata
direct derivata din SortedSet este interfata NavigableSet, care adauga metode de
navigare bidirectionala (crescator sau descrescator) a multimii si returneaza elemente
ce se potrivesc intr-o oarecare masura unui sablon de cautare. Exemplu de folosire a
lui NavigableSet:
public static void main(String args[]) {
//cream o SortedSet ca instanta a unei clase TreeSet
SortedSet<String> s=new TreeSet<>();
//cream un NavigableSet
NavigableSet<String> n=(NavigableSet<String>)s;
//adaugam elemente
n.add("ion");
n.add("Ion");
n.add("Vasile");
n.add("vasile");
n.add("gelu");
System.out.println("afisare in ordine crescatoare");
Iterator<String> a=n.iterator();
while(a.hasNext()){

System.out.println(a.next());
}
System.out.println("afisare in ordine descrescatoare");
Iterator<String> d=n.descendingIterator();
while(d.hasNext()){
System.out.println(d.next());
}

}
List,

direct derivata din Collection, poate contine elemente duplicat. Elementele


sunt stocate intr-o anumita ordine, data de un index intreg. Elementele pot fi inserate
sau sterse de oriunde din lista. Sunt oferite si metode de cautare. Poate contine mai
multe elemente nule. Listei ii este atasat un iterator. Clasa ArrayList reprezinta un sir
ce creste dinamic daca numarul de elemente depaseste dimensiunea initiala.
Queue, direct derivata din Collection, contine metode aditionale pentru inserare,
inspectare sau extragere de elemente. Nu este recomandabil sa se insereze elemente
nule
BlockingQueue, direct derivata din Queue, contine metode aditionale ce ne permit sa
asteptam pina se creaza un spatiu liber in coada inainte de a insera un nou element
BlockingDeque suporta operatii de blocare, precum asteptarea pentru eliberarea unui
spatiu sau asteptarea ca coada sa devina nevida inainte de a extrage un element. Este
thread safe, iar numarul sau de elemente poate fi limitat. Extinde atat Deque cat si
BlockingQueue.
Deque (double ended queue). Permite inserarea si stergerea la oricare capat. Interfata
nu furnizeaza metode pentru acces indexat, dar putem utiliza metode ca
removeFirstOccurence() si removeLastOccurence() pentru a extrage elemente
interioare dintr-o coada dubla. Putem sa o folosim pentru a crea structuri LIFO sau
FIFO. Nu este recomandabil sa inseram elemente nule, pentru ca null este folosit
pentru a evidentia ca coada este vida

Avem si alte interfete ce contin colectii aditionale in Collection Framework:


Map, contine perechi cheie-valoare. Nu poate contine chei duplicat si fiecare cheie
poate contine o singura valoare. Mai este cunoscut sub numele associative arrays.

Map

nu extinde interfata Collection pentru ca reprezinta mapari si nu colectii de


obiecte. HashTable este o implementare sincronizata a lui Map. HashMap este o alta
implementare a lui Map doar ca accepta chei si valori nule si nu este sincronizata
SortedMap, extensie a lui Map si retine elementele intr-o ordine ascendenta.
Elementele pot fi sortate folosind un Comparator, pe care il vom defini impreuna cu
colectia. Toate iteratiile si operatiile de view facute pe o mapare sortata sunt returnate
in ordinea cheii. TreeMap este o implementare directa a lui SortedMap.
ConcurrentMap, extensie directa a lui Map, este o versiune thread safe.
NavigableMap extinde capabilitatile lui SortedMap prin introducerea metodelor de
navigare si returnare a elementelor ce sunt apropiate de un anumit sablon. Exemplu de
folosire a interfetei:
public static void main(String[] args) {
//cream un SortedMap folosind clasa TreeMap
SortedMap<Double, String> s=new TreeMap<>();
NavigableMap<Double, String> n=(NavigableMap<Double, String>)(s);
//adaugam elemente
n.put(1.0,"Ion");
n.put(2.0,"ion");
n.put(3.0,"vasile");
n.put(4.0,"Vasile");
n.put(5.0,"gicu");
Double test=new Double(9.0);
//lowerKey() este utilizata pentru a afisa cea mai mare cheie
//strict mai mica decat cheia data: test
Double lower_key=(Double)n.lowerKey(test);
System.out.println("cheia mai mica: "+test+" - "+lower_key+" !");
//higherKey() este utilizata pentru a afisa cea mai mica cheie
//strict mai mare decat cheia data: test
Double higher_key=(Double)n.higherKey(test);
System.out.println("cheia mai mare: "+test+" - "+higher_key+" !");
}
Deoarece este bidirectional navigabila, elementele unui SortedMap pot fi accesate

in
ordinea crescatoare sau descrescatoare a cheii.
Interfata ConcurrentNavigableMap extinde atat ConcurrentMap cat si
NavigableMap. Astfel, interfata furnizeaza metode de navigare ce returneaza cea mai
apropiata potrivire a unui sablon dat, precum si traversarea bidirectionala, atat in
ordine crescatoare cat si descrescatoare. Interfata este thread safe.
In 6.0 au fost adaugate urmatoarele clase ce implementeaza unele dintre interfetele anterioare:
ConcurrentSkipListSet, implementeaza NavigableSet. Elementele sale sunt
sortate dupa ordinea naturala sau printr-un Comparator, furnizat la instantiere. Nu
sunt permise valori null
ConcurrentSkipListMap, implementeaza ConcurrentNavigableMap si are o
functionalitate asemanatoare cu ConcurrentSkipListSet. Nu sunt permise valori
null pentru chei
LinkedBlockingDeque, implementeaza BlockingDeque. Are un constructor cu
parametru intreg pentru a specifica capacitatea maxima. Daca nu este specificata
aceasta va fi Integer.MAX_VALUE
AbstractMap.SimpleEntry este folosita pentru a crea o mapare utilizator, in care un
obiect Entry este utilizat pentru gestiunea maparilor. Metoda setValue() este
folosita pentru modificarea valorilor

AbstractMap.SimpleImmutableEntry este folosita pentru a crea o mapare utilizator


in care un obiect AbstractMap.SimpleImmutableEntry este utilizat pentru gestiunea
maparilor. Nu suporta metoda setValue(). Este thread safe.
ArrayDeque este o implementare a lui Deque, este redimensionabila si nu este
sincronizabila, ceea ce inseamna ca mai multe fire nu pot acces sirul in mod
concurent. Nu este thread safe si nu permite adaugarea valorilor null. Deoarece
metodele add(), addFirst(), offerFirst(), offerLast() fac apeluri unchecked
catre un obiect Deque, trebuie sa compilam acest cod cu Xlint:unchecked option.
Exemplu de folosire a clasei ArrayDeque:
public static void main(String args[]) {
ArrayDeque ad = new ArrayDeque(1);
//inserare folosind metodele unchecked add() si addFirst()
ad.add("Java");
ad.add("VB");
ad.add("C++");
ad.addFirst("Oracle");
//inserare folosind metodele unchecked offerFirst() si
offerLast()
ad.offerFirst("MySql");
ad.offerLast("SQL");
//metode de consultare
System.out.println("primul element este :" + ad.peekFirst());
System.out.println("ultimul element este :"+ ad.peekLast());
//metode de stergere
System.out.println("stergem primul element :"+ ad.pollFirst());
System.out.println("stergem ultimul element :"+ ad.pollLast());
}

JCF este sustinuta de anumite interfete auxiliare ce se gasesc in pachetul java.util. Aceste
interfete ne permit sa manipulam elementele unei colectii. Acestea sunt:
RandomAccess este o interfata marker folosita de liste pentru a inlesni accesul rapid la
elemente listelor cu acces secvential sau aleator. Implementari ca Vector sau
ArrayList folosesc aceasta interfata
Comparable ce contine metoda compareTo() si permite doar o optiune de sortare
Comparator ne asigura ca o colectie este ordonata folosind o operatie de ordonare
utilizator. Interfata are doua metode compare() (returneza un intreg) si equals()
(returneza un boolean). Ne permite definirea mai multor optiuni de sortare. Este
implementata partial de clasa abstracta Collator.
Iterator permite parcurgerea inainte intr-o colectie. Are metodele next(),
hasNext() si remove(). Iteratorul unifica accesul la colectii
ListIterator este o extensie a Iterator si permite navigarea in ambele directii. Are
metodele add(), remove() si set() pentru manipulare, next() si previous() pentru
parcurgere, nextIndex() si previousIndex() ce returneza indexul si hasNext() si
hasPrevious() pentru a verifica daca mai exista un element dupa respectiv inaintea
elemetului specificat
Interfata List este implementata de clasele ArrayList, LinkedList si Vector. Metodele
interfetei sunt:
add(element), add(index,element) adauga elementul specificat la sfarsitul listei
sau la un index specificat.

remove(element), remove(index,element) sterge prima aparitie a elementului


specificat sau de la un index specificat. Stergerea determina mutarea spre stanga a
elementelor listei
size()returneaza numarul elemetelor din lista.
contains(element)returneaza true daca lista contine un anumit element.
set(index,element)seteaza valoarea unui element de pe o anumita pozitie.
In cele ce urmeaza prezentam un cod ce ilustreaza principalele operatii dintr-o lista:
public class WordQuery {
static BufferedReader query = new BufferedReader(new InputStreamReader(
System.in));
static String[] nume = new String[] { "Ion", "Vasile", "Gicu", "Nelu",
"Elvis", "Poasca" };
// definim un ArrayList ce contine o lista de nume
static List<String> listaNume = new ArrayList<>(Arrays.asList(nume));
private static int getWordCount() {
// returnam numarul de elemente din lista
int numarDeNume = listaNume.size();
System.out.println("avem " + numarDeNume + "nume in lista");
return numarDeNume;
}
private static void outputSortedList() {
// cream o lista de elemente sortate. pentru inceput cream o noua
lista
List<String> listaSortata = (List<String>) listaNume;
// utilizam metoda sort pentru sortare
Collections.sort(listaSortata);
String j = null;
// obtinem un iterator al listei
Iterator<String> i = listaSortata.iterator();
// parcurgem lista, verificand daca mai avem elemente disponibile
while (i.hasNext()) {
// trecem la urmatorul element disponibil
j = (String) i.next();
System.out.println(j);
}
}
private static boolean checkName(String nume) {
// verificam daca un element se afla in lista
boolean esteInLista = listaNume.contains(nume);
if (esteInLista)
System.out.println("acest element este in lista");
else
System.out.println("acest element nu este in lista");
return esteInLista;
}
private static void insertName(String nume) {
System.out.println("numele de inserat: " + nume);

try {
// adauga un element in lista
listaNume.add(nume);
}
// tartarea exceptiilor posibil a aparea
catch (UnsupportedOperationException e) {
System.out.println("Unsupported operation");
} catch (ClassCastException b) {
System.out.println("Class cast");
} catch (NullPointerException n) {
System.out.println("Null pointer");
} catch (IllegalArgumentException t) {
System.out.println("Illegal argument");
}
}
private static boolean removeName(String nume) {
if (checkName(nume))
// indeparteaza un element din lista
return (listaNume.remove(nume));
else
return false;
}
// utilitar pentru obtinerea unui nume de la intrare
private static String getName() {
String name = "";
try {
System.out.print("Nume: ");
name = query.readLine();
} catch (IOException e) {
System.out.println("Invalid name entry");
}
return name;
}
private static void printCommands() {
System.out.println("1: numara cuvinte");
System.out.println("2: sorteaza cuvinte");
System.out.println("3: cauta cuvant");
System.out.println("4: insereaza cuvant");
System.out.println("5: sterge cuvant");
System.out.println("6: afiseaza lista de optiuni");
System.out.println("0: Exit");
}
public static void main(String args[]) {
boolean gata = true;
printCommands();
while (gata) {
try {
System.out.print("Comanda: ");
int argType = Integer.parseInt(query.readLine());
switch (argType) {
case 0: {
gata = false;
break;

}
case 1: {
getWordCount();
break;
}
case 2: {
outputSortedList();
break;
}
case 3: {
checkName(getName());
break;
}
case 4: {
insertName(getName());
break;
}
case 5: {
removeName(getName());
break;
}
case 6: {
printCommands();
break;
}
default: {
System.out.println("Comanda invalida");
break;
}
}
} catch (Exception e) {
System.out.println("Operatie invalida, programul va
iesi" + e.getMessage());
System.exit(0);
}
} // while
} // main
} // class

Implementari ale interfetelor din JCF sunt grupate in urmatoarele categorii:


implementari cu caracter general, ce cuprind majoritatea cerintelor:
o pot fi serializabile si clonate utilizand metoda clone()
o permit folosirea cheilor, a valorilor duplicat si a elementelor null
o au un comportament consistent
o contin iteratori care pot detecta orice modificari neautorizate si produc oprirea
iterarii
o sunt predefinit desincronizate
Principalul factor in alegerea uneia sau alteia dintre implementari il reprezinta viteza.
Printre aceste clase avem:
o HashMap, TreeMap si LinkedHashMap ce implementeaza interfata Map.
TreeMap este folosit pentru a ne asigura ca rezultatul iteratiilor este ordonat. In
6.0 implementarea lui TreeMap implementeaza si interfata NavigableMap.
Daca ordinea elementelor adaugate intr-un TreeMap nu este importanta putem
folosi HashMap. Ordinea intr-un HashMap nu este garantat ca ramine aceeasi pe
tot parcursul exploatarii. LinkedHashMap contine o iteratie ordonata, dar de
costuri mai mici decat TreeMap. La creare putem specifica ordinea iteratiei si
aceasta este ordinea de inserare, sau putem folosi ordinea predefinita de

accesare de la cea mai recenta cheie accesata la cea mai demult accesata. Clasa
poate fi implementata ca un cash.
o HashSet, TreeSet si LinkedHashSet ce implementeaza interfata Set.
TreeSet utilizeaza o iteratie logaritmica pentru operatii ca adaugarea si
stergerea. Ordinea elementelor ramine aceeasi. In 6.0 TreeSet implementeaza
si interfata NavigableSet. Daca ordinea elementelor adaugate intr-un TreeSet
nu este importanta putem folosi HashSet. LinkedHashSet contine o iteratie
ordonata, dar de costuri mai mici decat TreeSet. Ordinea este de la ultimul
adaugat element la cel mai recent adaugat.
o ArrayList si LinkedList, implementeaza interfata List. ArrayList este mai
rapida decat LinkedList pentru ca utilizeaza metoda locala
System.arraycopy() si ofera timp de acces constant. Adaugarea se face
printr-o operatie de complexitate amortizata. Ordinea elementelor ramine
aceeasi. Celelalte operatii se executa in timp linear
o PriorityQueue, implementeaza interfata Queue si este o coada ordonata ce
foloseste o structura de heap pentru prioritati. Poate fi ordonata in ordine
naturala sau prin implementarea unui Comparator. Capul cozii este accesat
prin metode ca: poll(), remove() sau peek()
o ArrayDeque, implementeaza interfata Deque si este redimensionabila. Nu este
thread safe.
o Hashtable, implementeaza interfata Map. Este identica cu HashMap, dar este
sincronizata si nu poate avea elemente null. Hashtable inmagazineaza
elemente printr-o cheie asociata, ceea ce inseamna acces rapid atunci cand
lucram cu cantitati mari de date. Ordinea elementelor ramane constanta de-a
lungul timpului.
Implementari comode sau mini-implementari, contin in general metode statice:
o Collections.EMPTY_SET, Collections.EMPTY_MAP si
Collections.EMPTY_LIST, reprezinta un SET, MAP respectiv LIST, vide. Pot fi
utilizate ca date de intrare pentru metode, atunci cand nu dorim sa transmitem
valori. Acestea sunt nemodificabile
o Collections.singleton, returneza un SET nemodificabil ce contine doar un
singur element
o Collections.nCopies, returneza un LIST nemodificabil ce contine copii ale
aceluiasi element. Exemplu: List l = new
ArrayList(Collections.nCopies(100, "vaca")); Am creat o lista ce
contine de 100 de ori cuvantul vaca
o Array.asList, returneza un LIST de dimensiune fixa. Orice adaugare sau
stergere arunca o UnsupportedOperationException pentru ca dimensiunea
este nemodificabila.
Implementari Wrapper, contin metode factory (care reprezinta un fel de constructor
generic pe care il putem folosi pentru a crea mai multe tipuri de instante ale claselor)
statice ce impacheteaza colectiile actuale si aduc extra functionalitati. Avem
urmatoarele categorii de wrapperi:
o Nemodificabili: previne modificarea colectiei de catre utilizator prin aruncarea
unei exceptii UnsupportedOperationException in cazul in care s-ar intampla
acest lucru. Prin aceasta marim securitatea structurii de date, facand-o readonly. In aceasta categorie avem urmatoarele metode:
public static Collection unmodifiableCollection(Collection c);
public static Set unmodifiableSet(Set s);
public static List unmodifiableList(List list);

public static Map unmodifiableMap(Map m);


public static SortedSet unmodifiableSortedSet(SortedSet s);
public static SortedMap unmodifiableSortedMap(SortedMap m);

In acest sens iata un exemplu:


public class Unsupported {
static void test(String msg, List<String> list) {
System.out.println("--- " + msg + " ---");
Collection<String> c = list;
Collection<String> subList = list.subList(1, 8);
// Copy of the sublist:
Collection<String> c2 = new ArrayList<String>(subList);
try {
c.retainAll(c2);
} catch (Exception e) {
System.out.println("retainAll(): " + e);
}
try {
c.removeAll(c2);
} catch (Exception e) {
System.out.println("removeAll(): " + e);
}
try {
c.clear();
} catch (Exception e) {
System.out.println("clear(): " + e);
}
try {
c.add("X");
} catch (Exception e) {
System.out.println("add(): " + e);
}
try {
c.addAll(c2);
} catch (Exception e) {
System.out.println("addAll(): " + e);
}
try {
c.remove("C");
} catch (Exception e) {
}
// The List.set() method modifies the value but
// doesnt change the size of the data structure:
try {
list.set(0, "X");
} catch (Exception e) {
System.out.println("List.set(): " + e);
}
}
public static void main(String[] args) {
List<String> list = Arrays.asList("A B C D E F G H I J K L".split("
"));
test("Modifiable Copy", new ArrayList<String>(list));
test("Arrays.asList()", list);
test("unmodifiableList()",
Collections.unmodifiableList(new
ArrayList<String>(list)));
}
}

De sincronizare: pentru definirea colectiilor sincronizate. In aceasta categorie


avem urmatoarele metode:
public
public
public
public
public
public

static
static
static
static
static
static

Collection synchronizedCollection(Collection c);


Set synchronizedSet(Set s);
List synchronizedList(List list);
Map synchronizedMap(Map m);
SortedSet synchronizedSortedSet(SortedSet s);
SortedMap synchronizedSortedMap(SortedMap m);

De verificare: este o masura pentru verificarea tipului colectiei.


ClassCastException este aruncata daca se incearca a se adauga un element
de tip nepotrivit. In aceasta categorie avem urmatoarele metode:
public
type);
public
public
public
public
type);
public
type);

static Collection checkedCollection(Collection c, Class


static
static
static
static

List checkedList (List list, Class type);


Map checkedMap (Map map, Class valueType);
Set checkedSet (Set set, Class type);
SortedMap checkedSortedMap (SortedMap set, Class

static SortedSet checkedSortedSet (SortedSet set, Class

Implementari pentru scopuri speciale.


o EnumSet si CopyOnWriteArraySet implementeaza interfata Set. EnumSet este
folosita cu tipuri enum. Ordinea de iteratie este ordinea naturala. Nu este
thread safe. CopyOnWriteArraySet unde implementarea metodele add(),
set() si remove() determina creerea unei copii a sirului de baza.
Implementarea este thread safe
o CopyOnWriteArrayList implementeaza interfata List. Este asemanatoare ca
functionalitate cu CopyOnWriteArraySet. Putem folosi aceasta clasa atunci
cand facem modificari rare ale listei, dar frecvente traversari, in aplicatii
multifir
o EnumMap, WeakHashMap si IdentityHashMap implementeaza interfata Map.
EnumMap este folosita pentru chei de tip enumerare si fiecare cheie trebuie sa
fie de acelasi tip enumerare. Este reprezentata intern ca un sir, iar cheile sunt
ordonate natural. Nu este thread safe. WeakHashMap stocheaza chei slabe.
Aceasta inseamna ca daca o cheie nu mai este folosita atunci este automat
trimisa la garbage collector. IdentityHashMap foloseste egalitatea referintelor,
aceasta inseamna o relatie de egalitate in sensul operatorului ==.
Implementari concurente, care sunt thread safe si sunt continute in pachetul
java.util.concurrent.
o ConcurrentSkipListSet, este o implementare concurenta a interfetei
NavigableSet. Ordinea elemente este implicit cea naturala, dar putem sa o
customizam furnizand un Comparator. Toate operatiile de inserare, stergere
sau acces al elementelor sunt thread safe. Aceasta implementare nu permite
elemente null.
o LinkedBlockingQueue, simuleaza o FIFO, elementele fiind aranjate inlantuit
de la cel mai tarziu la cel mai devreme element inserat in coada, cu cel mai
batrin la inceput. ArrayBlockingQueue, asemanatoare lui
LinkedBlockingQueue, dar implementata cu siruri. PriorityBlockingQueue,
asemanatoare lui PriorityQueue.
o DelayQueue este o coada de elemente intarziate. Un element intarziat este un
element a carui intarziere a expirat, astfel incat metoda getDelay() returneaza

o valoare <=0. Doar elementele intarziate pot fi obtinute din coada. In capul
cozii se afla elementul ce a expirat cel mai recent
o SynchronousQueue este o clasa in care nu putem insera un element pina cand
un alt fir nu incearca sa-l extraga
o LinkedBlockingDeque, implementeaza interfata BlockingDeque sub forma
unor noduri inlantuite
o ConcurrentHashMap, este o implementare a interfetei ConcurrentHashMap.
Operatiunile de regasire nu presupun blocarea si nu avem suport pentru
blocarea intregii structuri in vederea accesului
o ConcurentSkipListMap, este o implementare a interfetei
ConcurrentNavigableMap. Ordinea este cea naturala sau data de furnizarea
unui Comparator
Implementari abstracte
o AbstractCollection, ofera o implementare de baza a interfetei Collection
si nu este nici Set si nici List. Trebuie implementate metodele size() si
o
o

o
o
o

iterator()
AbstractSet,

ofera o implementare de baza a interfetei Set. Trebuie


implementate metodele size() si iterator()
AbstractList, ofera o implementare de baza a interfetei List. Trebuie
implementate metodele size() si get(). Nu trebuie furnizata definitie pentru
iterator()
AbstractSequentialList, trebuie implementate metodele size() si
listIterator
AbstractQueue, ofera o implementare de baza a interfetei Queue. Trebuie
implementate metodele peek(), poll() si size()
AbstractMap, ofera o implementare de baza a interfetei Map. Trebuie
implementata metoda entrySet(). Are doua inner clase:

AbstractMap.SimpleEntry, suporta metoda setValue()


AbstractMap.SimpleImmutableEntry, nu suporta metoda
setValue()

Metoda hashCode()
Este membra a clasei Object si este folosita pentru a genera o valoare intreaga pentru orice
obiect. Fiecare obiect genereaza si inmagazineaza o unica valoare hashcode pe post de cheie.
Sintaxa metodei folosita pentru asa ceva este:
public int hashCode(Object);

si ofera suport pentru implementarile Hashtable si HashMap.


Codul unic al unui obiect este determinat de datele continute in obiect. Daca datele continute
in doua obiecte sunt egale atunci valoarea hashcode-ului este acelasi, adica daca
ob1.equals(ob2) atunci ob1.hashCode()==ob2.hashCode().
Putem invoca metoda hashCode() din obiecte ce implementeaza interfata Collection.
Pentru aceasta trebuie sa ne asiguram ca clasele ce suprascriu Object.equals() suprascriu si
Object.hashCode(). Conform contractului daca doua obiecte sunt egale via equals()
trebuie sa aiba acelasi hashCode(). Daca metoda este invocata de mai multe ori din acelasi
obiect ea va produce acelasi intreg pe toata durata aplicatiei.
Algoritmi folositi in gestionarea colectiilor
Metodele colectiilor, care sunt polimorfice, cuprind utilitatile predefinite oferite de JDK.
Colectiile au o ordine naturala predefinita (data de codificarea ASCII sau Unicode), aceasta
ordine poate fi modificata de utilizator. Metodele ce implica compararea sunt in general

supraincarcate. O prima varianta de supraincarcare are ca argument o lista sau o colectie in


timp ce a doua are pe linga acest argument inca unul, un Comparator.
Pentru a sorta elementele unei liste toate elementele listei treebuie sa implementeze interfata
Comparable. Apelul lui sort() sorteaza elementele in ordine naturala, dar putem defini un
Comparator pentru a modifica aceasta ordine. Avem doua forme ale metodei sort:

public static <T extends Comparable<? super T>> void sort(List<T>


list), foloseste algoritmul de sortate prin interclasare (merge sort)
public static <T> void sort(List<T> list, Comparator<? super T> c),

sortarea se face in acord cu comparatorul definit


Pentru a cauta un element intr-o colectie folosim metoda binarySearch(), care presupune ca
lista este ordonata crescator. Asadar, anterior apelelului trebuie sa apelam sort(). Are doua
forme:

public static <T> int binarySearch(List<? extends Comparable<? super


T>> list, T key)
public static <T> int binarySearch(List<? extends T> list, T key,
Comparator<? super T> c)

Valoarea returnata este mai mare sau egala cu zero, reprezentand indexul cheii, daca cheia
este gasita sau un rezultat negativ, altfel.
Avem trei algoritmi cu ajutorul carora manipulam datele unei liste.
public static <T> void fill(List<? super T> list, T obj), ceea ce
determina initializarea tuturor elementelor listei cu valoarea celui de-al doilea
parametru
public static void reverse(List<?> list), rearanjeaza in ordine inversa
elementele listei. Ruleaza in timp liniar si arunca o
UnsupportedOperationException daca lista nu suporta setari

public static <T> void copy(List<? super T> dest, List<? extends T>
src), suprascrie o lista destinatie cu toate elementele dintr-o lista sursa

Suport pentru monitorizare si management


Platforma Java pune la dispozitie interfete si instrumente pentru a ne ajuta sa monitorizam
JVM si aplicatiile Java. Unele dintre cele mai intalnite probleme de catre programatori pe
timpul dezvoltarii aplicatiilor sunt:
Memorie insuficienta: indicata, de obicei, printr-o exceptie OutOfMemoryException.
Cauzele pot fi urmatoarele:
o Spatiu insuficient in heap atunci cand aplicatia creaza un nou obiect
o Esecul incarcarii unei clase intr-o zona de memorie non-heap a Hotspot VM
implementation
o O alocare esueaza in heapul nativ
Java Heap Analysis Tool, sau JHAT, este un instrument de diagnostic ce ne permite sa
vizualizam problemele heap-ului, utilizand un browser. Permite interogari utilizator
ale problemelor heap-ului, utilizand Object Query Language (OQL)
Scurgeri de memorie: cand o aplicatie devine blocata, aceasta se poate datora
memoriei neeliberate, anterior alocata. Cauzele ar putea fi:
o Referinte neintentionate catre obiecte
o Rate de crestere ridicate ale claselor si obiectelor
o Un numar neasteptat de instante ale clasei
Pentru a diagnostica aceasta folosim JConsole, JStat, JMap
Finalizari: suprautilizarea sau subutilizarea finalizarilor poate cauza
OutOfMemoryError. Clasa Object defineste metoda finalize(), care este invocata
de garbage collector inaintea eliberarii spatiului de memorie. In cazul in care

finalize()

este suprascrisa trebuie sa ne asiguram ca aceasta nu interfera operatiile


garbage collector-ului. Una dintre cauzele erorii mai sus mentionate este ca obiectele
asteapta sa fie finalizate si nu pot fi astfel colectate de garbage collector. Folosim
JConsole si JMap pentru a monitoriza aceasta problema
Deadlock: gestionate de pachetul java.util.concurrent.locks. Spre exemplu,
clasa AbstractOwnableSynchronizer din pachet, permite unui fir sa fie proprietarul
exclusiv al unui sincronizator
Fire ciclabile: sunt generate de cicluri infinite. Putem folosi JConsole cu JTop.
High lock contention: atunci cand un numar foarte mare de fire asteapta ca un obiect
sa fie deblocat. JConsole gestioneaza situatia.
Java Management Extensions (JMX) poseda o multime de instrumente si extensii pentru
monitorizarea si managementul aplicatiilor. Aceasta se face prin introducerea unui agent JMX
in aplicatie catre care clientii JMX se pot conecta. JMX foloseste diverse mecanisme de
transport precum RMI. In 5.0 trebuie sa pornim aplicatia utilizand D
com.sun.management.jmxremote. Aceasta nu mai este obligatoriu in 6.0 pentru ca
JConsole o poate atasa orice aplicatie ce ruleaza. Lansarea toolului se face prin comanda
jconsole in linia de comanda. Cand JConsole porneste ea trebuie sa fie capabila sa detecteze
aplicatiile Java care ruleaza de pe masina locala. Putem alege aplicatia din interfata utilizator
JConsole. Cand aplicatia a fost selectata suntem conectati cu succes la agentul JMX. Cateva
dintre functiile lui JConsole:
Monitorizarea utilizarii memoriei de catre aplicatie
Monitorizarea numarului de clase incarcate
Detalii despre firele in rulare
Verificarea statutului JVM ce gazduieste aplicatia
Avem urmatoarele comenzi utilitare in linia de comanda pentru diagnosticare si monitorizare,
incepand cu 6.0:
JStat este un instrument de monitorizare statistic, experimental. Comanda jstat
gcutil arata o statistica a utilizarii heapului si garbage collection dat de id-ul de
proces. Pentru a determina id-ul folosim comanda jps.
JHat analizeaza problemele heapului. Pune la dispozitie interogari predefinite pentru a
examina clasele, instantele, histogramele de heap si obiectele ce asteapta sa se
finalizeze
JStack afiseaza traseele stivei Java. Acest tool permite detectarea firelor blocate mortal
JMap permite sa vizualizam histograme ale heapului, prin comanda jmap histo
Pasi pentru monitorizare: inseramm plug-in-ul pentru JMX in Eclipse: Help>Install new
Software...>Add

Name: eclipse-jmx
URL: http://eclipse-jmx.googlecode.com/svn/trunk/net.jmesnil.jmx.update/

Acceptam termenii. Resetam Eclipse. Intram in perspectiva JMX. La conectare localhost,


port: 8686. portul trebuie aflat din server.log, la pornirea Glassfish-ului. din administration
Console, nodul: admin service>JMX Connector vedem numele portului si trebuie sa ne
asiguram ca la address avem 127.0.0.1.
Tema:

1. Sa se scrie o clasa derivata din ArrayList care poate fi parcursa in ordine naturala,
dar si in doua ordonari custom: din trei in trei sau in ordinea, primul,ultimul, al doilea,
penultimul, etc.
3 iteratori: din 1 in 1; din 3 in 3 int iterator = -3; si capetele
Declarare de clase interne implements Iterator- constructor has next->boolean remove ; interfata iterator
2. Se da o lista de coduri de produse (ex: "1S01", "1S02", "1M01", "1S01", etc) si o
descriere a fiecarui cod sub forma: ("Tricou Albastru", "1S01"), ("Tricou Negru",
"1S02") etc. Sa se creeze un program eficient pentru obtinerea unui raport ce cuprinde
descrierea fiecarui produs si numarul de aparitii in lista de coduri. Raportul va fi
ordonat alfabetic dupa descriere
//Clasa produse( )
HashMap StringString( vezi curs )
3. Folositi o structura de date Deque, ca stiva, pentru a testa ca parantezele rotunde se
inchid corect intr-o expresie data de un String. Ca date de intrare vor fi mai multe
expresii, considerate constante (ex: if ((a == b) && (x != y));, if ((a ==
b) && (x != y)));). Testul va afisa un mesaj de forma:
Expresia 1 corect
Expresia 2 false ....

Push(de paranteza ) si la sf pop(paranteza)


Deque<Character> d = new Dwque
4. Fie un magazin de tricouri, il vom numi Dukes Choice. Tricourile (id, descriere,
culoare, marime, numar bucati) intra (se achizitioneaza) sau ies (se vand din magazin).
Dorim sa facem un inventar al tricourilor si sa tiparim la consola raportul rezultat,
dupa un numar de tranzactii (id tricou, tip tranzactie, numar bucati tranzactionate).
Dorim doua rapoarte: unul in ordinea crescatoare a numarului de bucati si altul in
ordinea alfabetica a descrierii. -> comparator pe nr de bucati, si unul pe descriere
Interfata cu push, pop
Tricouri implements Interfata
Clasa tranzactie // un Map cu <StringString>
Lista

S-ar putea să vă placă și