Documente Academic
Documente Profesional
Documente Cultură
Algoritmi
Ce este un algoritm?
In general, rezolvarea unei probleme presupune:
-formulare corecta a problemei, incadrarea ei intr-o clasa de probleme
-reprezentarea ei in vederea rezolvarii cu ajutorul calculatorului
Asadar, Algoritmul este o metoda de rezolvare a mai multor probleme de acelasi tip,
caracterizata prin generalitate (nu exista problema din clasa respectiva
nerezolvabila), corectitudine(solutia furnizata este corecta) si finitudinea(solutia se
furnizeaza dupa un numar finit de operatii).
O descriere mult mai simpla este aceea ca: Algoritmul reprezinta procesul prin
care obtinem anumite date de iesire in functie de anumite date de intrare( date
ce pot fi introduse de la tastatura, citite dintr-un fisier, etc.)
Start >> citeste date intrare >> calcul >> afisare >> Stop
Assigment
Realizati un alt algoritm pentru interschimbarea celor doua
variabile fara a folosi a treia variabila.
Structura alternativa
Auzim in viata de zi cu zi afirmatii de genul: DACA am promovat
examenul, ATUNCI ma voi imbata, ALTFEL stau sa invat pentru
toamna.
Se remarca trei cuvinte ce au un rol deosebit:
DACA, ATUNCI, ALTFEL.
Propozitia are trei
componente si anume:
1.o conditie, transcrisa prin “am promovat la toate materiile”,
conditie pe care o notam cu c;
2.o actiune transcrisa prin “ma voi duce in tabara”, notata cu p,
actiune asociata cu ATUNCI, adica se executa doar daca “am
promovat la toate materiile”;
3.o actiune transcrisa prin “stau sa invat”, notata cu q, actiune
asociata cu ALTFEL, adica se executa daca NU
“am promovat la toate materiile”;
Folosind notatiile facute, afirmatia se poate scrie astfel:
DACA c, ATUNCI p, ALTFEL q.
Pentru a fi foarte clar, afirmatia se poate scrie sub forma:
DACA c,
ATUNCI p,
ALTFEL q,
SFARSIT
S=1 + 2 + 3 + ... + n
Exemplu
EXERCITII
Ob. Exercitiile se vor rezolva prin scrierea algoritmului dar si
prin realizarea schemei logice specifice acestuia!!!
System.out.println(“Hello, world!”);
Assignment
Hello World!
Hello Again
This is fun.
Yay! Printing.
3. Cod. Comentarii
Indentarea codului
Instrucţiuni vide
Linii goale
Folosirea ctrl+shift+F în Eclipe pentru aşezarea codului
Comentarii
Pe un singur rând - / /
Pe mai multe rânduri - /*…*/
Pentru documentaţie (javadoc) - /** … */
Exemplu
public class CommentsAndSlashes {
/**
*/
/**
*/
Assingment
*****
*****
*****
*****
*****
3.
Printaţi iniţialele voastre după exemplul dat. Folosiţi tabelul de mai jos ca şi sugestie.
4. Aritmetică şi Comparaţii
Operatori aritmetici şi de comparaţie:
+ plus
- minus
* înmulţit
/ împărţit
% modulo (restul împărţirii)
== egal cu
!= diferit de
< mai mic ca
> mai mare ca
⇐ mai mic ca sau egal cu
>= mai mare ca sau egal cu
Exemplu
System.out.println( 3 + 2 + 1 - 5 + 4 % 2 - 1 / 4 + 6 );
System.out.println( 3 + 2 < 5 - 7 );
Assignment
În Java există mai multe tipuri de date, dar pentru moment vom folosi doar int,
double, boolean şi String.
int
declarare: int x;
iniţializare: x = 20;
atribuire cu operatorul de atribuire: x = 145;
afişare (sau alte operaţii): System.out.println(x);
Operatorul de atribuire "="
int i = 45;
int j = 6 + 5;
int k = i + j;
int m = 056; (baza 8)
int n = 0x5f; (baza 16)
Observaţie A nu se confunda operatorul de atribuire "=" care schimbă valoarea unei
variabile cu operatorul de comparaţie "==" care ne arată dacă 2 variabile sunt egale
sau nu.
Exemplu
cars = 100;
space_in_a_car = 4.0;
drivers = 30;
passengers = 90;
cars_driven = drivers;
}
}
Assignment
myTeeth = "White";
myHair = "Brown";
Assignment
int num = 4;
System.out.println(num);
System.out.println(“num”);
System.out.println(4);
2. Identificatori. Literali
Identificatori
Toate componentele Java necesită nume. Numele folosite pentru clase, variabile şi
metode sunt identificatori. În Java, există câteva noţiuni care trebuiesc reţinute
pentru identificatori:
Un literal este o reprezentare în codul sursă a unei valori fixe. Aceştia sunt
reprezentaţi direct în cod şi pot fi atribuiţi oricărui tip de date primitive. De exemplu:
byte, int, long, şi short pot fi exprimaţi în baza 10 (zecimal), baza 16 (hexazecimal)
sau baza 8 (octal). Prefixul 0 este folosit pentru a indica un prefix pentru numerele în
octal, iar 0x este prefixul ce indică literalii în hexazecimal. De exemplu:
Literalii de tip String sunt specificaţi ca şi în alte limbaje de programare prin scrierea
unor secvenţe de caractere între perechi de ghilimele. Exemple de literali String:
"Hello World"
"two\nlines"
"\"This is in quotes\""
Literalii de tip String sau char pot conţine orice caractere în Unicode. De exemplu:
Assignment
1. Folosind 3 variabile, afişaţi următorul text. Variabilele sunt subliniate. Alegeţi tipul
corespunzător.
This is room #113
e is close to 2.71828
I am learning a bit about Computer Science
2. Folosind 2 variabile, una pentru nume şi una pentru anul naşterii, să se printeze un
mesaj. Să se aleagă tipuri de date corespunzătoare şi nume potrivite pentru
variabile. Mesajul va arăta ca în exemplul de mai jos:
În Java există mai multe tipuri de date, dar pentru moment vom folosi doar int,
double, boolean şi String.
int
declarare: int x;
iniţializare: x = 20;
atribuire cu operatorul de atribuire: x = 145;
afişare (sau alte operaţii): System.out.println(x);
Operatorul de atribuire "="
int i = 45;
int j = 6 + 5;
int k = i + j;
int m = 056; (baza 8)
int n = 0x5f; (baza 16)
Observaţie A nu se confunda operatorul de atribuire "=" care schimbă valoarea unei
variabile cu operatorul de comparaţie "==" care ne arată dacă 2 variabile sunt egale
sau nu.
Exemplu
cars = 100;
space_in_a_car = 4.0;
drivers = 30;
passengers = 90;
cars_driven = drivers;
}
}
Assignment
myTeeth = "White";
myHair = "Brown";
Assignment
int num = 4;
System.out.println(num);
System.out.println(“num”);
System.out.println(4);
2. Identificatori. Literali
Identificatori
Toate componentele Java necesită nume. Numele folosite pentru clase, variabile şi
metode sunt identificatori. În Java, există câteva noţiuni care trebuiesc reţinute
pentru identificatori:
Un literal este o reprezentare în codul sursă a unei valori fixe. Aceştia sunt
reprezentaţi direct în cod şi pot fi atribuiţi oricărui tip de date primitive. De exemplu:
byte, int, long, şi short pot fi exprimaţi în baza 10 (zecimal), baza 16 (hexazecimal)
sau baza 8 (octal). Prefixul 0 este folosit pentru a indica un prefix pentru numerele în
octal, iar 0x este prefixul ce indică literalii în hexazecimal. De exemplu:
Literalii de tip String sunt specificaţi ca şi în alte limbaje de programare prin scrierea
unor secvenţe de caractere între perechi de ghilimele. Exemple de literali String:
"Hello World"
"two\nlines"
"\"This is in quotes\""
Literalii de tip String sau char pot conţine orice caractere în Unicode. De exemplu:
Assignment
1. Folosind 3 variabile, afişaţi următorul text. Variabilele sunt subliniate. Alegeţi tipul
corespunzător.
This is room #113
e is close to 2.71828
I am learning a bit about Computer Science
2. Folosind 2 variabile, una pentru nume şi una pentru anul naşterii, să se printeze un
mesaj. Să se aleagă tipuri de date corespunzătoare şi nume potrivite pentru
variabile. Mesajul va arăta ca în exemplul de mai jos:
I/O:
Input = datele introduse în program
Output = datele afişate / rezultate din program
import java.util.Scanner;
Exemplu
import java.util.Scanner;
int age;
String height;
double weight;
age = keyboard.nextInt();
height = keyboard.next();
weight = keyboard.nextDouble();
}
}
Clasa Scanner dispune de o serie de metode care permit introducerea datelor. Puteţi
consulta API-ul pentru detalii, cele mai uzuale fiind cele care încep cu “next”. Acestea
aşteaptă ca utilizatorii să introducă un anumit tip de dată de la tastatură.
Assignment
Schimbaţi programul anterior pentru a schimba citirea înălţimii cu două variabile: feet
şi inches. Acestea sunt reprezentate prin numere întregi.
Assignment
2. Întrebaţi utilizatorul cum îl cheamă. Afişaţi numele şi întrebaţi câţi ani are. Afişaţi
vârsta şi întrebaţi cât câştigă. Afişaţi salariul. Folosiţi variabile corespunzătoare
pentru valorile introduse.
Login: bonham_453916
Your information:
Login: bonham_453916
ID: 453916
GPA: 3.73
Grade: 12
Did you know that in five years you will be 39 years old?
And five years ago you were 29! Imagine that!
BMI Calculator
Sample Output
Exemplu
R = P (l / A)
Unde:
Iar
A = pi*r*r
D = 2*r
Unde:
Initial americanii au inventat sistemul ASCII care inseamna American Standard Code
127. Erau principalele litere mari, mici, cifre si alte cateva semne.
Ulterior ASCII a fost extins la 256 de caractere, adica de la 0 la 255.. (=2 8 , adica
Cu timpul, insa s-a dovedit a fi prea mic, si a aparut sistemul unicode pe 2 bytes (2
octeti) de la 0 la 65535. adica 216 caractere. Java foloseste exact acest sistem.
primitiva char ocupa exact 2 octeti si are exact 65536 caractere, adica de la 0 la
65535.
Dar cele trei inseamna exact acelasi lucru, si anume litera J mare.
Merge si direct:
reprezentare in baza 16, fie folosim o metoda a clasei String, pe care nu am invatat-
Ideea e ca ambele inseamna reprezentari diferite ale aceleasi valori. Aveti mai jos un
link cu tabelul caracterelor. Ascii Table - ASCII character codes and html, octal, hex
Eclipse în Windows nu afiseaza caracterele a căror valoare numerică depă șe ște 127.
Dar nu este eroare. Pur si simplu, Eclipse nu poate afisa alte caractere.
Exemplu:
Daca vrem sa obtinem scris "Ion" trebuie sa fortam operatorul "+" sa facă
+ ch3 ); ⇒ Ion
bytes (octeți), adică pe 24 biți, căci se pare că nici 65536 caractere nu au fost
suficiente.
Assignment
Sa se definească două caractere. Sa se afiseze valorile lor in Unicode si in ASCII,
Integer.valueOf(string, 16)
Operatori in Java
Operatorul de atribuire
int i = 45;
int j = 6 + 5;
int k = i + j;
Operatori aritmetici
1. binari (adică necesită 2 operanzi):
+, -, *, /, %
Exemplu:
int c = a+b;
int d = a-b;
int d = a*b;
a+=5; e totuna cu a = a + 5; \\
La fel si
a-=4 (scadem 4)
a*=6 (inmultim cu 6)
a/=3 (impartim la 3)
i *= 2; e totuna cu i = i * 2;
</note>
3. ternari
boolean bool;
Se verifică dacă a este mai mare decât 5. Dacă da, se efectuează prima operație după semnul
întrebării. Dacă nu, se efectuează cea de a doua.
int a = 5;
int b = 4;
E echivalent cu:
if (a > b) {
} else {
E echivalent cu :
boolean bool;
if (a > b) {
bool = true;
} else {
bool = false;
Operatori de comparație
>, >=, <, ⇐, ==, !=
if (a> 5) {...}
>= < ⇐ == != Ei returnează totdeauna doar true sau false. (adică un boolean)
!= înseamnă diferit de, Not Equal
if (a != b) {...}
if ( ch != 'e' ) {...}
if și while evaluează condiții. De aceea, putem spune if (true) sau if (false). if(false) nu are
sens. while (false) dă eroare de compilare.
Dacă folosim == la obiecte, se compară adresa din memorie. Din întâmplare merge la String,
pentru a compara șirurile, dar doar în anumite cazuri.
Egalitatea dintre 2 obiecte se face cu metoda equals() Exemple de obiecte: String, array, racul
din Greenfoot. Pentru a verifica egalitatea dintre 2 obiecte, metoda equals trebuie redefinită
pentru obiectul respectiv (o să vedem asta săptămâna asta), pentru ca calculatorul să știe cum
să verifice egalitatea. Cum verifici egalitatea între 2 raci? Sau 2 ursuleți? Depinde ce vrei să
compari.
Dacă nu o redefinim, equals() testează egalitatea adreselor acestor obiecte în memorie, ca și
==. La Array nu are sens să verificăm egalitatea. equals() testează egalitatea adreselor acestor
obiecte în memorie, nu dacă au elemente identice. Dacă vrem să testăm dacă au elemente
identice, trebuie să verificăm noi manual element cu element.
String a redefinit metoda equals(). De accea o putem folosi pentru a verifica egalitatea dintre
2 șiruri de caractere. (Mai multe despre equals() săptpmâna asta.) În cazui clasei String putem
compara două șiruri din punct de vedere alfabetic (asemenea unui dicționar, care cuvânt se
situează în fața altuia din punct de vedere alfabetic) cu metoda .compareTo(alt șir);
Operatori logici
Când vrem să verificăm mai multe condiții odată.
&- ȘI ,
|- ORI,
^- XOR (unul sau celălalt, dar nu ambele),
!- NOT
........
if ( ! str1.equals("catel") ) {...}
if ( ! (a>5) ) {...}
// Dacă bool
if ( ! bool ) {...}
Operatorii de scurtcircuitare se folosesc cel mai adesea din obișnuință, dar, totuși, uneori ei
sunt imperativ necesari pentru a sări, în anumite condiții, evaluarea celei de a doua condiții,
în sensul de a nu genera o eroare:
Eroarea apare pentru că str nu are nici o referință către nici un obiect (Mai mult depre
obiecte în zilele următoare Atenție: String este o CLASĂ, nu o PRIMITVĂ. Cu ajutorul
clasei String creăm obiecte de tip string, așa cum ați creat în Greenfoot). Nu putem apela
metoda length() la un obiect care nu există.
Dac ă str e null, cea de a doua condiție nici nu mai este evaluată și nu se mai generează
eroarea!
Assignment
Aflarea dimensiunii unui șir de caractere.
if ( string3.length() == 8 ) {….}
Verificăm:
if ( string3 != null ) {
if (string3.length() == 8) {
System.out.println (“Great”);
rulare.
Sau, prescurtat:
{..........}
Dacă prima condiție e false, nu se mai verifică cea de a doua condi ție, ca nu are
sens. false & true tot false dă. Cea de a doua condi ție se evaluează numai dacă
prima e true.
Cast (transformare) dintr-o primitivă în
alta
Putem atribui unui int valoarea unui short sau byte, pentru că 2, respectiv 1 byte
(octet) încap în 4:
short sh = 45;
int i = sh;
pentru că pur și simplu spațiul cu mai mulți octeți nu încape într-un spațiu cu mai
puțini octeți.
int i = 32;
din String îi este asociată o poziţie (sau index). Numărătoarea poziţiilor începe de la
J=0
A=1
V=2
A=3
generalizare:
lungime = n
poziţie minimă = 0
Assignment
Consultaţi API-ul pentru String pentru a rezolva următoarele probleme:
caracter.
să se afişeze.
termină cu “ala”.
facă ţinând cont de caracterele majuscule (MARE este egal cu MARE, dar nu
este egal cu Mare), apoi ignorând-ule (Mare este egal şi cu MARE şi cu mArE).
cele 2 caractere.
10. Să se verifice dacă un şir de caractere începe cu un alt şir de caractere (Ex:
exclus.
“miercuri”).
string2
boolean bool2 = string1.endsWith("ooee."); //daca se termina cu...
ignorand Case-ul
Dati click pe Frame pentru a vedea toate clasele. Nu va speriati. Nu trebuie sa stim
decat cateva.
Clasa String
De exemplu:
stringuri
fost scris ca char ci ca int, pentru că așa cum am văzut, char poate fi asociat cu
Assignment
Folosind bucla while, să se implementeze metoda (funcția) indexOf(char) din
clasa String:
Varianta 1
Condiția din if verifică dacă am ajuns la capătul șirului. Dacă nu ieștim din buclă,
int index = 0;
index++;
if (index == sir.length()){
break;
}
//acum verificam care a fost conditia care ne-a scos din bucla.
if (index != sir.length()){
} else {
Varianta 2
Verificăm totodată atât dacă am gasit caracterul, cât și dacă am depașit capătul
șirului.
int index = 0;
index++;
//acum verificam care a fost conditia care ne-a scos din bucla.
if (index != sir.length()){
} else {
}
Structura Condiţională. If
Este folosită pentru a verifica dacă o condiţie este adevarată. Sintaxa de bază este următoarea:
if (conditie) {
instructiuni;
Unde:
Exemplu
public class WhatIf {
if (people <cats) {
if (people> cats) {
}
if (people <dogs) {
if (people> dogs) {
dogs += 5;
if (people>= dogs) {
if (people == dogs) {
} } }
Assignment
Assignment
Schimbaţi valorile iniţiale ale variabilelor astfel încât să nu fie afişat doar un singur
mesaj. Adăugaţi if-uri astfel încât programul să afişeze minim 3 mesaje. Adăugaţi
Assignment
1. Creaţi un program care să afişeze unul din următoarele mesaje pentru o vârstă
vârsta e 25 sau mai mare, scrie "Poţi să faci orice este legal."
Pentru o vârstă între 18 şi 24 de ani: “Poţi vota, dar nu poţi închiria maşini.”
Pentru o vârstă de 25 de ani sau mai mare: “Poţi să faci cam orice.”
că:
1 Venus – 0.78
2 Marte – 0.39
3 Jupiter – 2.65
4 Saturn – 1.17
5 Uranus – 1.05
6 Neptun – 1.23
Exemplu consolă:
Exemplu consolă:
Are you ready for a quiz? Y
1) Melbourne
2) Anchorage
3) Juneau
That's right!
Q2) Can you store the value "cat" in a variable of type int?
1) yes
2) no
1) 5
2) 11
3) 15/3
That's correct!
6. Două întrebări
Creaţi un program care să pună 2 întrebări. Prima întrebare ar trebui să fie "animal,
vegetal sau mineral?" şi a doua întrebare "este mai mare decât o pâine?". Apoi
afişaţi una din cele şase combinaţii posibile, în funcţie de răspunsurile primite. Puteţi
Sugestie:
Creaţi un program cu if-uri imbricate şi încă unul cu condiţii compuse (care folosesc
&&).
Exemplu consolă:
TWO QUESTIONS!
animal
no
7. Scrieţi un program prin care să ghiciţi un număr. Reţineţi un număr într-o variabilă,
apoi introduceţi un număr de la tastatură. Dacă numărul introdus este egal cu cel
reţinut, afişaţi un mesaj de genul “Ai ghicit numărul!”. Dacă este diferit, afişaţi mesajul
If Else
Atunci când condiţia de la if este falsă, putem avea alt set de instrucţiuni pe care îl
vom executa puse în clauza else. Mai mult, se pot face verificări succesive, astfel
if (condiție) {
//bloc de instrucțiuni
} else if {
//bloc de instrucțiuni
} else {
//bloc de instrucțiuni
Exemplu
int weekday = 2;
if ( weekday == 1 ) {
result = "Luni";
} else if ( weekday == 2 ) {
result = "Marti";
} else if (weekday == 3) {
result = “Miercuri”;
} else {
Assignment
Assignment
1. Calculator IMC
Creaţi un calculator BMI (body mass index) (IMC – indice de masă corporală). Acesta
Ex: kg / (m * m).
Categorii:
2. Două întrebări
Cu următoarele variante:
Exemplu consolă
ambele? exterior
int i = "axe".compareTo("dog");
System.out.println(i);
");
System.out.println( "applebee's".compareTo("apple") );
Această metodă va produce un rezultat negativ dacă folosim un cuvânt care este
Creaţi un program prin care să introduceţi cuvinte. După primul cuvânt introdus, se
mai cere un cuvânt şi se va afişa dacă acesta este din punct de vedere alfabetic
înainte sau după cuvântul anterior. Apoi se va mai introduce un cuvânt şi se va afişa
dacă este înainte sau după al doilea cuvânt. Pentru al 4-lea cuvânt introdus se va
Atenţie Limbajul Java face distincţie între literele mari şi literele mici. Creaţi
o valoare egală, va executa toate instrucţiunile până la întâlnirea unui break. În cazul
în care nicio valoare nu este egală, va executa instrucţiunile din clauza default.
Exemplu 1
int weekday = 5;
switch (weekday) {
case 1:
result = "Sunday";
break;
case 2:
result = "Monday";
break;
case 3:
result = "Tuesday";
break;
default:
Exemplu 2
int month = 5;
int daysInMonth = 0;
switch (month) {
case 1: // Ianuarie
case 3: // Martie
case 5: // Mai
case 7: // Iulie
case 8: // August
daysInMonth = 31;
break;
case 4: // Aprilie
case 6: // Iunie
case 9: // Septembrie
daysInMonth = 30;
break;
case 2: // Februarie
daysInMonth = 28;
break;
Exemplu 3
case 0:
case 2:
break;
case 13:
System.out.println("4444444444444444");
case 4:
break;
case 3:
case 8:
default:
break;
}
Assignment
Assignment 1
Observaţie
Varabila folosită la switch poate fi doar byte, short, char, int sau String. Poate
funcţiona şi cu enumeraţii (Enum) sau clase analoage pentru tipurile de date primitive
pot repeta.
Assignment 2
Assignment 3 <
1. Calculator IMC
Creati un calculator BMI (body mass index) (IMC – indice de masa corporala). Acesta
Ex: kg / (m * m). Se cere sa se afiseze indicele BMI si categoria din care face parte.
Categorii:
Cu urmatoarele variante:
int i = "axe".compareTo("dog");
System.out.println(i);
");
System.out.println( "applebee's".compareTo("apple") );
Aceasta metoda va produce un rezultat negativ daca folosim un cuvant care este
mai cere un cuvant si se va afisa daca acesta este din punct de vedere alfabetic
inainte sau dupa cuvantul anterior. Apoi se va mai introduce un cuvant si se va afisa
daca este inainte sau dupa al doilea cuvant. Pentru al 4-lea cuvant introdus se va
Limbajul Java face distinctie intre literele mari si literele mici. Creati programul astfel
Exemplu toString()
Maria a obținut nota 10, Anca 9, iar restul 7. Dar îl avem și pe domnul profesor. Ce
if ( nume.equals(”Maria”) ) {
} else if ( nume.equals(”Anca”) ) {
} else if ( nume.equals(”profesor”) ) {
} else {
switch (nume) {
break;
break;
break;
Sau:
!nume.equals(“profesor”) ) {
syso(“Nota 7”);
}
//adică dacă numele nu e nici Maria, nici Anca și nici profesor
(!nume.equls(“profesor”)) ) ....
Structura repetitivă while este folosită pentru a executa o secvenţă de instrucţiuni cât
while (conditie) {
instructiuni;
La fel ca la structura if, condiţia trebuie să fie o valoare booleană (true sau false), iar
NU uitați să introduceți o linie de cod care să poată facă condiția false, pentru a
nu intra într-o buclă infinită fără scăpare. Sau folosiți break (detalii mai încolo).
Exemplu
import java.util.Scanner;
while (!entry.equals(pin)) {
entry = keyboard.next();
YOUR ACCOUNT.");
}
Variante de folosire a buclei while cu 1 condiție
1. Afișarea primelor 10 numere.
int i = 1;
while (true){
System.out.println(i);
if (i == 10) {
break;
i++;
int i = 1;
while (flag){
System.out.println(i);
if (i == 10) {
flag = false;
i++;
2. Ghicește numărul
nt numar = 6;
int ghici;
while (flag){
System.out.println(
”Ghiceste numarul de la 1
a 10”);
ghici = keyboard.nextInt();
if (ghici == numar) {
flag = false;
System.out.println(”Felicitari”);
int numar = 6;
int ghici;
while (true){
System.out.println(
”Ghiceste numarul de la 1
a 10”);
ghici = keyboard.nextInt();
if (ghici == numar) {
break;
System.out.println(”Felicitari”);
int numar = 6;
ghici = keyboard.nextInt();
System.out.println("Felicitari");
Nu e bine.
int numar = 6;
int ghici;
do {
System.out.println( "Ghiceste
numarul de la 1 a 10");
ghici = keyboard.nextInt();
System.out.println("Felicitari");
Bucla do…while o folosim atunci când trebuie să executăm iterația cel puțin o dată.
Assignment
Assignment 1
avem cuvântul String în faţa lui entry? Ce se întamplă dacă ştergeţi linia entry =
Assignment 2
aceasta?
while (true)
System.out.println(“printing”);
introducerea unei valori de la tastatură. Afişaţi mesaje diferite dacă numărul este mai
Exemplu consolă
Introduceti numarul: 3
Introduceti numarul: 8
int n = 0;
while (n <5) {
n++;
Pentru a putea finaliza problema avem nevoie de un counter care să numere de câte
ori am afişat mesajul. În acest caz, n ţine locul acestui counter. De obicei, folosim un
while pentru a repeta o serie de instrucţiuni cât timp o condiţie este adevărată.
Această problemă este indicată pentru un alt tip de structură repetitivă, dar se poate
folosi şi un while.
Afişaţi în faţa mesajului numerele 10, 20, 30, 40, etc… Rezolvaţi în 2 moduri.
5. Modificaţi programul dat ca exemplu, astfel încat dacă introduceţi un pin greşit de
introduce valoarea 0.
Reguli:
Examplu
Starting number: 6
6 3 10 5 16 8 4 2 1
Mai mult:
11. Scrieți un protgram în care voi vă gândiți la un număr între 1 și 100, iar
Assignment 3
While cu o condiție
care v-ati gandit voi (intre 1 si 100). Hint: el propune un numar aleator. Intreaba
daca numarul la care s-a gandit userul este mai mare sau mai mic decat numarul
propus de el. Daca este mai mare, va cauta un numar aleator intre numarul
propus anterior si 100. Daca este mai mic, va cauta un numar aleator intre
6.
While cu două condiții
2. Realizati o metodă care face ce face metoda indexOf('char') din clasa String.
String. Programul va inlocui prima aparitie a subsirului “dra” cu “dru” din cuvantul
“Alexandra”. Vom presupune că șirul nostru are un singur “d”. Indiciu: Vom afla
înlocuiească a cincia apariție a literei “a”, dacă există, cu litera “i”. Exemplu: Rareș
a incercat sa prinda pasica, dar aceasta a fost mult mai rapida decat el.
“a” cu “i”. Practic implementăm noi metoda replaceAll(sir, sir) din clasa String.
7. Bonus 2 - Spânzuratoarea
maxim de pași. Indiciu: Noi propunem o litera. Calculatorul spune daca exista sau
Exemplu:
Zii o litera
Zii o litera.
Zii o litera.
f nu este.
…
Zii o litera.
Bravo! Ai ghicit!
condiţiei care este făcută la final pentru structura do-while. Din acest motiv,
Sintaxa
do {
instructiuni;
} while (conditie);
Unde
do – cuvânt cheie
condiţie – o condiţie oricât de complexă din care rezultă ceva adevărat sau
fals; atât timp cât condiţia este adevărată, se vor executa instrucţiunile din
Exemplu
Scanner sc = new Scanner(System.in);
int sum = 0;
do {
sum += num;
System.out.println(sum);
Assignment
Assignment 1
import java.util.Scanner;
double currentTemperature;
double savedTemperature;
int swimTime;
currentTemperature = keyboard.nextDouble();
);
swimTime++;
);
water temperature
System.out.println( "\nOkay, so the current water
swimTime = 0;
do {
);
swimTime++;
);
currentTemperature -= 0.5;
Rulaţi programul pentru o valoare de 80.5 pentru temperatura curentă a apei. Înoată
cei doi sportivi pentru aceeaşi perioada de timp? Rulaţi programul pentru 78 de
grade. Ce diferenţe sunt? Se aruncă cei doi sportivi în apă fără să verifice
temperatura acesteia?
Assignment 2
1. Se da următorul cod.
String again;
while ( again.equals("y") ) {
String coin;
if ( flip == 1 )
coin = "HEADS";
else
coin = "TAILS";
again = keyboard.next();
folosind do-while. Stergeţi modificarea care aţi făcut-o la început. Se mai compilează
codul? De ce?
Folosiţi do-while.
numărul respectiv din mai multe încercări. După fiecare încercare să se afişeze dacă
numărul introdus este mai mare sau mai mic decât numărul care trebuie ghicit. Să se
folosească do-while.
4. Să se creeze un calculator care face operaţii simple de adunare şi înmulţire cu o
while şi do-while.
Ex:
Greșeli în programare
Fie următorul program ce conține 2 bucle:
int i=0;
while (i<100) {
i++;
while (i<15) {
i++;
Exemple de utilizare
Exemplu:
Folosind bucla while, să se realizeze un bancomat care cere codul pin de un inifinit
package automat;
import java.util.Scanner;
String parola;
while (true){
// E suficient să scriem doar while (bool)
parola = scanner.nextLine();
if (parola.equals("9759")){
System.out.println("Bravo");
break;
package automat;
import java.util.Scanner;
String parola;
while (bool){
parola = scanner.nextLine();
if (parola.equals("9759")){
System.out.println("Bravo");
bool = false;;
Varianta 3: clasică
package automat;
import java.util.Scanner;
//altfel ne va da eroare la
executare
parola = scanner.nextLine();
}
System.out.println("Daca ati ajuns aici inseamna ca
linia cu while. E cam forțat. Ce făceam dacă parola era chiar “0000” ? Există pentru
do {
// bloc de instructiuni
package automat;
import java.util.Scanner;
String parola;
do {
parola = scanner.nextLine();
Sintaxa
instructiuni;
Unde
condiţie – orice condiţie cât de complicată care rezultă în adevărat sau fals;
Exemplu 1
System.out.println(“mesaj ” + i);
Exemplu 2
Să se afişeze un mesaj introdus de 5 ori.
import java.util.Scanner;
five times." );
}
}
Variante de for
ori); while este folosit atunci când ştim până când vrem să repetăm ceva (cât timp nu
// …
}
Un while care îndeplineşte aceeaşi funcţionalitate arată în felul următor:
int i = 0;
while (i <6) {
// …
i++;
Assignment
Assignment 1
Assignment 2
3…)
3. Scrieţi un program care citeşte 3 numere: un număr de la care pornim
numărătoarea, un număr până la care numărăm şi din cât în cât numărăm. Afişaţi
numărătoarea. (0 2 4…)
variabilă y.
6. Scrieţi un program care citeşte un număr şi afişează toate numele până la acesta.
numerelor impare.
3 afişaţi mesajul “Tres”, pentru multiplii de 5 afişaţi mesajul “Cinco”, iar pentru
lui. Puteţi folosi funcţia charAt(int) a clasei String. Număraţi de câte ori apare litera „a‟
9. Scrieţi un program care face suma primelor n numere, unde n este citit de la
10. Scrieţi un program care adună n numere citite de la tastatură (n este şi el citit de
la tastatură). De exemplu: a + b + c + d + …. + k.
11. Scrieţi un program care citeşte un cuvânt de la tastatură şi îl afişează de 10 ori. În
cazul în care cuvântul începe cu o vocală, acesta trebuie afişat doar de 5 ori. Folosiţi
2 1 2
3 2 1 2 3
4 3 2 1 2 3 4
5 4 3 2 1 2 3 4 5
Programul se poate modifica apoi să primească orice număr, iar afişarea să se facă
cu metoda printf.
For Each
O altă variantă pentru structura for învaţată este for each sau “enhanced for loop”
exemplu, pentru a afişa elementele unui tablou din exemplul anterior, putem scrie:
System.out.println(x);
În acest caz, nu mai avem acces la index-ul pe care se află elementul pe care vrem
să îl afişăm. Este mai util să folosim un for-each, ba chiar indicat acolo unde putem.
Assignments
de pe poziţiile 1, 2 şi 4.
lungime n, puneţi valori aleatoare pe fiecare poziţie (între 1 şi 100) şi afişaţi vectorul.
4. Creaţi un vector care reţine 1000 de valori. Puneţi în el valori aleatoare între 10 şi
99. Afişaţi vectorul, apoi afişaţi de câte ori apar numere cu 0 în coadă (ex: 10, 20, 30,
etc…).
apoi conţinutul în alt vector. Schimbaţi ultimul element cu valoarea -5. Afişaţi vectorii.
6. Creaţi un vector de 10 elemente cu numere aleatoare între 0 şi 99. Creaţi un alt
10 11 12 13 14 15 16 17 18 19 – vector initial
19 18 17 16 15 14 13 12 11 10 – vector final
tastatură şi afişaţi de câte ori găsiţi numărul respectiv în vector. Afişaţi şi un mesaj
când aţi găsit numărul. Schimbaţi programul astfel încât să afişaţi şi indexul pe care
numărul a fost găsit. Schimbaţi programul astfel încât să reţineţi toţi indecşii pentru
atunci când acesta a fost găsit. Utilizaţi break sau o variabilă booleană.
Afişaţi vectorul.
persoanei.
12. Creaţi apoi un nou program prin care să alegeţi dacă faceţi căutarea după nume,
Exemplu
Values:
Found in slot 3
Name: Zimmerman
Average: 96.8
ID: 307760
Bucle Imbricate
Buclele imbricate apar atunci când o buclă conţine ca şi instrucţiune o altă buclă.
Exemplu
System.out.println();
Assignment
Rulaţi exemplul anterior. Ce afişează acesta? De câte ori se execută fiecare buclă?
Exemplu
System.out.println("\n");
System.out.println("\n");
Assignment
Ce afişează exemplul anterior? La setul #1, care variabilă creşte mai repede?
Schimbaţi pentru setul #1 ordinea buclelor – puneţi bucla din interior în exterior şi
invers. Cum se modifică programul? Pentru setul #2 schimbaţi instrucţiunea print în
Assignment
“System.out.print(“*”);” şi 2 for-uri.
*****
*****
*****
*****
*****
*****
“System.out.print(“*”);” şi 2 for-uri.
**
***
****
*****
* 0 1 2 3 …
0 0 0 0 0
1 0 1 2 3
2 0 2 4 6
3 0 3 6 9
153 = 13 + 53 + 33
if ( condiție ) {
break BuclaMare;
Labeled loops:
outer:
if (conditie1){
if (conditie2){
break outer; //iese din bucla mare
președinție are 6 secțiuni. Prima secțiune are o întrebare. Cea de a doua: două
întrebări. Cea de a treia: trei întrebări, ș.a.m.d. Intervievatul poate răspunde cu: „DA”,
“NU”, “Nu stiu” sau “Nu raspund”. Programul va genera aleator răspunsul
răspundă cu “NU” este tot de 30%, șansa să răspundă cu “Nu stiu” este de 20%, iar
50% - 50%.
Sfaturi:
intrați între paranteze / acolade și tastați Enter și scrieți acolo codul. - pentru a nu
4. Puteți face tab la mai multe linii de cod odată, selectându-le și apăsând TAB
import java.util.Random;
int x = r.nextInt(10);
Assignment 1
astfel încât limita superioară să fie introdusă de la tastatură (vom avea numere de la
1 la n). Modificaţi din nou programul astfel încat şi limita inferioară să fie introdusă de
Assignment 2
1. Scrieţi un program care generează 2 numere între 1 şi 10. Verificaţi dacă numerele
2. Modificaţi programul de mai sus astfel încât să genereze numere până când găsiţi
5. Scrieţi un program în care să reţineţi 10 mesaje. La rulare, veţi afişa aleator unul
din mesaje.
6. Scrieţi un program pentru a ghici un număr generat aleator. Veţi afişa la început
intervalul între care numărul este ghicit, apoi veţi lăsa utilizatorul să aleagă un număr
până ghiceşte numărul iniţial. De fiecare dată când este introdus un număr,
utilizatorul va trebui să afişeze dacă acesta este mai mic, mai mare sau egal cu
numerele şi suma acestora. În cazul în care numerele sunt egale, afişaţi mesajul
“dublu 6”, unde în loc de 6 veţi pune numărul care se află pe ambele zaruri.
8. Modificaţi programul anterior, astfel încât să fie aruncate zarurile de mai multe ori,
9. Se dă următorul scenariu: Avem 3 cărţi cu faţa în jos, una dintre ele este As.
Celelalte 2 cărţi sunt Dama şi Popa. Fiecare carte va fi stabilită aleator. Utilizatorul
trebuie să ghicească care din cărţi este Asul dintr-o singură încercare. Simulaţi
You slide up to Fast Eddie's card table and plop down your cash.
He glances at you out of the corner of his eye and starts shuffling.
He lays down three cards.
# # #
1 2 3> 2
Ha! Fast Eddie wins again! The ace was card number 3.
K Q A
1 2 3
10. Recreaţi scenariul anterior în felul următor: Jocul începe cu o sumă de bani (de
ex.: 1000 dolari). Utilizatorul poate juca de mai multe ori, şi va fi întrebat înainte de
fiecare joc dacă vrea să joace. La fiecare joc acesta va paria o suma de bani. În
cazul în care pierde, nu va primi nimic înapoi. În cazul în care câştigă, acesta va
11. Modificaţi programul anterior, astfel încât să reţineţi impozite pe câştig de 16%
Break şi Continue
Instrucţiunile break şi continue sunt folosite pentru a modifica flow-ul normal al
programului. Acestea sunt folosite în special la bucle. Spre exemplu break întrerupe
o buclă (cea mai interioară pentru care este aplicat), iar continue sare la iteraţia
următoare din bucla respectivă (cea mai interioară buclă care o găseşte). De exmplu,
int suma = 0;
int produs = 1;
int num;
// 1.
while (true) {
num = sc.nextInt();
if (num == 0) {
}
suma += num;
// 2.
while (true) {
num = sc.nextInt();
if (num == 0) {
} else if (num == 1) {
produs *= num;
}
System.out.println("produs final: " + produs);
Assignment
Assignment 1
Ce diferenţe apar?
Assignment 2
negativ.
3. Se citesc numere. Să se facă produsul numerelor citite, doar dacă sunt pozitive.
dat.
Varianta 1:
Pe care poate unii dintre voi o preferați. Bucla While care conține un if.
Condiția din while verifică dacă am gasit 'e'-ul. Condiția din if verifică dacă am ajuns
la capătul șirului. Dacă nu ieștim din buclă, index va depăși capătul șirului și vom
sir.charAt(index).
int index = 0;
index++;
if (index == sir.length()){
break;
bucla.
if (index != sir.length()){
} else {
exista.");
șirului.
int index = 0;
){
index++;
bucla.
if (index != sir.length()){
} else {
System.out.println("Returnam -1 pentru ca 'e' nu
exista.");
StringIndexOutOfBoundsException.
Exerciții
Keywords: Switch, For, While, Do…While, Math.random()
Switch
1. Să se realizeze un program în care utilizatorul introduce de la tastatură un număr
Math.random()
For
2. Să se arunce cu zarul de 5 ori. Să se afișeze suma punctelor obținute în cele 5
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
1 0 0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0
0 0 0 0 1 0 0 0 0 0
0 0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 0 1
5. Afișați în consolă următorul output:
0 1 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0
0 0 0 0 1 0 0 0 0 0
0 0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 1 0 0 0 0
0 0 0 0 1 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0 0
11
222
3333
44444
555555
000000
11111
2222
333
44
Metode
Să presupunem că în flow-ul programului, la un moment dat vrem să executăm un
task foarte specific, bine definit, care se întinde pe mai multe linii de cod, cum ar fi, în
cazul citirii unei variabile de la utilizator sau calcularea unui rezultat folosind niște
operații complexe.
Pentru că este un task bine definit, pentru a ușura citirea codului programului, putem
muta tot acest bloc de linii de cod în altă parte și să îl referim prin apelarea unui
denumiri pe care să i-o dăm. În acest fel codul nostru este mai bine structurat, mai
În cazul în care apare un bug în programul nostru, va fi mult mai ușor de a face
Există, de asemenea, și situația în care un anumit cod poate fi apelat din zone
pizze, este de observat că ambele folosesc aceeși bucată de cod pentru a primi date
de la utilizator.
Astfel au apărut metodele (funcțiile). Acestea sunt blocuri de cod care efectuează
etc
și care sunt apelate între ele, sau din metoda public static void main(String[]args)
----------------------------------------
----------------------------------------
----------------------------------------
----------------------------------------
}
Sintaxa:
metoda
Exemple de apelare:
….....str.length():
afiseazaInConsolaNumarAleator(nrAleator);
….........
daDrumulLaRadio();
Exemplu:
//varianta 1:
complex.
return d:
//varianta 2:
return Math.random();
}
Ceea ce intoarce trebuie să fie de același tip cu key-wordul din definiția metodei:
int/double/String
Alte exemple
….........
void, int, boolean, String, int[], String[], char[], int[][], int[][][], orice alt obiect,
când nu.
double d = genereazaNumarAleator();
genereazaNumarAleator();
System.out.println(d);
Pe scurt, putem scrie:
System.out.println ( genereazaNumarAleator() );
În felul acesta facem economie de memorie și timp, nu mai definim o variabilă. Chiar
Fără parametrii
1. nu întoarce nimic
//diverse operații
2. întoarce ceva
//alte operatii
return str;
keyword
Cu parametrii
3. nu întoarce nimic
//diverse operații
4. întoarce ceva
..................
if (conditie){
return true;
} else {
return false;
keyword
Exerciţii
1. Realizati o metodă care primește un număr și returnează numărul de divizori.
3.
2. Realizați o altă metodă care primește un număr și returnează dacă numărul este
prim.
Exercitii extra
1. Să se creeze o metoda public static void sayHello() care afișează „Hello”. Să se
invoce metoda.
3. Să se creeze o metoda care public static void afiseaza() care afișează primele
Să se invoce metoda.
metoda.
7. Să se creeze o metoda public static int ridicaLaPatrat(int nr) care returnează
la tastatura si returneaza true daca e cuvantul = Food și false dacă nu. Să se afiseze
rezultatul.
Tablouri (Arrays)
Un tablou poate conţine mai multe elemente care aparţin aceluiaşi tip de date, spre
putem folosi variabile care sunt tablouri pentru a reţine 10 numere întregi.
Fiecare element din tablou are asociată o poziţie. Numerotarea poziţiilor începe de la
0 = prima poziţie
etc… Numărul total de elemente este 7, iar ultimul element, adică 14 este pe poziţia
6.
Un tablou care are o singură dimensiune, cum e cel de mai sus mai poartă
10 15 43 28
24 35 46 30
18 -100 3 48
Tabloul de mai sus este o matrice cu 4 coloane (column) şi 3 linii (row), adică 4 pe 3.
este o coloană, nu un singur număr. Fiecare element din acest tablou are de data
geometrice. Primul index este folosit pentru a indica rândul (axa Y) şi al doilea pentru
a indica linia (axa X). De exemplu, pentru 46 avem coordonatele (1,2). Mai exact,
A
B
Unde A este prima linie, B a doua şi C a treia. Deci mai întăi indicăm linia (adică
elementul A B sau C), apoi pentru vectorul obţinut trebuie să indicăm noua poziţie.
A= 10 15 43 28 (0, 0)
B= 24 35 46 30 (1, 0)
C= 18 -100 3 48 (2, 0)
Pentru a folosi un vector în java, vom adăuga un set de [] la declarare şi vom iniţializa
folosind din nou [], împreună cu cuvântul new şi numărul de elemente, ca în exemplu.
Dacă un tablou a fost iniţializat, elementele lui încă nu există, deci trebuie să atribuim
şi acestora valori.
Exemplu
// INITIALIZARI
elemente
tablou1[0] = s.nextInt();
tablou1[1] = s.nextInt();
tablou1[2] = s.nextInt();
// SAU
tablou2[i] = s.nextInt();
}
// AFISARE
System.out.println(tablou3[0]);
System.out.println(tablou3[1]);
System.out.println(tablou3[2]);
System.out.println(tablou3[i]);
Assignment
1.Să se găsească numărul cel mai mare dintr-un Array.
acestui număr.
numărului.
aleatoare între 1 și 10. Se citește un numar de tipul int de la tastatură între 1 și 10.
Varianta I: se va folosi bucla while cu un if nested in el, iar if-ul conține break.
începe cu indexul 0. Apoi merge x căsuțe în față sau în spate în funcție de valoarea
din index. Dacă pe indexul 0 scrie 4, merge 4 căsuțe în față. Dacă scrie -3 merge 3
afișeze de câte ori face salturi până când iese din array, sau -1 dacă nu iese din
array niciodată.
vectorul si luam valoarea cea mai mică și o punem pe prima poziție într-un alt vector.
Modificăm valoarea la cea mai mare valoare pe care o poate lua un integer:
Varianta 2: folosind metoda bubbling. Se compara valorile din primii doi indexi. Dacă
sunt în ordine, se inversează. Tot așa până la final. Astfel, valorile urcă, asemenea
bulelor de soda într-un pahar. (bubbling). Se parcurge din nou vectorul de mai multe
ori, până când nu mai au loc inversări. Pentru a ști dacă nu au mai avut loc inversări
folosim o variabilă de tip boolean. Mai multe detalii
vă uitați la răspuns.
angajatorii testează candidații. În fie lună se pune câte un test gratuit. Faceți testul
Practic, fiecare tablou conţine un tablou care conţine elemente. Null ne indică faptul că nu
avem niciun tablou.
Exemplu
// DECLARATII
int[][] t0;
int[] t1[];
int t2[][];
// INITIALIZARI
int[][] t3 = { { 1, 6, 3 }, { 2, 3, 5 } };
// 1 6 3
// 2 3 5
// echivalent cu:
t0 = new int[2][3];
t0[0][0] = 1;
t0[0][1] = 6;
t0[0][2] = 3;
t0[1][0] = 2;
t0[1][1] = 3;
t0[1][2] = 5;
t1 = new int[2][3];
pozitie de pe linie
t1[i][j] = scanner.nextInt();
pozitie de pe linie
t2[i][j] = scanner.nextInt();
// pentru afisare
pozitie de pe linie
System.out.println();
}
for (int[] vector : t1) { // ia vectorul de pe fiecare linie
System.out.println();
Assignment
de la tastatură. Să se afişeze.
acesta se află.
acestuia (afişarea va fi făcută aşa cum apar ei în matrice). Să se ţină cont de cazurile
extreme (când maximul este pe prima sau ultima linie, prima sau ultima coloană, sau
Pe fiecare coloană se găsesc toate notele pentru un student, iar pe fiecare linie se
tabelul de mai sus. Veţi avea nevoie de un vector pentru nume, un vector pentru
Excepţii
Excepţiile sunt evenimente nedorite care se întâmplă în timp ce programul rulează şi
când apelăm o poziţie prea mare sau prea mică dintr-un vector
termine sau pentru a trimite utilizatorului un mesaj de eroare mai estetic. Acest lucru
// 1)
int n;
try {
n = s.nextInt();
} catch (Exception e) {
0.");
}
// 2)
try {
n = rand.nextInt();
} catch (Exception e) {
// 3)
try {
System.out.println(vect[n]);
} catch (Exception e) {
Pentru exemplul 2, putem evita folosirea obiectelor cu valoarea null, astfel încât să
nu mai fie aruncate excepţii la rularea programelor. Codul poate fi scris în următorul
fel:
// 2)
rand = null;
if (rand != null) {
n = rand.nextInt();
Pentru al treilea exemplu, putem evita direct folosirea poziţiilor inexistente în cod.
Sau, dacă nu ne dăm seama de acest lucru, putem face o verificare ca mai sus.
if (k <n) {
System.out.println(vect[k]);
Sfaturi:
1. Ori de câte ori deschideți o paraneteză sau o acoladă închideți-o imediat, intrați
între paranteze / acolade și tastați Enter și scrieți acolo codul. - pentru a nu uita să
2. Chiar dacă după if / else / while există doar o singură instrucțiune, puneți totuși
3. Puteți comenta mai multe linii de cod odată, selectându-le și apăsând Control +
4. Puteți face tab la mai multe linii de cod odată, selectându-le și apăsând TAB (sau
Shift+Tab pt stânga).
JVM
JVM = Java Virtual Machine
Java Virtual Machine este un program care simulează procesorul calculatorului.
care pagina ne roagă să instalăm Java pentru a rula o anumită aplicație. Atunci
se instalează JRE.
JDK – Java Development Kit – conține tot ce conține JRE, precum și alte tool-
împachetatorul etc.
fișierul Main.java. Uitați-vă în folderul proiectului pe care l-ați creat. (Acesta se află în
binar, Main.class. Eclipse face acest lucru automat, ori de câte ori dăm Save la o
rulează Main.class.
Acest fișier binar se execută cu programul java.exe care se află în una din
următoarele locaţii:
care practic lansează JVM (dacă nu era lansată) și rulează programul nostru
(Main.class).
Când limbajul Java a fost gândit, el a fost gândit din start atfel încât aplicațiile scrise
în java să poată rula pe orice sistem de operare (platform independent) pentru a veni
JVM a fost astfel creată pentru a putea traduce (interpreta) orice aplicație java în
Astfel, îl traduce într-un .exe pentru Windows (sau într-un executabil pentru Linux,
într-un alt executabil pentru Mac, într-un alt executabil pentru Solaris, etc.).
Împachetarea
Dacă aplicația noastră are mai multe clase, pentru a putea rula, ele trebuie
împachetate într-un singur fișier, un fel de arhivă, care are extensia .jar.
ce clasă adică în ce fișier.class se află metoda pubic static void main (String[] args)
Eclipse face acest lucru automat când dăm RUN, dacă aplicația noastră are mai
Pe scurt:
(java.exe)
La rulare
Când rulează un program, JVM încarcă automat (din folderele proprii JRE sau JDK)
toate clasele Java din pachetul java.lang, adică clasele String, System, Object, etc.
Ea nu încarcă toate clasele din Java Standard Edition (Java SE). Nu încarcă automat
clasele precum Scanner, ArrayList. Sunt sute de clase în tot pachetul Java SE și ar
folosite.
În momentul citirii și executării unei aplicații scrise de noi, se încarcă doar clasele
import java.util.Scanner;
import java.util.ArrayList;
Clase. Obiecte
Clasele reprezintă tipuri de date definite de utilizator sau deja existente în sistem. O
Prin instanțierea unei clase se înțelege crearea unui obiect care corespunde tiparului
definit de clasa respectivă. În cazul general, acest lucru se realizează prin intermediul
Un exemplu de clasă predefinită este clasa String. Ea se instanțiază astfel (nu este
varianta următoare este corectă, dar ineficientă, din motive ce vor fi explicate ulterior.
s = new String("str");
Pentru a crea o clasă nouă, cu funcționalități dorite, vom adăuga în fişierul nostru
câmpuri şi metode.
Câmpuri
Un câmp este un obiect având tipul unei clase sau o variabilă de tip primitiv. Dacă
este un obiect atunci trebuie inițializat înainte de a fi folosit (folosind cuvântul cheie
new).
int i;
float f;
boolean b;
String s;
instantaClasei.numeCamp
Metode
O metodă este o acţiune care poate fi executată de clasa noastră. Pentru a crea o
int suma = 0;
suma += i;
}
}
mate.afiseazaSumaPrimelor10();
Exemplul dat mai sus conţine o metodă de tipul void. Aceasta înseamnă că metoda
oferă informaţii au alt tip înafară de void şi întorc la finalul acestora un răspuns.
int suma = 0;
return suma;
Iar pentru a folosi metoda, putem avea următoarea implementare în clasa de test:
Unde metoda poate fi apelată ca în primul exemplu sau poate fi folosită oriunde
putem folosi un număr întreg. Dacă metoda are alt tip, aceasta poate fi folosită
mate.getSumaPrimelor10());
nevoie de parametrii. O metodă poate avea oricâţi parametrii de orice tip. În schimb,
dacă metoda are prea mulţi parametrii e foarte probabil ca aceasta să poată fie
rescrisă cu mai multe metode. Următoarea metodă va calcula suma primelor numere
suma += i;
return suma;
int suma = 0;
suma += i;
suma);
}
Putem folosi şi metode din clasele date ca exemplu în Java. De exemplu pentru
clasa String:
System.out.println(s1.length());
System.out.println(s2.length());
// lista instructiuni
Pentru a utiliza un câmp într-o funcție a clasei respective, folosim direct numele
int dogs;
int cats;
anterioară.
public class VeterinaryTest {
vr.dogs = 199;
obiectului creat
toate referințele (la obiecte) la null și tipurile primitive la 0 (pentru tipul boolean la
false).
În Java fișierul trebuie să aibă numele clasei (publice) care e conținută în el. Cel mai
simplu și mai facil din punctul de vedere al organizării codului este de a avea fiecare
vr.cats = 99;
vr.dogs = 199;
vr2.dogs = 2;
vr.displayStatistics();
Se observă că, deși câmpul dogs aparținând obiectului vr2 a fost actualizat la
valoarea 2, câmpul dogs al obiectului vr1 a rămas la valoarea inițiala (199). Fiecare
Assignment
Assignment
1. Numere complexe
2. Operații
înmulțire pentru numere complexe. Definiți în clasa Operatii câte o metodă pentru
3. Biblioteca
Completați această clasă, așa cum considerați necesar. Apoi, creați un obiect de tip
carte și setați atributele introducând date de la tastatură. Pentru această folosiți clasa
Scanner:
4. Verificări cărți
tipul Carte.
Prima metodă va verifica dacă o carte este în dublu exemplar, caz în care va
întoarce adevărat.
A doua metodă va verifica dacă o carte este mai groasă decât altă, și va întoarce
5. Formatare afișare
direct prin nume. Apelul de funcții aparținând unui alt obiect se face prefixând apelul
Totuși, unele funcții pot trimite un parametru cu același nume ca și un câmp membru.
denumirea câmpului când se dorește utilizarea acestuia. Acest lucru este necesar
tratate:
int dogs;
int cats;
[...]
public void setAnimalsNo(int cats, int dogs) {
this.dogs = dogs;
this.cats = cats;
}
Constructori
Există uneori restricții de integritate care trebuie îndeplinite pentru crearea unui
Astfel, la crearea unui obiect al unei clase se apelează automat o funcție numită
constructor. Constructorul are numele clasei, nu returnează explicit un tip anume (nici
class MyClass {
// ...
param_n);
De reținut că, în terminologia POO, obiectul creat în urma apelului unui constructor al
Acesta creează întâi un obiect de tip String folosind constructorul fără parametru
constructorului), iar apoi creează un alt obiect de tip String pe baza unui șir de
caractere constant.
Clasele pe care le-am creat până acum însă nu au avut nici un constructor. În acest
caz, Java crează automat un constructor implicit (în terminologia POO, default
class SomeClass {
class Test {
System.out.println(instance.getName());
de forma:
public SomeClass() {
// Eventuale initializari
Student.java
class Student {
String name;
int averageGrade;
public Student() {
name = "Necunoscut";
averageGrade = 5;
media
name = n;
averageGrade = avg;
}
// (3) constructor cu un singur parametru, folosit atunci când
public Student(String n) {
name = n;
averageGrade = 5;
return name;
}
Declararea unui obiect de tip Student se face astfel:
Student st;
Crearea unui obiect Student se face prin apel la unul din cei 3 constructori de mai
sus:
compilare:
class Student {
String name;
int averageGrade;
name = n;
averageGrade = avg;
}
Putem identifica mai multe tipuri de constructori, printre care: fără parametrii (sau
String culoare;
int petale;
public Floare() {
culoare = “”;
petale = 4;
}
// constructor cu parametrii
this.culoare = culoare;
this.petale = petale;
// constructor de copiere
String(f.nume);
this.petale = f.petale;
Assignment
1. Să se implementeze o clasă Punct care să conțină:
un constructor care să primească cele două numere reale (de tip float) ce
reprezintă coordonatele.
mai sus și completează vectorul de puncte cu cele n instanțe ale clasei Punct
Punct.
anumită lungime fixată, conținând caractere alese aleator dintr-un alfabet. Această
Exemplu de utilizare:
char[] a = {'a','b','c'};
String-ului de convertit.
import java.util.Random;
// ...
se creeze:
Exemplu:
lungimeSir = 4;
alfabet = "abcdefgh";
Rezultat posibil: dfah
Obiecte
OOP = Object Oriented Programming
switchuri care sunt on/off, 1/0, plus/minus sau deschis/inchis (cum vreți voi). 1 este
În primii ani ai computerul, în anii 40, un panel de swithcuri era tot ce se introducea
binar.
Limba vorbită este mult mai complexă decât cea a unui computer. În timp ce creierul
uman înțelege propoziții, computerul nu înțelege decât starea unor swithuri. Pentru
Dar este foaret dificil să scrii instrucțuni în binar. Limbajele de programare, au fost
create ca punte între limbajul binar și cuvinte. Limbajele timpurii foloseau cuvinte
Curând au fost create primele limbaje evoluate, pentru a scrie programe de calculator
repede și eficient pentru a rezolva probleme din lumea reală. Aceste limbaje au fost
care un computer trebuie să le facă pentru a executa un program. Acest lucru le-a
evoluate sunt:
Programul definește toate datele și toate instrucțiunile pentru a procesa aceste date.
paote fi apelat de mai multe ori: pentru a scrie fișiere pe hard disk, trimite mesaje
biblioteci. Programatorii puteau folosi aceste funcții în aplicațiile lor. Acest lucru a
rezolve coimputerul.
taskurile ce trebie efectuate sunt descrise în obiecte. Obiectele sunt create și stocate
operare încarcă obiectele și efectuează operații asupra lor când este instruit.
Avantajele OOP:
scăzând costurile
// CONSTRUCTOR
public Student() {
// CONSTRUCTOR
this.nume = nume;
this.varsta = varsta;
this.nota = nota;
}
// ACCESSORS / GETTERS
return nume;
// MUTATORS / SETTERS
this.nume = nume;
return varsta;
this.varsta = varsta;
}
return nota;
this.nota = nota;
//....alte metode
Atributele cu fără access specifier (default) se văd numai din clasele care sunt
Atributele protected se văd din clasele din același pachet și din clasele care
Constructorul este metoda care construiește un nou obiect din clasa respectivă. El
numește public class Student, fișierul trebuie să se numească tot Student.java, iar
are return-type.
Chiar dacă noi nu specificăm un constructor, compilerul va pune el în codul binar
constructorul default:
public Student(){
inițializate.
Dacă în medtoda main() scriem Student student1 = new Student(); vom avea un
obiect de tip Student creat, dar el nu are nici numele, nici nota și nici vârsta setate.
care să îl scriem:
// CONSTRUCTOR
this.nume = nume;
this.varsta = varsta;
this.nota = nota;
this.nume = nume;
O dată creat obiectul putem apela atribute și metode din el. În principiu, am putea
student1.nume = "Ghoeorghita";
System.out.println(student1.nume);
private. Deci, nu îl putem apela din altă clasă. Declarându-l private am făcut ceea ce
pentru că adesea este nevoie să facem niște validări. De exemplu, ce facem dacă se
numai litere. De aceea avem metoda setNume() pe care o facem publică și în care
Vom apela atunci setterul și getterul dacă vrem să modificăm sau să afişăm numele:
student1.setNume(”John”);
System.out.println(student1.getNume());
// ATRIBUTELE CLASEI
// CONSTRUCTOR
this.nume = nume;
this.varsta = varsta;
this.nota = nota;
}
....getter, setteri, alte metode
STACK.
Atributele există atâta vreme cât obiectul există. Dacă obiectul nu mai are referințe
(variabile de pe STACK care să pointeze către el, va fi șters din memorie de către
garbage collector).
2. nr – identifier (denumire)
3. 0 – valoarea
5. scope/life of the variable. Variablilele locale (din metode există numai atâta
vreme cât se execută metoda). Variabilele de tip instanță sau statice (de tip clasă)
Obiectul există atâta timp cât există variabile pe STACK care pointează către el.
De exmplu:
student2 = student1;
student2 acum pointeză către același obiect ca și student1. Studnetul cu numele Ionel
garbage collector.
Life cycle of an object
Obiectul este creat cu keywordul new care invocă constructorul. Obiectul există în
memoria RAM a calculatorului (pe HEAP) atâta vreme cât există variabile care să
aibă referință către el. Dacă nu mai există nici o referință către el, obiectul este la
latitudinea garbage collector-ului. Acesta este un program care rulează din când în
când pentru a șterge obiectele fără referință și face rost de memorie. În programele
necesar. Noi nu îi putem spune când să ruleze, putem doar cel mult să îi
System.gc();
Un obiect fără referințe nu mai poate fi recuperat, pentru că nu mai ai cum să faci
referire la el.
În alte limbaje, cum ar fi C++, programatorul trebuie să aibă grijă să distrugă
obiectele de care nu mai are nevoie, altfel apar memory leaks și programme failure.
În Java, de memorie se ocupă JVM (Java Virtual Machine), care ruleză garbage
static
Un obiect poate avea și un alt tip de atribute (variabile) și metode: statice. Atributele
statice se mai numesc static fields sau class fields. Dacă în exemplul nostru, atributul
nume putea lua valori diferite pentru fiecare obiect în parte, atributele statice vor avea
}
Dacă modificăm valoarea atributului static la un obiect, ea se modifică la toate
obiectele.
Dacă avem:
Și facem:
student1.setGrupa(”grupa 1”);
System.out.println(student2.getGrupa());
Deși atributele statice se pot apela și așa, oficial ele se apelează așa:
Student.setGrupa(”grupa 1”);
System.out.println(Student.getGrupa());
sau o metodă de instanță (de obiect, nestatică) – pentru că pur și simplu nu știe
metode statice.
Putem pune metoda main() în interiorul clasei Student. Dar, atentie, nu putem apela
direct nici un atribut sau metoda din clasă, pentru că sunt de instanță, iar noi ne
this.nume = nume;
}
public void setNume(String nume){
this.nume = nume;
return nume;
student1.setNume(“Gigel”);
// aici am puteam face si direct
student1.nume = “Gigel”;
atributele private.
in setNume()
face așa:
System.out.println(new Student(”Ionel”).getNume());
Singurul dezavantaj e că o dată trecut la linia următoare, nu mai avem cum să facem
referire la acest obiect. El există în memorie, undeva, dar nu mai putem să îl folosim,
Aici putem observa obiectele in și out pe care le-am folosit. După cum vedeți, ele
Dacă dați click pe PrintStream, veți putea observa metoda println() pe care o folosim
frecvent: System.out.println().
În clasa System mai putem observa câteva metode:
folosim multele metode copyOf(…) din clasa Arrays, care sunt tot
statice: Arrays.copyOf(…….)
1970
După cum vedem, toate sunt metode statice. Se apelează folosind denumirea
clasei: System.metodă(). Nu este nevoie să creăm cun obiect pentru a folosi aceste
metode statice.
Obiecte
O aplicație OOP = colecție de obiecte distincte care incorporează date și
comportamente
Exemple de obiecte:
clienți
conturi bancare
animale
obiecte de tip service care manipulează alte obiecte (de tip domain: animale,
Cu excepția primitivelor, toate în java sunt obiecte. Metoda public static void main
care se află.
Clasa String este și ea un șablon care construiește obiecte de tip String. Este o clasă
puțin aparte, în sensul că poate crea obiecte atât pe Heap cât și pe String pool.
îl găsește îl crează.
Heap
Heap
true
afișează false
afișează false
Și noi o să impelentăm această metodă pentru ca să verifice egalitatea a două
comparăm.
Mai sus vedem că Object mai are o metodă care se moștenește la toate
datele obiectului respectiv. Aceasta ne ajută pentru a nu mai scrie fiecare câmp în
parte apelat.
Obiectele se constuiesc utilizând keywordul new. Acesta apelează constructorul din
clasa respectivă.
Constructorul este o metodă specială care nu are return-type (nici void, din nimic). El
Pot exista mai mulți constructori într-o clasă, care să difere între ei prin numărul, tipul
trebuie să difere ceva: fie numărul parametrilor, fie tipul lor, fie ordinea lor.
ram);
String marca;
int procesor;
int ram;
public Constructor() {
//constructorul default
}
this.marca = marca;
this.procesor = procesor;
this.ram = ram;
constructorul default, iar dacă noi vom construi un obiect cu acest constructor fără să
1990101123456L,
e de dorit.
c3.getCont().setSold(24.87);
Există mai multe tipuri de asocieri, le vom discuta în viitor.
Pachete
Uneori, în aplicațiile foarte mari putem avea aceeași denumire pentru mai multe
clase. Pentru a evita vreo confuzie, dar și pentru a avea o ordine a claselor noastre,
De exemplu, clasele Client și Cont sunt obiecte clasice cu care lucrăm. Le putem
Clasa Banca este o clasă operațională. O putem pune într-un pachet care să se
Clasele care nu sunt în același packet nu se văd unele pe altele și trebuie importate,
Într-adevăr, aparent nu are logică, dar ideea este că adesea (chiar foarte des) o
aplicație are biblioteci uriașe cu mii de clase atașate în aplicație. Pentru a face
economie de memorie, JVM nu încarcă toate aceste clase în memorie. S-ar umple
import domain.Cont;
........
}
Exerciţii clase şi obiecte
1. Scoala
Realizati un program:
Clasa Scoala
- denumire
- adresa
- nrElevi
- nrSali
- profesor1
- profesor2
- profesor3
- profesor4
- director
Clasa Profesor
- numele
- materia
Clasa Adresa
- strada
- numarul
- orasul
Nu setati pe profesor4.
Cerinţe:
2. My Mall
Clasa Mall
- denumire
- nrEtaje = 2 default
- Administrator
- Cinema
Clasa Administrator
- denumire
Clasa Cinema
- denumire
- nrSali
Cerinţe:
3. Agentii de turism
Realizati un program în care vor exista 2 agentii de turism. Numiți-le cum vreți voi.
Agentia 1:
Sejurul 1 (circuit)
Agentia 2:
Sejurul 4 (circuit):
Preturi hoteluri:
Hotel 1 : 50euro/noapte
Hotel 3: 60 euro/noapte.
4. Agentii de turism II
Cerinţe:
4. Folosiți constructorii.
5. Folosiţi array-uri.
6. Clientul poate alege un sejur prestabilit sau își poate configura sejurul.
7. Când clientul își va configura sejurul, veți crea un obiect de tip Sejur.
5. Echipe
Scop: Crearea unui proiect care să reflecte una sau mai multe echipe sportive.
11. În clasa Test creați 2 echipe, una de fotbal și una de baschet. Alișați la fiecare
12. Realizați modificările necesare astfel încât numele echipei pentru clasele
altă clasă. Acea clasă practic va refolosi codul din clasa corespunzatoare obiectului.
Exemplu:
class Page {
this.content = c;
this.no = no;
class Book {
sa existe
sa existe
private LibraryRow libraryRow = null; // agregare - poate
lipsi
this.libraryRow = libraryRow;
this.title = title;
class LibraryRow {
this.rowName = rowName;
}
}
class Library {
book = null;
obiect este dependentă de un alt obiect. În exemplul de mai sus, o carte nu poate
Moștenire (Inheritance)
Numită și derivare, moștenirea este un mecanism de refolosire a codului specific
altă clasă deja existentă. Ideea de bază este de a prelua funcționalitatea existentă
Clasa existentă este numită clasa-părinte, clasa de bază sau super-clasă. Clasa care
subiect.
class Animal {
System.out.println("Animal eating");
System.out.println("Wolf howling");
}
System.out.println("Wolf eating");
System.out.println("Snake biting");
class Test {
snake.bite();
snake.eat();
wolf.eat();
is a- indică faptul că o clasă este derivată dintr-o clasă de bază (intuitiv, dacă
avem o clasă Animal și o clasă Caine, atunci ar fi normal să avem Caine derivat
dacă avem o clasă Masina și o clasă Motor, atunci ar fi normal să avem Motor
Super
super este un cuvânt cheie, asemănător cu this. Singura diferenţă este că super este
constructor din clasa părinte sau o metodă folosind super în următorul fel:
class Animal {
int age;
this.age = age;
System.out.println("Animal eating");
super(age);
}
public void eat() {
super.eat();
System.out.println("Wolf eating");
Assignment
1. Întrucât în ierarhia de clase Java, clasa Object se află în rădăcina arborelui de
moștenire pentru orice clasă, ceea ce înseamnă că orice clasă va avea acces la o
serie de facilități oferite de Object. Una dintre ele este metoda toString(), al cărei
scop este de a oferi o reprezentare a unei instanțe de clasă sub forma unui șir de
caractere.
Definiți clasa Persoana cu un membru nume de tip String, și o metodă toString() care
instanță.
2. Adăugați metode toString() în cele două clase derivate, care să returneze tipul
Hint: vedeți metodele clasei Object, moștenită de toate clasele. Object oferă
care au unele atribute și metode similare, dar care au și unele atribute și metode
distincte.
din România. Vom stoca localități de toate tipurile, toate dimensiunile, din toate
județele.
La o primă vedere, putem crea clasa Localitate care să aibă următoarele atribute:
String denumire;
int numărDeLocuitori;
String județ;
String tipulLocalitatii;
String adresaPrefectura;
String adresaPrimarie;
String adresaSpital;
moștenească această clasă, dar care să aibă și unele atribute distincte. Renunțăm la
atributul tipulLocalitatii.
String judet) {
this.denumire = denumire;
this.numarDeLocuitori = numarDeLocuitori;
this.judet = judet;
// getteri, setteri
}
String judet,
String spital){
this.adresaPrefectura = prefectura;
this.adresaPrimarie = primarie;
this.adresaSpital = spital;
judet,
this.adresaPrimarie = primarie;
this.adresaSpital = spital;
String primarie){
this.adresaPrimarie = primarie;
judet){
}
Deși clasa ResedintaJudet pare să aibă doar 3 atribute, în realitate are 6, pentru că
Atentie: Dacă cele 3 atribute ale clasei Localitate sunt private tot le moștenșete, dar
constructorul unei subclase care moștenește o altă clasă, trebuie să fie trimiterea la
Dacă noi nu scriem super();, acest lucru îl va facem automat compilatorul care va
insera pe prima linie în codul compilat, comanda super();. În cazul nostru, noi vom
folosind comanda :
constructor, iar noi nu vom menționa keywordul super, vom avea o eroarea de
compilare, întrucât compilatorul va introduce keywordul super() automat care va bate
oras.setDenumire(”Braila”);
System.out.println(oras);
Ce obținem?
Deși moștenește atributele private, nu vom putea, totuși, scrie direct într-o metodă a
clasei Oras următorul cod: this.denumire = ”Iasi”;. Dar, vom putea folosi getterul
Aplicaţie:
Faceți o aplicație care să conțină clasa Animal și mai multe subclase (tipuri de
(sunet generic).”);
(SUPRASCRIERE)
System.out.println(“Pisica miauna.”);
System.out.println(“Pisica toarce.”);
}
}
pisica.toarce();
pisica.scoateSunet(); // ce se va afisa?
Aplicatie
apelăm pisica.scoateSunet();.
Nivele de acces
Există 4 nivele de acces:
protected – se pot vedea și din exteriorul pachetului, numai dacă clasa care
vrea să folosească acel atribut sau acea metodă este o subclasă a clasei care
deține acel atribut/metodă (atenție, dacă este subclasă, oricum moștenește, dar
dacă e în afara pachetului, iar dacă metoda nu este protected, nu o poate folosi)
String denumire;
//constructor:
this.marca = marca;
this.cc = cc;
CULOARE = culoare;
}
Odată setată, culoarea nu mai poate fi modificată niciodată în cod.
derivată (moștenită)
(de exemplu clasa String) public final class Animal {…} - clasa Animal nu poate fi
moștenită
Polimorfism
pe Heap.
Ce afisează acum:
animal.scoateSunet(); // ?
System.out.println(telefon);
// sau
telefon.setRingTone(“melodia preferata”);
interfețe)
instanceof
Clasa Catel extinde clasa Animal.
Up-casting și down-casting
Upcasting
System.out.println(loc);
Convertirea unei referințe la o clasă derivată într-una a unei clase de bază poartă
de către programator.
Exemplu de upcasting:
class Instrument {
}
// Wind objects are instruments //
i.play();
Deși obiectul flute este o instanță a clasei Wind, acesta este pasat ca parametru în
locul unui obiect de tip Instrument, care este o superclasa a clasei Wind. Wind este
clase (în special UML) în care moștenirea se reprezintă prin 2 blocuri așezate unul
sub altul, reprezentând cele 2 clase (sus este clasa de bază iar jos clasa derivată),
Downcasting:
care se merge în jos pe ierarhia claselor (se convertește o clasă de bază într-una
derivată). Acest cast trebuie făcut explicit de către programator. Downcasting-ul este
posibil numai dacă obiectul declarat ca fiind de o clasă de bază este, de fapt,
instanță clasei derivate către care se face downcasting-ul. Iată un exemplu în care
class Animal {
public void eat() {
System.out.println("Animal eating");
System.out.println("Wolf howling");
System.out.println("Wolf eating");
class Test {
a[i].eat(); // 1
// 2
((Snake)a[i]).bite(); // 3
}
}
Snake pentru a putea fi apelate metodele specifice definite în aceste clase. Înaintea
încerca să facem downcast către tipul Wolf al unui obiect instantiat la Snake mașina
Apelarea metodei eat() (linia 1) se face direct, fără downcast, deoarece această
(overrides) metoda eat(), apelul a[0].eat() va afișa “Wolf eating”. Apelul a[1].eat() va
apela metoda din clasă de bază (la ieșire va fi afișat “Animal eating”) deoarece a[1]
upcasting? Aceasta deoarece upcasting-ul se face atunci când pentru unul sau mai
multe obiecte din clase derivate se execută aceeași metodă definită în clasa părinte.
Clasa Object
Suprascrierea metodei equals()
Toate clasele moștenesc clasa Object, și implicit toate metodele acesteia (sunt public
și protected)
Metoda equals(Object o) în mod default verifică dacă adresele a două obiectele sunt
aceleași.
metoda
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
if ( marca == null) {
if (other.marca != null)
return false;
} else if (!marca.equals(other.marca))
return false;
if (frecventa == null) {
if (other.frecventa != null)
return false;
return false;
if (memorie == null) {
return false;
return false;
return true;
metoda hashCode().
Moștenire (Inheritance)
Numită și derivare, moștenirea este un mecanism de refolosire a codului și reprezintă
posibilitatea de a defini o clasă care extinde o altă clasă deja existentă. Ideea de
Clasa existentă este numită clasa-părinte, clasa de bază sau super-clasă. Clasa care
Moștenirea este un mecanism care permite crearea unor versiuni “specializate” ale
unor clase existente (de bază). Moștenirea este folosită în general atunci când se
specializare oferită prin clasa derivată) a unui lucru mai general. Un exemplu simplu
}
public class Dog extends Mammal {
obiect:
Dog este o subclasă atât pentru clasa Mammal cât şi pentru clasa Animal.
respectivă poate fi accesată doar din cadrul clasei însăși sau din clasele derivate
din această clasă. Clasele nu pot avea acest specificator, doar membrii acestora!
respectivă poate fi accesată doar din cadrul clasei însăși, nu și din clasele
derivate din această clasă. Clasele nu pot avea acest specificator, doar membrii
acestora!
respectivă.
class Animal {
}
}
În exemplul de mai sus, putem observa că obiectul b, chiar dacă este de tipul Animal
apelează metoda din clasa Dog. Motivul este următorul: la compilare, verificarea este
făcută pe tipul referinţei. Cu toate acestea, la rulare, JVM rulează metoda care
corect, clasa Animal având metoda move. Apoi, la rulare se va executa metoda
class Animal {
}
public void bark(){
b.bark();
b.bark();
suprascrisă.
Tipul returnat ar trebui să fie la fel sau un subtip a tipului declarat în metoda
atunci metoda din subclasă nu poate fi declarată nici private nici protected.
O subclasă dintr-un pachet diferit poate declara doar metodele non-final care
Super
Folosirea cuvântului cheie super se face de obicei când apelăm o metodă, un
class Animal {
1. Cuvântul-cheie "static"
De fiecare dată când cream o instanță a unei clase, valorile câmpurilor din cadrul
instanței sunt unice pentru aceasta. Ele pot fi utilizate fără ca altă instanță să le
modifice în mod implicit. Următoarea clasă conţine 2 câmpuri statice care pot fi
se apelează cu numele clasei. Ele se pot apela şi cu oricare instanţă, dar acest lucru
String color;
String name;
double weight;
color = "White";
name = "Joana";
weight = 0;
myCow.sound);
}
Un alt exemplu este folosirea unui câmp static pentru a numără câte instanţe s-au
public Dog() {
numberOfDogs++;
Atunci când folosim câmpuri statice, ele pot fi folosite în orice loc al clasei (în orice
şi pot fi apelate cu numele acesteia. Într-o metodă statică se pot utiliza doar câmpuri
doar o instanţă a acesteia. Acestea pot fi apelate cu instanţele clasei, însă nu vor
Un atribut ne-static nu poate fi apelat decât dacă avem un obiect. Atributele ne-
statice sunt atribute specifice ale obiectelor. Nu poate exista o memorie ram fără
computer.
int ram;
//constructor
System.out.println ( ram );
System.out.println (c1.getRam());
Computer.go();
Dintr-o metodă statică (= context static) nu putem apela DIRECT un atribut ne-static,
pentru că metoda statică poate se fie apelată fără să existe vreun obiect. Dacă nu
Soluția:
ajutorul clasei
parametru.
int ram;
//constructor
preia practic pe c1
System.out.println( computer.ram ); //computer.ram
//afișăm ram-ul
lui c1.
Atributele ne-statice
Atributele statice
Modul de apelare
Assignment
astfel unei variabile de tip referință care are atributul final îi poate fi asignată o
singură valoare (variabila poate face referinţă către un singur obiect). O încercare
nouă de asignare a unei astfel de variabile va avea ca efect generarea unei erori la
compilare. Totuși, obiectul către care face referinţă o astfel de variabilă poate fi
public Cow() {
constructor
this.color = color;
}
}
Variabilele primitive De
referință
Locale (în Definite în √ √ Nu au access specifiers (public,
metode) metodă private, protected); Nu au
static; Pot fi final
Definite ca √ √
parametri în
paranteza
metodei
câmpuri De instanță √ √ Pot avea access specifiers
(nestatice) (public, private, protected); pot
fi statice; pot fi final; pot fi
De clasă (statice) √ √ static + final
sunt declarate.
3. Constante
Constantele sunt definite folosind atât static, cât şi final. Identificatorul lor se scrie cu
Java. Conversia între o dată primitivă şi clasa ei se face automat – acest mecanism
Problemă:
Cum facem?
Soluție:
Clasele Wrapper sunt asemenea lui String. String împachetează un șir de caractere
număr), asupra căruia putem efectua multe operații. (Primitiva este stocată într-un
încarcă automat.
int nr = 8;
// alternativ
// sau
// alternativ
Putem efectua o mulțime de operații cu aceste obiecte. A se vedea API pentru clasa
Integer.
0 sau 1.
adresele.
sau false.
System.out.println(integer1.toString());
Există o muțime de metode utile care sunt statice și care manipulează int-uri:
System.out.println(Integer.compare(3355, 545747));
static int compareUnsigned(int x, Compares two int values numerically treating the values
int y) as unsigned.
System.out.println(Integer.compareUnsigned(3355, -545747));
static int max(int a, int b) Returns the greater of two int values as if by calling Math.max.
System.out.println(Integer.max(3355, -545747));
static int signum(int i) Returns the signum function of the specified int value.
Returnează semnul.
System.out.println(Integer.max(-545747));
static int sum(int a, int b) Adds two integers together as per the + operator.
System.out.println(Integer.sum(3355, -545747));
System.out.println(Integer.toBinaryString(5747));
static int Returns the number of zero bits preceding the highest-order
numberOfLeadingZeros(int i) ("leftmost") one-bit in the two's complement binary
representation of the specified int value.
System.out.println(Integer.numberOfLeadingZeros(3));
static int Returns the value obtained by reversing the order of the bits in the two's
reverse(int i) complement binary representation of the specified int value.
Inversează biții.
static String toString(int i) Returns a String object representing the specified integer.
System.out.println(Integer.toString(3));
Există metode care transformă un int ↔ Integer ↔ String. Metode similare există și în
celelalte clase wrapper (Double, Float, Short, Long, Boolean, Character etc).
Atribute:
Integer.MAX_VALUE → 2 miliarde și ceva
// sau
5. Obiecte imutabile
Dacă toate atributele unui obiect sunt finale, spunem că obiectul respectiv este
obiecte sunt instanțele clasei String. Odată create, prelucrările asupra lor (ex.:
înseși.
String s = "abc";
s.toUpperCase(); // s-ul nu se modifică. Metoda întoarce o referință
Observăm că în acest exemplu am folosit un String literal. Literalii sunt păstrați într-
un String pool pentru a limita memoria utilizată. Asta înseamnă că dacă mai
declarăm un alt literal “abc”, nu se va mai aloca memorie pentru încă un String, ci
vom primi o referință către s-ul inițial. În cazul în care folosim constructorul pentru
String a = "abc";
String b = "abc";
în sine am fi folosit metoda equals. Același lucru este valabil și pentru oricare alt tip
referință: operatorul "==" testează egalitatea referințelor (i.e. dacă cei doi operanzi
Odată aceste obiecte create, conținutul lor (Maria sau 4) nu se mai schimbă
Variabilele de referință str și i1 pot să pointeze către alte obiecte, dar, obiectele de pe
heap: new String("Maria"), new Integer(4) sau string pool "Maria" nu se mai schimbă
niciodată.
str = "Ioana";
i1 = new Integer(8);
Obiectul nu s-a schimbat!! Variabila de referință doar pointează către un alt obiect!
String str = "Mac";
către acesta
Semnătura metodelor. Supraîncărcare
(Overloading)
Semnătura metodei este dată de numele acesteia şi lista de parametrii (numărul şi
tipul fiecăruia). Într-o clasă nu putem avea metode cu aceeaşi semnătură, dar putem
Antetul metodei, este format din modificatori, tipul metodei şi semnatura acesteia.
acesteia.
Dacă într-o clasă există mai multe metode cu acelaşi nume, dar cu o listă de
// implementation
// implementation
Deci pot exista într-o clasă mai multe metode cu același nume dacă:
4. nu contează return-type-ul
Cu alte cuvinte, dacă semnătura metodelor este diferită. Semnătura unei metode
semnătura metodei.
this.marca = marca;
this.procesor = procesor;
type... parameternName
acesta trebuie să fie ultimul din lista de parametrii. Ceilalţi parametrii normali trebuie
atare.
Exemplu
printMax(34,3,3,2,56.5);
printMax(new double[]{1,2,3});
if (numbers.length == 0) {
return;
if(numbers[i]> result)
result = numbers[i];
}
Care va afişa următorul rezultat:
Exemplu 2
25372);
“fdyerfa”, “dsgjkse”);
“fsdgsfg”, bicicleta1);
de int-uri
contine parametrii
System.out.println(numar);
variabil de string-uri
System.out.println(siruri[i]);
}
public static void metoda3 (Object... obiecte){ //adică număr
variabil de obiecte
contine parametrii
System.out.println(obiect);
if (nr == 0){
return;
}
return; nu face altceva decat sa termine metoda. Dar el nu returneaza nimic, pentru
Metode. Recapitulare
Assignment
1. Pentru următorul program, apelaţi cele 2 funcţii lipsă şi schimbaţi structura if-else
într-un switch.
import java.util.Scanner;
int choice;
choice = kb.nextInt();
System.out.println();
if (choice == 1) {
butterfly();
} else if (choice == 2) {
elephant();
} else if (choice == 3) {
'teddybear'
} else if (choice == 4) {
} else {
System.out.println( "Sorry, that wasn't one of the
choices." );
System.out.println( "\nGoodbye!" );
");
System.out.println(" _..--\"\"-. .-
\"\"--.._ ");
'-._");
',...:::. '.");
System.out.println("( .'``'''::;
;::'''``'. )");
/");
System.out.println(" /
/");
/");
System.out.println(" | \\0|0/ | /");
/");
_..'");
\"`\"`");
System.out.println("
` \\");
System.out.println("
'--' /.____");
/");
`\\");
|");
System.out.println(" / /
` |");
System.out.println(" | .\\/
.--. __ \|");
/");
System.out.println(" jgs `
' |------'`");
System.out.println("
|");
System.out.println("
/");
System.out.println(" ``");
System.out.println(" <====,.;;--.");
System.out.println("
|===| //");
System.out.println("___________\\|===| //_____,----
\"\"\"\"\"\"\"\"\"\"-----,_");
----,____ `,");
System.out.println(" |==||
\\");
System.out.println(" |==| pb
) |");
System.out.println(" |==| _____
______,--' '");
`\"\"\"\"\"\"\"\" _,-'");
System.out.println(" `=
__,---\"\"\"-------------\"\"\"''");
pierdem. Reparaţi ambele fişiere astfel încât împarţirea "(a + b + c) / 2" să devină "(a
+ b + c) / 2.0" peste tot unde apare. Este mai uşor să reparaţi fişierul care conţine
Adăugaţi încă un test pentru ambele fişiere: găsiţi aria unui triunghi cu laturile de 9, 9,
şi 9. Cât de dificilă a fost această modificare pentru fişierul care foloseşte funcţii?
double a;
a = triangleArea(3, 3, 3);
of " + a );
a = triangleArea(3, 4, 5);
of " + a );
a = triangleArea(7, 8, 9);
of " + a );
double s, A;
s = (a+b+c) / 2;
A = Math.sqrt( s*(s-a)*(s-b)*(s-c) );
return A;
}
public class HeronsFormulaNoFunction {
int a, b, c;
double s, A;
a = 3;
b = 3;
c = 3;
s = (a + b + c) / 2;
A = Math.sqrt(s * (s - a) * (s - b) * (s - c));
area of " + A );
a = 3;
b = 4;
c = 5;
s = (a + b + c) / 2;
A = Math.sqrt(s * (s - a) * (s - b) * (s - c));
area of " + A );
a = 7;
b = 8;
c = 9;
s = (a + b + c) / 2;
A = Math.sqrt(s * (s - a) * (s - b) * (s - c));
area of " + A );
a = 5;
b = 12;
c = 13;
s = (a + b + c) / 2;
A = Math.sqrt(s * (s - a) * (s - b) * (s - c));
System.out.println("A triangle with sides 5, 12, 13 has an
area of " + A );
a = 10;
b = 9;
c = 11;
s = (a + b + c) / 2;
A = Math.sqrt(s * (s - a) * (s - b) * (s - c));
area of " + A );
a = 8;
b = 15;
c = 17;
s = (a + b + c) / 2;
A = Math.sqrt(s * (s - a) * (s - b) * (s - c));
area of " + A );
}
3. Scrieţi o funcţie care să calculeze distanţa dintre 2 puncte. Având 2 puncte (x1, y1)
puncte. Folosiţi clasa Math pentru a calcula puterea unui număr şi rădăcina acestuia.
3,-1,-2) );
);
public static double getDistance(int x1, int y1, int x2, int y2)
4. Scrieţi o funcţie. Aceasta va returna numele unei luni dintr-un an, în funcţie de
return result;
următoarele metode:
calculeze, apoi îi va cere valorile necesare pentru forma respectivă (lungime, lăţime,
aria rezultată.
vor face în metoda main(), iar valorile trebuie trimise prin parametrii, respectiv
Veţi avea nevoie de valorea lui pi pentru aria cercului. Aceasta poate fi folosită prin
constanta Math.PI.
Programul va trebui să ruleze la infinit până când utilizatorul decide să iasă din
acesta.
6. Funcţii pentru apelul alfabetului - un alt program care conţine doar apeluri de
metode.
display (9)
System.out.println();
System.out.println();
display (6)
System.out.println();
/**************************************
*************************************/
if (doit)
System.out.print("Crocodile ");
System.out.print("Doggie ");
}
public static void e(int howmany) {
String s;
s = "Elephant ";
int x = 0;
while (x <howmany) {
System.out.print(s.charAt(x));
x = x + 1;
int x = 0;
while (x <reps) {
System.out.print("Horseradish ");
x = x+1;
ignoredparameter = 32;
System.out.print("Ice_cream" + space);
}
public static String j(int whichone) {
if (whichone == 1)
else if (whichone == 2)
else
System.out.print("Kiwi ");
if (a && b)
System.out.print("Lettuce ");
else
System.out.print("Lhasa_apso ");
if (a || b)
System.out.print("Mango ");
else
System.out.print("Monkey! ");
}
public static int o() {
System.out.print("Orangutan ");
System.out.print("Quail ");
if (first)
String s;
s = "Snake ";
int x = 0;
while (x <howmany) {
System.out.print( s.charAt(x) );
x = x+1;
int x = 0;
while (x <reps) {
System.out.print("Valentine_candy ");
x = x + 1;
ignoredparameter = 32;
String space = Character.toString((char) ignoredparameter);
System.out.print("Walrus" + space);
if (whichone == 1)
else
System.out.print("Yams ");
else
următor:
4. Checkout
Please enter your choice: 1
ADD KEYCHAINS
4. Checkout
VIEW ORDER
CHECKOUT
Va trebui să creaţi metode pentru fiecare dintre cele patru opţiuni din meniu.
4. Checkout
4. Checkout
4. Checkout
4. Checkout
CHECKOUT
Veţi avea nevoie de 2 noi variabile în funcţia main, una pentru stocarea numărului de
breloace, şi unul pentru a stoca preţul pentru un breloc. Preţul ar trebui să fie de 10
RON.
returnat void. Va afişa, pe 3 linii diferite, numărul de breloace din comandă, preţul
void. Va cere utilizatorului numele acestuia pentru a face corect livrarea, va afişa
Funcţia va trebui să returneze valoarea true dacă n este un număr par (se divide
Funcţia va întoarce valoarea true dacă numărul este divizibil cu 3, şi false altfel.
Scrieţi în funcţia main() o buclă for care generează numere de la 1 la 20. Folosiţi
instrucţiuni if în interiorul acestei bucle pentru a marca numerele care sunt pare prin
semnul "<" şi cu un "=" numerele divizibile cu 3 şi cu "both" dacă numerele sunt
divizibile şi cu 2 şi cu 3.
Această funcţie va trebui să returneze valoarea true dacă n este prim şi false altfel.
Un număr este prim dacă acesta este divizibil doar cu 1 şi cu el însăşi. Putem rezolva
Dacă găsiţi orice număr la care numărul dat este divizibil, puteţi returna false fără a
termina bucla.
Dacă bucla se termină şi nu găseşte niciun număr cu care să îl dividă, atunci putem
După ce aţi terminat e scris funcţia, scrieţi metoda main() care conţine o altă buclă
for. Afişaţi toate numerele de la 2 la 20, şi afişaţi în dreptul numerelor prime semnul
"<".
1. Pachete
Pachetele sunt folosite pentru a grupa clasele în funcţie de modul în care acestea comunică.
Pentru a folosi pachete, se va declara pachetul pe prima linie din fişierul clasei. Pachetele
grupează clasele folosite în foldere în interiourul proiectului, în folderul de fişiere surse.
Pentru a denumi un pachet, formatul standard este numele paginii web specificat invers
(exemplu pentru jademy.ro, avem pachetul ro.jademy) (mai ales în Android). Dacă avem
pachetul ro.jademy şi câteva clase în acest pachet (Test.java), atunci structura proiectului va fi
în felul următor: în folderul src, vom avea subfolderul ro, în subfolderul ro, vom avea
subfolderul jademy, iar în subfolderul jademy vom avea clasa Test.java
Pentru a folosi o clasă din acelaşi pachet, aceasta este recunoscută automat. Pentru a folosi
clase din pachete diferite, trebuie să importăm clasa respectivă în clasa în care vrem s-o
folosim. Deci vom folosi un import.
2. Nivele de Acces
Pentru a accesa câmpurile şi metodele în alte clase şi pachete, dar şi pentru a restricţiona
accesul la acestea, putem folosi o serie de modificatori.
În cazul modificatorului public, elementele respective pot fi accesate din orice alta clasă
(indiferent de pachetul în care se află). În cazul indentificatorului private, acestea nu pot fi
accesate decat în clasa în care au fost declarate.
Câmpurile şi metodele care au modificatorul protected sunt vizibile în clasa în care au fost
create, în subclase şi în acelaşi pachet, iar cele care nu au niciun modificator sunt vizibile doar
în clasă şi în pachet. Acest modificator se mai numeşte şi modificator de pachet.
Un atribut sau o metodă cu modificator de acces protected poate fi văzut/ă și din alt pachet,
dacă clasa care vrea să îl/o vadă este subclasă a clasei care conține acest atribut/metodă, adică
dacă o moștenește.
În superclasă :
3. Încapsulare
În mod normal, câmpurile unei clase sunt private pentru a nu avea acces direct la
ele. Pentru a avea acces la ele, vom folosi metode publice de set şi de get.
return name;
this.name = name;
return hireDate;
}
public void setHireDate(String hireDate) {
this.hireDate = hireDate;
return salary;
Definirea claselor
Clasele se definesc de obicei în fişiere diferite. Putem defini 2 clase în acelaşi fişier,
cu condiţia ca doar una din ele să fie publică. Clasa care este publică trebuie să aibă
acelaşi nume cu fişierul în care este definită. Putem defini o clasă în interiorul altei
În cazul claselor care se află în interiorul altei clase, ele pot fi statice. Dacă sunt
statice, se denumesc clase statice imbricate. Dacă sunt clase imbricate ne-statice se
mai numesc şi clase interioare. Putem avea clase şi în interiorul metodelor. Acestea
String getDate() {
interioara nestatica
mug.size = size;
return mug;
// clasa locala
class Tie {
}
System.out.println(new Tie().color);
class Mug {
String color;
int size;
double size;
int color;
}
// data de angajare pentru fiecare angajat
class HireDate {
int day;
int month;
int year;
public, și anume clasa care poartă și numele fișierului. Restul claselor trebuie să aibă
modificator de acces default (adică nimic). Dezavantajul este că clasa nu se vede din
alte pachete.
Dacă vă uitați în folderul unde este proiectul, veți vedea în subfolderul src în pachetul
respectiv un singur fișier .java, iar în subfolderul bin în pachetul respectic mai multe
fișiere .class.
Employee
statica
de clasa
}
}
Blocuri
într-o clasă putem avea blocuri care nu sunt legate de nicio metodă în interiorul
În cazul în care acestea sunt statice, se execută o singură dată, atunci când folosim
static {
public Duck() {
System.out.println("Duck Constructor");
}
Pentru exemplul de mai sus, se vor afişa următoarele linii în consolă:
Duck Constructor
Duck Constructor
inițilizează la 10
Rulează blocul nestatic de inițializare
//constructor / constructori
//getteri, setteri
Şi metoda main().
//......
masina1.setMarca( ”Dacia” );
Alt exemplu este cazul în care Eclipse ne genereaza metoda equals() pentru o clasă:
//constructor / constructori
//getteri, setteri
@Override
//........
System.out.println(computer1 == computer2);
System.out.println ( computer1.equals(computer2) );
metoda equals()
celor 2 computere.
caracteristicile lor,
// am fi obținut tot false, ca în cazul lui == pentru că
și ==,
obj este o variabilă care preia ca referință pe computer2. Adică, obj este o variabilă
locală de pe stack care va pointa către același obiect către care pointează și
computer2.
dacă pointează către același obiect. Adică dacă computer1 și computer2 sunt unul și
același obiect. (În cazul nostru, nu sunt unul și același obiect, sunt obiecte diferite,
client.
String nume;
Client client1;
Client client2;
this.nume = nume;
instanța Furnizorului
Magazin magazin1;
Magazin magazin2:
this.nume = nume;
this.furizor = furnizor;
this.client = client;
Iată un exemplu în care vom extinde clasa Student pentru a cunoaște grupa din care
face parte:
class Grupa {
Grupa (){
crt = 0;
}
public boolean addStudent(String nume, int media) {
if (crt <studenti.length) {
return true;
return false;
class Student {
this.name = name;
this.averageGrade = averageGrade;
După cum știți, obictele se alocă pe heap. Pentru ca un obiect să poată fi folosit, este
necesară cunoașterea adresei lui. Această adresă, se reține într-o referinţă. Limbajul
(management) transparent.
Student st;
creează o referință care poate indica doar către o zonă de memorie inițializată cu
patternul clasei Student fără ca memoria respectivă să conțină date utile. Astfel, dacă
jos:
s2 = s1;
s2.averageGrade = 10;
System.out.println(s1.averageGrade);
se va afișa 10. Motivul este că s1 și s2 sunt două referințe către ACELAŞI obiect din
memorie. Orice modificare făcută asupra acestuia prin una din referințele sale va fi
vizibilă în urma accesului prin orice altă referință către el. În concluzie, atribuirea de
ele, NU VOR FI VIZIBILE după apel, deoarece ele modifică o copie a referinței
originale.
class TestParams {
st.averageGrade = 10;
s.averageGrade = 10;
modificaReferinta(s); // 1
System.out.println(s.getName()); // 1'
modificaObiect(s); // 2
System.out.println(s.averageGrade); // 2'
Astfel, apelul (1) nu are niciun efect în metoda main pentru că metoda
modificaReferinta are ca efect asignarea unei noi valori referinței s, trimisă prin
ajutorul metodei setName sau prin acces direct. Linia (2') va afișa textul: 10.
Exemplu
nr = 10;
bicicleta.marca = "BMX";
}
public static void main(String[] args) {
int nr = 5;
modifica(nr);
bici.marca = "RK";
modifica(bici);
Enum
Enum-urile au fost introduse în Java 5.0. Scopul lor este să restricţioneze o variabilă
la câteva valori predefinite. Valorile din această listă enumerată poartă numele de
enumeraţii.
Cu ajutorul enum-urilor, este posibil să reduceţi numărul bug-urilor din cod. De
Class FreshJuice{
FreshJuiceSize size;
juice.size =FreshJuice.FreshJuiceSize.MEDUIM ;
Observaţie: enumurile pot fi declarate în fişiere proprii sau în interiorul unei clase.
Constructori
this() sau this(parametri)
supraîncărcarea)
Atribute
this.atribut = valoare / variabilă locală;
super.atribut
Metode
this.metoda() / this.metroda(parametri)
overloaded / suprascrisă
super.metoda() / super.metoda(parametri)
apelarea unei metode din clasa mamă pe care noi o extindem.
Referinţa this
super nu se comportă ca o referinţă.
Exemplu 1
În main():
toto.scoateSunet();
System.out.println("Ham");
System.out.println("Miau");
Exemplu 2
În metoda main():
Furnizor furnizor1 = new Furnizor (“Pepsi”);
Clasa Furnizor:
String nume;
Client client1;
Client client2;
this.nume = nume;
}
Polimorfismul
Polimorfismul este abilitatea unui obiect de a lua mai multe forme. Cea mai întâlnită
Fiecare obiect din Java care poate trece un test de IS-A este considerat ca fiind
polimorfic. În Java, toate obiectele sunt polimorfice, având în vedere că pot trece
testul IS-A atât pentru tipul lor cât şi pentru clasa Object.
Variabilei referinţă îi pot fi reatribuite alte obiecte dacă aceasta nu a fost declarată ca
final. Tipul variabilei referinţă va determina metodele pe care le poate apela din
obiect.
O variabilă referinţă poate face referire la oricare obiect de tipul declarat, sau la unul
din subtipurile tipului declarat. O variabilă referinţă poate fi declarată ca o clasă sau o
interfaţă.
Acum, clasa Deer poate fi considerată ca fiind polimorfică având în vedere că are o
Când aplicăm regulile pentru variabilele referinţă pentru o referinţă de tipul Deer,
Animal a = d;
Vegetarian v = d;
Object o = d;
Toate variabilele referinţă d, a, v, o fac referire la acelaşi obiect Deer din heap.
Reţinerea în Array
Se consideră clasele următoare:
System.out.println(“Sunet generic”);
System.out.println(“Vrabiuta ciripeste.”);
Animal a;
a = new Vrabie();
Definirea unei variabile de tip Animal poate fi utilă, deoarece, uneori îi putem pasa
diferite Animale.
Deși poinetază către un obiect de tip Vrabie, totuși variabila animal este un Animal.
pe ciripeste(): animal.ciripeste();.
selecta pe aceasta.
Invocation.
}
Upcasting și Downcasting
Convertirea unei referințe la o clasă derivată într-una a unei clase de bază poartă
de către programator.
Exemplu de upcasting:
class Instrument {
Deși obiectul Flute este o instanță a clasei Wind, acesta este pasat ca parametru în
locul unui obiect de tip Instrument, care este o superclasă a clasei Wind. Upcasting-
clase (în special UML) în care moștenirea se reprezintă prin 2 blocuri așezate unul
sub altul, reprezentând cele 2 clase (sus este clasa de bază iar jos clasa derivată),
Deci, oriunde ni se cere un tip de data, putem folosi tipul respectiv, sau orice
subclasă derivată din tipul cerut. Ca regulă generală, obiectul transmis, trebuie sa fie
care se merge în jos pe ierarhia claselor (se convertește o clasă de bază într-una
derivată). Acest cast trebuie făcut explicit de către programator. Downcasting-ul este
posibil numai dacă obiectul declarat ca fiind de o clasă de bază este, de fapt,
class Animal {
System.out.println("Wolf howling");
System.out.println("Wolf eating");
System.out.println("Snake biting");
}
}
class Test {
a[i].eat(); // 1
((Wolf)a[i]).howl(); // 2
((Snake)a[i]).bite(); // 3
}
}
Snake pentru a putea fi apelate metodele specifice definite în aceste clase. Înaintea
încerca să facem downcast către tipul Wolf al unui obiect instanţiat la Snake mașina
Apelarea metodei eat() (linia 1) se face direct, fără downcast, deoarece această
(overrides) metoda eat(), apelul a[0].eat() va afișa “Wolf eating”. Apelul a[1].eat() va
apela metoda din clasă de bază (la ieșire va fi afișat “Animal eating”) deoarece a[1]
upcasting? Aceasta deoarece upcasting-ul se face atunci când pentru unul sau mai
multe obiecte din clase derivate se execută aceeași metodă definită în clasa părinte.
Up-casting
Pentru că orice Oraș este (is-a) Localitate, acest cast se face implicit de către
„transformare”, localitate va avea mai puține atribute și metode decât Oras. Practic
Down-casting
Din exact același motiv, cazul invers nu este posibil:
localitate are mai puține atribute și metode. Variabila oras care preia obiectul
În plus, deși orice Oraș este o Localitate, nu orice Localitate este neapărat un Oraș.
compilare, va crăpa la rulare. localitate este un obiect de tip Localitate. Oras trebuie
să aibă atribute suplimentare, care, pur și simplu, nu exsită în cadrul lui localitate
Down-castingul este posibil, numai dacă, localitate pointează către un obiect de tip
Oraș! Precum în cazul în care avem un array sau arraylist de tip Localitate care este
populat cu diverse obiecte definite prin relația is-a Localitate, adică: Sate, Comune,
Orașe, Municipii. În acest caz, unele din localitățile din arraylist pointează către
În cazul parcurgerii unui arraylist de localități care pot fi sate sau comune sau orașe
orasului
de tip Localitate
System.out.println(orasDeLucru.getNumarDeLocuitori());
}
Clase abstracte
Fie urmǎtorul exemplu (Thinking in Java) care propune o ierarhie de clase pentru a
Instrument
Clasa Instrument nu este instanţiatǎ niciodată pentru cǎ scopul sǎu este de a stabili
o interfaţǎ comunǎ pentru toate clasele derivate. În acelaşi sens, metodele clasei de
bazǎ nu vor fi apelate niciodatǎ. Apelarea lor este ceva greşit din punct de vedere
conceptual.
Clase abstracte
Dorim sǎ stabilim interfaţa comunǎ pentru a putea crea funcţionalitate diferitǎ pentru
Metodele suprascrise în clasele derivate vor fi apelate folosind dynamic binding (late
polimorfismului.
Nu existǎ instanţe ale unei clase abstracte, aceasta exprimând doar un punct de
pornire pentru definirea unor instrumente reale. De aceea, crearea unui obiect al unei
clase abstracte este o eroare, compilatorul Java semnalând eroare in acest caz.
Metode abstracte
Pentru a exprima faptul cǎ o metodǎ este abstractǎ (adicǎ se declarǎ doar interfaţa
O clasǎ care conţine metode abstracte este numitǎ clasă abstractǎ. Dacǎ o clasǎ are
una sau mai multe metode abstracte atunci ea trebuie sǎ conţinǎ în definiţie cuvântul
abstract.
abstract class Instrument {
// ...
Deoarece o clasǎ abstractǎ este incompletǎ (existǎ metode care nu sunt definite),
implementeazǎ toate metodele abstracte ale clasei de bazǎ. Putem defini clase
abstracte care moştenesc alte clase abstracte şi tot aşa. O clasǎ care poate fi
Acest lucru este folositor când declarǎm o clasǎ pentru care nu dorim instanţe (nu
este corect conceptual sǎ avem obiecte de tipul acelei clase, chiar dacǎ definiţia ei
este completǎ).
Interfeţe
INTERFETE
unei interfeţe e similară cu scrierea unei clase, dar sunt concepte diferite. O clasă
“formǎ” pentru o clasǎ: numele metodelor, lista de argumente, valori întoarse, dar
farǎ nicio implementare. O interfaţǎ poate conţine câmpuri dar acestea sunt în mod
cod care foloseşte o anumitǎ interfaţǎ ştie ce metode pot fi apelate pentru acea
interfaţǎ.
Pentru a crea o interfaţǎ folosim cuvântul cheie interface în loc de class. La fel ca în
cazul claselor, interfaţa poate fi declaratǎ public doar dacǎ este definitǎ într-un fişier
Pentru a defini o clasǎ care este conformǎ cu o interfaţǎ anume folosim cuvântul
Pentru a defini o interfaţǎ care moşteneşte altǎ interfaţǎ folosim cuvântul cheie
// Compile-time constant:
String what();
void adjust();
}
System.out.println("Suflat.play()");
return "Suflat";
System.out.println("Trompeta.play()");
System.out.println("Trompeta.adjust()");
Implicit, specificatorul de acces pentru membrii unei interfeţe este public. Atunci când
interfaţǎ ele nu au fost specificate explicit astfel. Acest lucru este necesar deoarece
specificatorul de acces implicit în clase este package-private, care este mai restrictiv
decât public.
O interfaţă e scrisă într-un fişier cu extensia .java, iar numele interfeţei publice
package java.util;
O interfaţă fără metode mai este cunoscută şi ca tagging interface. Există două
de multe interfeţe din Java, putem folosi interfeţele pentru tagging pentru a crea
înalt. Deoarece o interfaţǎ nu specificǎ niciun fel de implementare (nu existǎ nici un
fel de spaţiu de stocare pentru o interfaţǎ) este normal sǎ “combinǎm” mai multe
interfeţe. Acest lucru este folositor atunci când dorim sǎ afirmǎm cǎ “X este un A, un
interface Fighter {
void fight();
interface Swimmer {
void swim();
interface Flyer {
void fly();
class ActionCharacter {
public void fight() {}
Flyer {
fighter.fight();
swimmer.swim();
}
static void callFlyer(Flyer flyer) {
flyer.fly();
character.fight();
}
Se observǎ cǎ Hero combinǎ clasa ActionCharacter cu interfeţele Swimmer etc.
Acest lucru se realizeazǎ specificând prima dată clasa concretǎ (sau abstractǎ)
Combinarea unor interfeţe care conţin o metodǎ cu acelaşi nume este posibilǎ doar
dacǎ metodele nu au tipuri întoarse diferite şi aceeaşi listǎ de argumente. Totuşi este
acelaşi nume deoarece acest lucru poate duce la confuzii evidente (sunt amestecate
Extinderea interfeţelor
Se pot adǎuga cu uşurinţǎ metode noi unei interfeţe prin extinderea ei într-o altǎ
interfaţǎ:
interface Monster {
void menace();
void destroy();
}
Deoarece câmpurile unei interfeţe sunt automat static şi final, interfeţele sunt un mod
O clasă Java poate extinde doar o clasă părinte. Moştenirea multiplă nu este
permisă. O interfaţă nu este o clasă, şi aceasta poate extinde mai multe interfeţe
părinte. Cuvântul extends e folosit o singură dată, iar interfeţele părinte sunt
declarate într-o listă separată prin virgulă. De exemplu, dacă avem o interfaţă Hochei
cu valori neconstante. Câmpurile fiind statice, ele vor fi iniţializate prima oarǎ când
Exemplu Practic
O clasă nu poate extinde 2 clase. Să presupunem că 2 clase extind o superclasă
Dacă o altă clasă ar extinde ambele aceste clase, această clasă ar moșteni 2 metode
turn() diferite – lucru imposibil. Și dacă am vrea să apelăm această metodă, care din
care sunt legate logic și controlul vizibilității uneia din cadrul celorlalte.
clasei. Asta face ca o clasa internă sa poata avea acces la toți membrii clasei de care
aparține (outer class), inclusiv cei private. În plus, aceasta poate avea modificatorii
runtime printr-o instanță a clasei externe (la fel ca metodele și variabilele ne-statice).
Compilatorul creează fișiere .class separate pentru fiecare clasă internă, în exemplul
permisă.
class Outer {
class Inner {
private int i;
this.i = i;
return i;
return in;
}
System.out.println(in1.value());
System.out.println(in2.value());
}
În exemplul de mai sus, o dată ce avem o instanță a clasei Outer, sunt folosite două
instanță;
Dintr-o clasă internă putem accesa referința la clasa externă (în cazul nostru Outer)
Outer.this;
orice identificatori de acces, spre deosebire de clasele top-level Java, care pot fi doar
public sau package-private. Ca urmare, clasele interne pot fi, în plus, private și
interface Hidden {
class Outer {
this.i = i;
return i;
return in;
}
public class Test {
instanta HiddenInner
System.out.println(in3.value());
Observați definirea interfeței Hidden. Ea este utilă pentru a putea asocia clasei
eronate de a instanția HiddenInner. Cum clasa internă a fost declarată private, acest
Totuși, design-ul claselor interne este destul de complet și există modalităţi mai
“obscure” de a le folosi: clasele interne pot fi definite și în cadrul metodelor sau ale
Singurii modificatori care pot fi aplicați acestor clase sunt abstract și final (binențeles,
nu amândoi deodată).
interface Hidden {
class Outer {
return i;
System.out.println(in3.value());
creat pentru metoda respectivă, ceea ce face ca ele să nu fie existe la fel de mult cât
clasa internă. Dacă variabila este declarată final, atunci la runtime se va stoca o
class AlterStudent {
public void alterStudent() {
s.name = ... // OK
interface Hidden {
class Outer {
if (i == 11) {
class BlockInner implements Hidden {
return i;
return null;
În acest exemplu, clasa internă BlockInner este defintă în cadrul unui bloc if, dar
compilare clasa va fi creată indiferent care este valoarea de adevăr a condiției if.
Clase anonime
Există multe situații în care o clasă internă este instanțiată într-un singur loc (si este
folosita prin upcasting la o clasă de bază sau interfață), ceea ce face ca numele
clasei să nu mai fie important, iar tipul ei poate fi un subtip al unei clase sau o
În Java putem crea clase interne anonime (făra nume) ca în exemplul următor:
interface Hidden {
class Outer {
return i;
}
};
System.out.println(in3.value());
… } reprezintă următoarele:
acest obiect este instanțiat imediat după return, folosind new (referința
Constructori
Clasele anonime nu pot avea constructori din cauză că nu au nume (nu am ști cum
clasele normale acest lucru era posibil prin apelarea explicită, în prima linie din
clasele interne acest lucru se obține prin transmiterea parametrilor către constructorul
new Student("Andrei") {
// ...
există doar în contextul unei instanțe a clasei exterioare, astfel că poate accesa
claselor exterioare, clasele interne pot avea modificatorii disponibili pentru metode și
variabile, dintre care și static (clasele exterioare nu pot fi statice!). Așa cum pentru a
accesa metodele și variabilele statice ale unei clase nu este nevoie de o instanță a
aceteia, putem obține o referință către o clasă internă fără a avea nevoie de o
Pentru a înțelege diferența dintre clasele interne statice și cele nestatice trebuie să
reținem următorul aspect: clasele nestatice țin legătura cu obiectul exterior în vreme
interne
nu putem accesa câmpuri nestatice ale clasei externe din clasă internă (nu
class Outer {
class NonStaticInner {
private int i = 1;
return k;
}
public class Test {
incorectă.
pentru a grupa clasele, dacă o clasă internă statică A.B este folosită doar de
altei clase, și cuprinde atât inner classes cât și clasele statice interne. De aceea,
claselor statice interne li se spune static nested classes și nu static inner classes.
exterioare, moștenirea unei clase interne este puțin mai complicată decât cea
class WithInner {
class Inner {
public void method() {
InheritInner(WithInner wi) { // OK
wi.super();
ii.method();
(WithInner)
putem extinde decât o singură clasă. Putem defini însă clase interioare. Acestea
pot moșteni orice clasă și au, în plus, acces la obiectul clasei exterioare.
evenimente într-un sistem bazat pe evenimente. Unul din cele mai importante
sisteme de acest tip este GUI (graphical user interface). Bibliotecile Java Swing,
AWT, SWT sunt arhitecturi de control care folosesc intens clase interne. De
următor:
implementata e ActionListener
numClicks++;
});
următor:
4. Checkout
ADD KEYCHAINS
4. Checkout
VIEW ORDER
1. Add Keychains to Order
4. Checkout
CHECKOUT
Va trebui să creaţi metode pentru fiecare dintre cele patru opţiuni din meniu.
4. Checkout
4. Checkout
Please enter your choice: 2
4. Checkout
4. Checkout
CHECKOUT
breloace, şi unul pentru a stoca preţul pentru un breloc. Preţul ar trebui să fie de 10
RON.
returnat void. Va afişa, pe 3 linii diferite, numărul de breloace din comandă, preţul
void. Va cere utilizatorului numele acestuia pentru a face corect livrarea, va afişa
Cerinţa
Să se implementeze enum-ul TipBreloc.
AUR,
ARGINT,
TINICHEA
}
// denumire
// pret
// tip
Pentru operaţiile de add şi remove ţineţi cont că pe lângă numărul de breloce veţi
Pentru vizualizare, veţi afişa o listă cu toate breloacele comandate, preţul parţial
1. Completaţi codul acolo unde vă este indicat astfel încât să schimbaţi Pokemonul
import java.util.Scanner;
int x;
do {
System.out.println("EXCHANGE POKEMON\n");
System.out.print("> ");
x = keyboard.nextInt();
Pokemon in slot x
} while ( x> 0 );
selectaţi.
import java.util.Scanner;
public class PokeTrader2 {
int a;
int b;
do {
System.out.println("EXCHANGE POKEMON\n");
pokeParty[i]);
System.out.print("\nChoose a Pokemon (or -1 to quit). =>
");
a = keyboard.nextInt();
if (a>= 0) {
b = keyboard.nextInt();
reordona valorile din array astfel încât să fie în ordine crescătoare (de la mic la
mare).
public class SortingValues {
int[] arr = { 45, 87, 39, 32, 93, 86, 12, 44, 75, 50 };
System.out.print("before: ");
System.out.println();
/*
for ( ; ; ) {
for ( ; ; ) {
if ( ) {
// swap the values in two slots
*/
System.out.print("after : ");
System.out.println();
4. Implementaţi metoda sortării prin selecţie pentru următorul cod. Vă puteţi folosi de
informaţiile următoare:http://www.algolist.net/Algorithms/Sorting/Selection_sort
import java.util.Random;
public class SelectionSort {
int i;
arr[i] = 1 + r.nextInt(100);
// Display it
System.out.print("before: ");
System.out.println();
// Sort it
selectionSort(arr);
System.out.print("after : ");
Recursivitate
Recursivitatea este o tehnică prin care putem divide problema în subprobleme de
acelaşi tip. Putem folosi exemplul de mai jos pentru a o înţelege mai bine.
Calculul factorial
Factorial de n (notat n!) reprezintă produsul numerelor întregi între 1 şi n. De
exemplu, 5! = 1 * 2 * 3 * 4 * 5 = 120.
Recursivitatea este o tehnică prin care putem calcula factorialul. Mai exact, 5! = 4! *
mai departe. Procesul descris mai sus, ar putea dura la infinit, neavând un caz de
bază la care să ne oprim. Acest caz de bază ne defineşte când ar trebui oprit
if (n <= 1)
return 1;
else
cazul curent. Apoi, la întoarcerea la problemă, cazurile de bază (este posibil să avem
recirsivitatea foloseşte stiva pentru a stoca toate stările tuturor apelurilor recursive
active. Mărimea stivei poate fi foarte mare, dar este mereu limitată. Aşadar, apelurile
recursive prea adânci pot rezulta în Stack Overflow. Pentru a rezolva această
Assignment
1. Dacă avem un n care este mai mare sau egal ca un, să se calculeze factorial de n,
bucle).
factorial(1) = 1
factorial(2) = 2
factorial(3) = 6
calculăm recursiv numărul total de urechi de la toţi iepuraşii (fără bucle sau înmulţiri).
bunnyEars(0) = 0
bunnyEars(1) = 2
bunnyEars(2) = 4
Hint: În primul rând stabiliţi cazul de bază (bunnies == 0), şi returnaţi 0. Altfel, faceţi
recursivă. Primele două valori sunt 0 şi 1 (două cazuri de bază). Fiecare număr
ulterior este suma a două valori anterioare, iar secvenţa completă este 0, 1, 1, 2, 3,
5, 8, 13, 21, etc. Definiţi o metodă recursivă fibonacci(n) care să întoarcă al n-lea
fibonacci(0) = 0
fibonacci(1) = 1
fibonacci(2) = 1
(1, 3, …) au 2 urechi normale. Iepuraşii pari (2, 4, …) putem spune că au trei urechi,
deoarece fiecare a ridicat o lăbuţă. Întoarceţi recursiv numărul de "urechi" din linia de
bunnyEars2(0) = 0
bunnyEars2(1) = 2
bunnyEars2(2) = 5
5. Avem un triunghi construit din cărămizi. Cel mai de sus rând are o cărămidă, al
doilea rând are 2 cărămizi, al treilea rând are 3 cărămizi, şi aşa mai departe. Calculaţi
recursiv (fără bucle sau multiplicări) numărul total de cărămizi într-un asemenea
triangle(0) = 0
triangle(1) = 1
triangle(2) = 3
6. Dacă avem un număr pozitiv întreg n, calculaţi recursiv suma cifrelor sale (fără a
folosi bucle). Ţineţi cont că operaţia modulo (%) 10 ne va da cifra cea mai din
dreapta (126 % 10 este 6), iar diviziunea (/) la 10 va şterge cifra cea mai din dreapta
sumDigits(126) = 9
sumDigits(49) = 13
sumDigits(12) = 3
7. Dacă avem un număr pozitiv întreg n, calculaţi de câte ori apare cifra 7. De
exemplu, 717 are trebui să dea rezultatul 2. Calculaţi recursiv, fără a folosi bucle.
Ţineţi cont că operaţia modulo (%) 10 ne va da cifra cea mai din dreapta (126 % 10
este 6), iar diviziunea (/) la 10 va şterge cifra cea mai din dreapta (126 / 10 este 12).
count7(717) = 2
count7(7) = 1
count7(123) = 0
8. Dacă avem un număr pozitiv întreg n, calculaţi de câte ori apare cifra 8, cu
excepţia faptului că dacă cifra 8 este urmată imediat de un alt 8, o vom număra de
două ori. Deci 8818 va da rezultatul 4. Calculaţi recursiv, fără a folosi bucle. Ţineţi
cont că operaţia modulo (%) 10 ne va da cifra cea mai din dreapta (126 % 10 este 6),
iar diviziunea (/) la 10 va şterge cifra cea mai din dreapta (126 / 10 este 12).
count8(8) = 1
count8(818) = 2
count8(8818) = 4
recursiv (fără bucle) valoarea bazei la puterea n, astfel încât powerN(3, 2) este 9 (3
la pătrat).
powerN(3, 1) = 3
powerN(3, 2) = 9
powerN(3, 3) = 27
10. Se dă un şir de caractere, să se calculeze recursiv (fără bucle) numărul de
countX("xxhixx") = 4
countX("xhixhix") = 3
countX("hi") = 0
numărul 6. Vom folosi o convenţie pentru a considera doar o parte din array care
porneşte de la un index dat. În acest mod, un apel recursiv poate trimite index + 1 ca
array6({6}, 0) = true
12. Afişaţi următoarea formă din steluţe folosind o metodă recursivă care desenează
un rând de steluţe:
*****
****
***
**
*
13. Creaţi o metodă care să deseneze un pătrat într-un pătrat, în alt pătrat în mod
recursiv.
14. Creaţi o metodă care să deseneze un triunghi, într-un pătrat, intr-un pentagon,
15. Calculaţi cel mai mare divizor comun între 2 numere, folosind algoritmul lui
Euclid.
cmmdc(5,5) = 5
16. Un ArrayList poate contine elemente de tip ArrayList sau Integer. Dacă elementul
este de tip ArrayList, elementele sale pot fi tot de tip ArrayList sau Integer. Dacă un
element al acestuia este de tip ArrayList, elementele acestuia din urmă pot fi tot de
tip ArrayList sau Integer. Tot așa. La un moment dat, un ArrayList va conține doar
(nedefinit).
17. O metoda primeste un array de numere naturale. Sa se creeze o functie (metodă)
returneze suma divizorilor. Indiciu: se merge pas cu pas înapoi scăzând 1. Dacă e
0, returnăm 0.
12
21
Permutari de 3 elemente
123
132
213
231
312
321
Permutari de n elemente
ArrayList sunt indexate asemenea unui array, fiind 0-based. Într-un ArrayList se pot
Spre deosebire de array, ArrayList poate conține numai obiecte. (nu și primitive)
Metode uzuale
Modifier and Type Method and Description
boolean add(E e) Appends the specified element to the end of this list.
void add(int index, E element) Inserts the specified element at the specified position in
this list.
boolean addAll(Collection<? Appends all of the elements in the specified collection to
extends E> c) the end of this list, in the order that they are returned by
the specified collection's Iterator.
boolean addAll(int index, Inserts all of the elements in the specified collection into
Collection<? extends E> c) this list, starting at the specified position.
void clear() Removes all of the elements from this list.
Object clone() Returns a shallow copy of this ArrayList instance.
boolean contains(Object o) Returns true if this list contains the specified element.
void ensureCapacity(int Increases the capacity of this ArrayList instance, if
minCapacity) necessary, to ensure that it can hold at least the number
of elements specified by the minimum capacity
argument.
E get(int index) Returns the element at the specified position in this list.
int indexOf(Object o) Returns the index of the first occurrence of the specified
element in this list, or -1 if this list does not contain the
Modifier and Type Method and Description
element.
boolean isEmpty() Returns true if this list contains no elements.
Iterator<E> iterator() Returns an iterator over the elements in this list in proper
sequence.
int lastIndexOf(Object o) Returns the index of the last occurrence of the specified
element in this list, or -1 if this list does not contain the
element.
ListIterator<E> listIterator() Returns a list iterator over the elements in this list (in
proper sequence).
ListIterator<E> listIterator(int Returns a list iterator over the elements in this list (in
index) proper sequence), starting at the specified position in the
list.
E remove(int index) Removes the element at the specified position in this list.
boolean remove(Object o) Removes the first occurrence of the specified element
from this list, if it is present.
boolean removeAll(Collection<?> Removes from this list all of its elements that are
c) contained in the specified collection.
protected void removeRange(int Removes from this list all of the elements whose index is
fromIndex, int toIndex) between fromIndex, inclusive, and toIndex, exclusive.
boolean retainAll(Collection<?> Retains only the elements in this list that are contained in
c) the specified collection.
E set(int index, E element) Replaces the element at the specified position in this list
with the specified element.
int size() Returns the number of elements in this list.
List<E> subList(int fromIndex, Returns a view of the portion of this list between the
int toIndex) specified fromIndex, inclusive, and toIndex, exclusive.
Object[] toArray() Returns an array containing all of the elements in this list
in proper sequence (from first to last element).
<T> T[] toArray(T[] a) Returns an array containing all of the elements in this list
in proper sequence (from first to last element); the
runtime type of the returned array is that of the specified
array.
void trimToSize() Trims the capacity of this ArrayList instance to be the
list's current size.
//aduagarea de elemente
lista.add(computer1); //pe poziția 0
System.out.println(lista);
pozitia 3 și îl returnează
Iterare
Un ArrayList se poate itera în 3 moduri:
1. cu for classic
if (lista.get(i).getMarca().equals(“Acer”)){
lista.remove(i);
}
}
2. cu for-each
if (computer.getMarca().equals(“Toshiba”)){
lista.remove(computer);
Pentru a sterge un element dinamic din lista, in timp ce parcurgem lista, nu sunt,
totusi, indicate variantele de mai sus, întrucât pot apărea crashuri, ci varianta cu
iterator.
in API ListIterator.
Nu apelam metoda next() sau previous() decat daca sunt siguri ca exista un element
while (iter.hasNext()){
iter.next();
while (iter.hasNext()){
if (iter.next().getMarca().equals(“HP”) {
returnat de iter.next()
computere.add(c2);
computere.add(c3);
computere.add(c4);
computere.remove(altComputer);
computere.
Exerciţiu
Se consideră clasa Avion cu următoarele câmpuri: companie, marca+model, tip de
7. Stergeți un avion.
Assignment
1. Creaţi un ArrayList care reţine valori de tipul Integer. Adăugaţi în acesta 10 copii
2. Creaţi un ArrayList care reţine valori de tipul Integer. Adăugaţi în acesta 10 copii
De data aceasta, folosiţi o buclă pentru a umple array-ul cu valori şi apoi pentru a-l
numere aleatoare, cu valori între 1 şi 100. Apoi afişaţi conţinutul acestui ArrayList.
Folosiţi o buclă pentru a genera valori. Pentru afişare puteţi folosi metodă simplă,
fără buclă:
System.out.println("ArrayList: " +
whateverYourArrayListVariableIsCalled);
4. Creaţi un ArrayList care să reţină valori de tipul Integer. Populaţi lista cu 1,000 de
valori aleatoare, fiecare între 10 şi 99. Apoi afişaţi conţinutul acestui ArrayList pe
toate elementele din primul ArrayList într-un alt ArrayList de aceeaşi dimensiune.
Afişaţi apoi valorile din cei doi ArrayList folosind modalitatea dorită.
numere aleatoare între 1 şi 100. Copiaţi fiecare valoare din ArrayList într-un alt
ArrayList cu aceeaşi capacitate. Schimbaţi ultima valoare din primul ArrayList la -7.
Creaţi un ArrayList care reţine valori de tipul Integer şi populaţi-l cu valori aleatoare
între 1 şi 50. Afişaţi aceste valori pe ecran, şi apoi cereţi utilizatorului un număr întreg
între aceste valori. Căutaţi în ArrayList numărul introdus şi dacă acesta este prezent,
afişaţi un mesaj. Nu este necesar să afişaţi un mesaj dacă valoarea nu a fost găsită.
Dacă găsiţi de mai multe ori numărul respectiv, nu este nicio problemă dacă mesajul
Creaţi un ArrayList care să reţină valori de tipul Integer şi adăugaţi numere aleatoare
între 1 şi 50. Afişaţi aceste valori pe ecran, apoi cereţi utilizatorului un număr întreg.
Căutaţi în ArrayList, şi dacă itemul respectiv este prezent, afişaţi un singur mesaj
(chiar dacă este prezent de mai multe ori). Dacă valoarea nu se află în ArrayList,
8. Unde există?
Creaţi un ArrayList care să reţină valori de tipul Integer şi umpleţi-l cu numere
aleatoare între 1 şi 50. Afişaţi aceste valori şi cereţi utilizatorului un număr întreg.
Căutaţi în ArrayList şi dacă gasiţi acest număr, afişaţi poziţia lui. Dacă numărul nu
este în ArrayList, afişaţi un mesaj corenspunzător. Dacă numărul apare de mai multe
ori, afişaţi mesajul cu poziţia de câte ori este necesar, sau afişaţi o singură dată
Integer. Populaţi ArrayList-ul cu numere aleatoare între 1 şi 100. Afişaţi valorile din
ArrayList. Folosiţi o căutare liniară pentru a găsi valoarea maximă din ArrayList şi
afisaţi-o.
numere aleatoare între 1 şi 100. Afişaţi valorile pe ecran. Folosiţi o căutare liniară
11. Sortare.
Creaţi un ArrayList care să reţină valori de tipul Integer. Populaţi ArrayList-ul cu valori
aleatoare între 10 şi 99. Afişaţi valorile din ArrayList pe ecran. Apoi, folosind o
metodă de sortare la alegere, aranjaţi valorile de la cel mai mare la cel mai mic şi
în ArrayList (toate cu litere mici) într-o oarecare ordine. Afişaţi-le pe ecran. Folosind o
Creaţi un ArrayList care conţine valori de tipul String. Lăsaţi utilizatorul să introducă
valorile prin folosirea metodei nextLine() din Scanner. Folosind String.split(), împărţiţi
marca (String)
model (String)
package pack2;
frecventaProcesor) {
super();
this.marca = marca;
this.memorieRam = memorieRam;
this.frecventaProcesor = frecventaProcesor;
}
//getteri si setteri
package pack2;
}
}
Din punct de vedere al obiectelor ele nu sunt egale. Ele sunt doua obiecte diferite pe
Dacă apelăm:
System.out.println(computer1);
System.out.println(computer2);
pack2.Computer@1db9742
pack2.Computer@106d69c
Dacă acum în clasa Computer suprascriem metoda toString() din clasa Object: (Right
@Override
memorieRam
+ ", frecventaProcesor=" +
frecventaProcesor + "]";
System.out.println(computer1);
System.out.println(computer2);
ne va da:
Au valori egale, însă asta, în continuare, nu înseamnă că sunt obiecte egale. Sunt 2
if (computer1 == computer2){
obiect");
} else {
System.out.println("Sunt obiecte diferite.");
//sau
//sau
System.out.println(bool);
Obținem:
false
false
Cum putem face să scriem un bloc de cod care să afișeze true dacă cele două
if (computer1.getMarca().equals(computer2.getMarca())
&& computer1.getMemorieRam() ==
computer2.getMemorieRam()
&& computer1.getFrecventaProcesor() ==
computer2.getFrecventaProcesor()) {
");
} else {
fel.");
Acum obținem:
Cele doua computere sunt la fel.
În principiu ne-am atins scopul. Doar că în felul acesta de fiecare dată când vrem să
asemenea, dacă suntem un magazin care vinde 100 de obiecte diferite (computere,
telefoane, tablete, procesoare, cabluri, routere, swithcuri etc) metoda noastră main()
mergem peste tot în aplicație și să căutăm toate locurile în care am făcut această
verificare a similariății a două computere. Dacă uităm într-un singur loc să facem
În fond, poate vreodată, vom scrie un alt program care să folosească clasa
Copy + Paste în Package Explorer (coloana din stânga) sau muta clase dintr-un
Și în fond, ce trebuie să știe clasa Main toată bucătăria internă a clasei Computer?
Nu era mai simplu dacă clasa Computer avea o metodă care să returneze dacă 2
În clasa Computer:
if ( this.marca.equals(altComputer.marca)
&& this.memorieRam == altComputer.memorieRam
&& this.frecventaProcesor ==
altComputer.frecventaProcesor){
} else {
similare.";
System.out.println(computer1.suntSimilare(computer2));
Obținem:
&& this.memorieRam ==
altComputer.memorieRam
&& this.frecventaProcesor ==
altComputer.frecventaProcesor) {
return true;
} else {
return false;
System.out.println( computer1.suntSimilare(computer2)
);
//sau
System.out.println( bool2);
Obținem:
true
Toate clasele moștenesc automat clasa Object – care este superclasa tuturor
În mod normal, această metodă compară adresele din memorie a două obiecte,
returnând true dacă cele două obiecte au aceeași adresă (adică sunt unul și același
obiect) și false dacă au adrese diferite (adică sunt două obiecte distincte, care pot
Hai să vedem:
System.out.println(computer1.equals(computer2));
System.out.println(computer2.equals(computer1));
Obținem:
false
false
System.out.println( str1.equals(str2));
Obținem:
true
if (this.marca.equals(altComputer.marca)
&& this.memorieRam == altComputer.memorieRam
&& this.frecventaProcesor ==
altComputer.frecventaProcesor) {
return true;
}//end if
Computer
return false;
Pentru că cei de la Sun când au creat Java (care ulterior a fost cumpărată de Oracle)
Noi, însă, trebuie să facem verificarea, dacă obiectul pe care îl primește metoda este,
apelează.
System.out.println(computer1.equals(computer2));
Obținem:
true
System.out.println(computer1.equals(computer4));
Obținem:
false
Dar dacă computerul pe care îl pasăm ca argument în metodă este null? Adică
nenstanțializat?
System.out.println( computer1.equals(computer3));
Obținem:
false
Metoda funcționează.
ArrayList
Metodele contains(), indexOf() și remove() se ajută de equals().
În main()
ArrayList<Computer>();
computere.add(c1);
Am adăugat 5 computere.
Cum căutăm dacă lista nostră conține un anumit computer? Pentru c1 este simplu:
System.out.println(computere.contains(c1));
Dar cum facem pentru celelalte? Că nu avem vreo variabilă de referință către ele.
Putem parcurge toată lista de computer și verifica pentru fiecare în parte dacă
computerul nostru se regăsește printre acestea, adică verificănd dacă marca e egală,
1600);
dacă obiectul nu se regăesște efectiv în listă, va returna true, dacă există un obiect
În main()
computere.contains(computerDeLucru);
Obținem
true
vedea API) returnează indexul primei apariții în listă a respectivului obiect pe care îl
căutăm.
System.out.println(index);
Obținem:
În main()
computere.remove(computerDeLucru);
System.out.println(computere);
Obținem:
computere.contains(computerDeLucru));
Obținem:
false
similare, accesate printr-un index. Structurile de date de tipul array pot fi stocate
array static are o mărime constantă şi există pe toată durata de rulare a aplicaţiei.
Tipul de array dinamic este creat în momentul rulării programului şi pot fi ştersi când
nu mai sunt necesari. Aceştia pot fi destul de mari, chiar depăşind memoria fizică. Nu
putem însă modifica mărimea acestora, decât prin aplicarea următorului mecanism:
se numesc şi vectori de mărime fixă. Dar, ne putem crea un simplu mecanism prin
imaginar în două părţi. Prima parte conţine datele efective şi a doua spaţiu liber.
Când un nou element este adăugat, spaţiul liber este redus şi vice-versa. Această
abordare rezultă într-o risipă a spaţiului liber, dar avem toate avantajele unui vector şi
capabilitatea de a-i schimba mărimea dinamic. Mai jos sunt prezentate câteva definiţii
Vectorul dinamic are o capacitate, care conţine numărul maxim de elemente ce pot fi
din mai multe numere introduse de utilizator. Alocăm un spaţiu pentru a reţine 15
elemente, dar utilizatorul introduce doar 5 numere. Aşadar, capacitatea acestui array
este de 15 elemente, dar mărimea logică doar de 5. Când vectorii dinamici nu mai au
spaţii goale, va trebui să fie mărit prin crearea unui nou vector mai mare şi prin
H e l l o !
72 101 108 108 111 33
import java.util.Scanner;
int n = 0;
int value = 0;
value = keyboard.nextInt();
keyboard.nextLine();
if (value != -1) {
arr[n] = value;
n++;
if (n == 0) {
} else {
if (arr[i] <minimum)
minimum = arr[i];
Coada de priorităţi
În practică, avem deseori de a face cu priorităţile. De exemplu, într-o listă de TO-DO,
fiecare task are asociată o anumită importanţă. Este absolut necesar să ne luăm
maşina de la service (cea mai mare prioritate), şi este posibil să ne uităm la un film
(cea mai joasă prioritate). În afară de exemplele din viaţa reală, multe task-uri din
calculator funţionează pe baza priorităţilor. Cel mai uzual exemplu este algoritmul lui
Dijkstra pentru găsirea celei mai rapide căi. Lista de priorităţi ne permite să lucrăm cu
priorităţile şi vom considera că pentru itemele e1, e2: e1 < e2 înseamnă că e1 are o
Operaţii
PriorityQueue create() - crează o coadă de priorităţi goală
Stiva
Stiva este o structură de date fundamentală şi este folosită în mulţi algoritmi şi
aplicaţii, ca de exemplu:
implicit în recursivitate
etc
În primul rând vom descrie structura de date abstractă stiva şi apoi o vom
exemplifica.
boolean isEmpty(Stack s)
push(Stack s, Item e)
Item peek(Stack s)
pop(Stack s)
destroy(Stack s)
distruge stiva s
Axiome
stivele noi create sunt goale
cheie (şi totodată valoarea asociată cu aceasta) şi să căutăm o cheie după valoare.
Valorile nu sunt necesare să fie unice. Un exemplu simplu este dicţionarul pentru
explicaţii. În acest exemplu, cuvintele sunt chei, iar explicaţiile lor sunt valorile.
Operaţii
Dictionary create()
boolean isEmpty(Dictionary d)
remove(Dictionary d, Key k)
destroy(Dictionary d)
şterge dicţionarul d
Hash Table
Hash table (sau hash map) este una din implementările posibile ale dicţionarului.
Acesta mapează practic chei unice la valori asociate. Din perspectiva implementării,
un hash table este o structură de tip array, care foloseşte funcţii hash pentru a face
conversia unei chei în indexul elementului din array, unde valoarea asociată este
regăsită.
Funcţii hash
Funcţiile hash sunt o parte importantă din tabelul hash. O funcţie hash este bună
funcţiei hash, necesare pentru un hash de calitate sunt detaliate mai jos. Principalul
motiv pentru care sunt foarte importante este că pot cauza coliziuni şi alte efecte
încărcare este rata între numărul de elemente stocate în array şi mărimea acestuia.
Hash table poate avea o mărime constantă sau poate fi redimensionat dinamic, când
ca tabelul să devină plin pentru a menţine numărul coliziunilor sub un anume nivel şi
Coliziuni
În cazul în care funcţia ne întoarce aceeaşi valoare hash pentru chei diferite, se
în tabel, pentru a face diferenţe între perechile cheie-valoare cu acelaşi hash. Există
mai multe modalităţi de rezolvare a coliziunilor. Practic, există două strategi diferite:
Adresarea închisă (hashing deschis). Fiecare slot din tabel conţine o legătură
către o altă structură de date, cum ar fi o listă simplu înlănţuită, care stochează
perechile cheie-valoare cu acelaşi hash. Când apare coliziunea, această structură
locaţie (de exemplu, următoarea disponibilă) pentru un slot liber. Tabelele hash,
tabelul este foarte plin (un factor de umplere de 0.7 sau mai mult).
coliziunile sunt rezolvate prin adresare deschisă şi mărimea tabelului este constantă.
Hash Table
Array-ul folosit la implementare are o dimensiune de 128 elemente, iar fiecare slot
conţine perechea cheie-valoare. Cheia este stocată pentru a diferenţia între perechile
Funcţia Hash
restul împărţirii la 128. Din perspectiva implementării, aceasta poate folosi operatorul
Rezolvarea coliziunilor
Pentru a rezolva coliziunile este folosită inserarea lineară. În cazul în care slot-ul
indicat de funcţia hash este deja ocupat, algoritmul încearcă să găsească un slot
Această implementare are un bug. Dacă nu mai există niciun loc liber, bucla care
caută un loc liber va rula la infinit. Acest lucru nu se va întâmpla în cazul unei
this.key = key;
this.value = value;
return key;
}
public int getValue() {
return value;
HashEntry[] table;
HashMap() {
table[i] = null;
}
public int get(int key) {
if (table[hash] == null)
return -1;
else
return table[hash].getValue();
Colecţii Java
Înainte de Java 2, existau clase precum Dictionary, Vector, Stack sau Properties care
Framework-ul pentru colecţii din Java a fost proiectat pentru a atinge următoarele
scopuri:
şi TreeSet ale acestor interfeţe ne sunt puse la dispoziţie pentru a le folosi, dar putem
Implementări, sau mai exact clase: Acestea sunt implementări concrete ale
Algoritmi: Acestea sunt metodele prin care facem diverse operaţii, cum ar fi
sunt polimorfici: mai exact, aceeaşi metodă poate fi folosită pe mai multe
Pe lângă colecţii, framework-ul defineşte câteva interfeţe şi clase pentru map. Map-
Framework-ul
Clasele care implementează interfața Set nu sunt ordonate (nu au index), dar
dicționar. Cheile sunt obiecte. Cheile nu pot avea duplicate și nu sunt ordonate
aleatoriu elementele.
Colecţia Descriere
Vector Primul tip de vector, din versiunea java 1.0. În versiunea 1.2 a fost
introdus în Collection Framework. Are metodele sincronizate pentru firele
de execuție.
ArrayList Un List tipic. Nu are metodele sincronizate.
LinkedList Asemenea lui ArrayList dar fiecare element are câte o referință către
elementul precendent și câte una către elementul următor. Este ideal pentru
inserarea sau ștergerea de elemente la mijlocul unei liste, la listele mari.
Stack Elementele formează o stivă. Nu poate fi accesat un element, decât dacă
Colecţia Descriere
sunt scoase cele de deasupra lui.
HashSet Un Set tipic. Nu are metodele sincronizate.
LinkedHashSet Are tehnologie asemenea lui LinkedList, elementele au 2 referințe: către
elementul precendent și cel următor.
TreeSet Elementele sunt sortate după ordinea naturală (în cazul wrapper classes
sau stringuri) sau după metodologia scrisă de programator. Un nou
element se așează din start la locul lui.
HashMap Un Map tipic. Nu are metodele sincronizate.
LinkedHashMap Moștenește pe HashMap. Are tehnologie asemenea lui LinkedList,
elementele au 2 referințe: către elementul precendent și cel următor.
Hashtable Primul tip de dicționar din versiunea 1.0. În versiunea 1.2 a fost introdus în
Collection Framework. Are metodele sincronizate pentru firele de
execuție.
TreeMap Cheile sunt sortate după ordinea naturală (în cazul wrapper classes sau
stringuri) sau după metodologia scrisă de programator. Un nou element se
așează din start la locul lui.
Interfeţele pentru colecţii
Framework-ul de colecţii defineşte o serie de interfeţe. Această secţiune descrie pe
Collection
List
elemente.
Set
elemente unice.
SortedSet
Map.Entry
SortedMap
Enumeration
ca succesor Iterator.
Clasele pentru Colecţii
Java ne oferă o serie de clase pentru colecţii care implementează interfeţele
Collection. Unele clase ne dau implementare completă care poate fi folosită ca atare,
iar unele sunt clase abstracte pentru care avem o implementare schelet ce poate fi
AbstractCollection
AbstractList
AbstractSequencialList
LinkedList
AbstractSequencialList.
ArrayList
AbstractSet
HashSet
LinkedHashSet
elementelor.
TreeSet
AbstractMap
HashMap
TreeMap
WeakHashMap
LinkedHashMap
elementelor.
IdentityHashMap
documentelor.
Clasele AbstractCollection, AbstractSet, AbstractList, AbstractSequencialList şi
Vector
Stack
first-out (LIFO).
Dictionary
Hashtable
concretă a Dictionary.
Properties
BitSet
Creează un tip special de array care reţine valori de tipul bit. Acest
Unele din metode pot arunca ClassCastException, care apare când încercăm să
EMPTY_MAP.
Dar, dacă avem nevoie de o sortare de ocazie, putem transforma Set-ul într-un List
iterator(). Scrie mai jos că metoda iterator() este moștenită de la interfața List. Totuși,
o putem folosi. Cum o putem folosi? Folosim direct metoda din interfața List? Putem
observăm că practic sunt mai multe clase în această ierarhie de clase și interfețe.
Genericitate
Metodele generice în Java ne permit aplicarea aceluiaşi algoritm pentru mai multe
asemănătoare.
Metode Generice
Putem scrie o singură declaraţie de metodă generică care poate fi apelată cu
secţiune delimitată prin diamant (< >) care trebuie scris întainte de tipul returnat.
Fiecare secţiune conţie unul sau mai multe tipuri separate prin virgule. Un tip
generic al parametrului.
Corpul unei metode generice este declarat ca la oricare altă metodă. Tipul
parametric poate fi doar un tip referinţă, nu şi primitiv (int, double, char, etc).
Exemplu
Următorul exemplu ilustrează modul în care putem afişa un array printr-o metodă
generică:
public class GenericMethodTest {
System.out.println();
123456
1.12.23.34.4
Array characterArray contains:
H E L L O
apelul metodei. De exemplu, o metodă care foloseşte doar numere, ar putea necesita
doar instanţe ale clasei Number şi ale subclaselor ei. Pentru această restricţionare
Exemplu
Următorul exemplu ilustrează modul în care extends este folosit la modul general,
interfeţe). Acest exemplu foloseşte o metodă generică pentru a întoarce cel mai mare
if (z.compareTo(max)> 0) {
maximum(3, 4, 5));
}
}
Maximum of 3, 4 and 5 is 5
Clase generice
Declaraţia unei clase generice este asemănătoare cu declaraţia unei clase normale,
generice poate conţine unul sau mai mulţi parametrii separaţi prin virgule. Aceste
clase sunt cunoscute sub denumirea de clase parametrizate sau tipuri parametrizate
Exemplu
private T t;
public void add(T t){
this.t = t;
public T get(){
return t;
integerBox.add(newInteger(10));
integerBox.get());
IntegerValue: 10
StringValue: HelloWorld
ar.add("sas");
ar.add(new Integer(4));
ar.add(new Double(345.56));
// e ca si cum am fi scris:
// ArrayList<Object> ar = new
ArrayList<Object>();
rulare
// solutia:
Computere.
Double>();
Clase parametrizate
Putem crea clase parametrizate (generice) care pot avea atribute diferite în funcție
private A atribut;
this.atribut = atribut;
public A getAtribut(){
return this.atribut;
<String>();
cg1.setAtribut (“Hello”);
System.out.println(cg1.getAtribut());
ClasaMeaGenerica<Computer>();
cg2.setAtribut(new Computer());
System.out.println(cg2.getAtribut());
Iteratorul
De multe ori este necesar să parcurgem elementele unei colecţii. De exemplu, vrem
să afişăm fiecare element. Cea mai uşoară modalitate este să folosim un iterator,
care este un obiect ce implementează una din interfeţele Iterator sau ListIterator.
Iterator ne permite să ciclăm prin colecţie, pentru a prelua sau şterge elemente.
modificarea elementelor.
iterator de la începutul colecţiilor. Prin folosirea acestui obiect, putem accesa fiecare
Pregătim o buclă ce verifică hasNext(). Aceasta va rula atât timp cât hasNext()
întoarce true.
Exemplu
Exemplul de mai jos demonstrează atât Iterator cât şi ListIterator. Acesta foloseşte
un obiect de tipul ArrayList, dar principiul general se aplică la orice tip de colecţie.
Desigur, ListIterator este disponibil doar pentru acele colecţii care implementează
interfaţa List.
import java.util.*;
al.add("C");
al.add("A");
al.add("E");
al.add("B");
al.add("D");
al.add("F");
System.out.println();
while(litr.hasNext()) {
litr.set(element + "+");
itr = al.iterator();
while(itr.hasNext()) {
System.out.println();
while(litr.hasPrevious()) {
System.out.println();
Comparatorul
Atât TreeSet cât şi TreeMap stochează elementele sortate. Dar, comparatorul este
cel care determină excat ce înseamnă să fie sortat. Interfaţa Comparator defineşte
Metoda compare()
Metoda întoarce o valoare pozitivă dacă obj1 este mai mare ca obj2.
O valoare negativă este întoarsă dacă obj1 este mai mic ca obj2.
Metoda equals()
Această metodă întoarce true dacă obj şi obiectul care a apelat metoda sunt
Dog() {
Dog(String n, int a) {
name = n;
age = a;
return age;
return (this.name).compareTo(d.name);
}
}
System.out.println(" ");
În ordine crescătoare
Practic implementăm noi metodele: Arrays.sort(int[]
Algortimi de sortare
Varianta 1: Utilizînd o buclă for parcurgem vectorul si luam valoarea cea mai mică și
o punem pe prima poziție într-un alt vector. Modificăm valoarea la cea mai mare
Varianta 2: folosind metoda bubbling. Se compara valorile din primii doi indexi. Dacă
sunt în ordine, se inversează. Tot așa până la final. Astfel, valorile urcă, asemenea
bulelor de soda într-un pahar. (bubbling). Se parcurge din nou vectorul de mai multe
ori, până când nu mai au loc inversări. Pentru a ști dacă nu au mai avut loc inversări
Collections.sort(ArrayList arraylist)
Această sortare se face după ordinea naturală a elementelor Este posibilă pentru că
Dar dacă vrem să sortăm niște computere sau orice alte clase, trebuie să îi spunem
int compareTo(T o) Compares this object with the specified object for order.
...........
@Override
return -1;
//trebuie sa returnam 0
return 0;
} else {
return 1;
.........
Collections.sort(listaComputere);
int compare(T o1, T o2) Compares its two arguments for order.
import java.util.Comparator;
@Override
// trebuie sa returnam 0
return 0;
} else {
return 1;
Apoi scriem:
.......
Comparator ramComparator = new RamComparator();
Collections.sort(listaComputere, ramComparator);
În java 1.7 cele două interfețe aveau decât 2 metode de implementat. În java 1.8 s-
http://docs.oracle.com/javase/8/docs/api/index.html?java/util/Compar
able.html
Interface Comparable<T>
• Type Parameters:
Path,RunnableScheduledFuture<V>, ScheduledFuture<V>
All Known Implementing Classes:
AbstractChronology, AbstractRegionPainter.PaintContext.CacheMode,
AddressingFeature.Responses, Authenticator.RequestorType,
CertPathValidatorException.BasicReason, Character,
Collector.Characteristics, Component.BaselineResizeBehavior,
DayOfWeek, Desktop.Action,
Diagnostic.Kind,Dialog.ModalExclusionType, Dialog.ModalityType,
FormatStyle,Formatter.BigDecimalLayoutForm,
FormSubmitEvent.MethodType, GraphicsDevice.WindowTranslucency,
GregorianCalendar,GroupLayout.Alignment, HijrahChronology,
JDBCType, JTable.PrintMode,
MultipleGradientPaint.ColorSpaceType,
MultipleGradientPaint.CycleMethod, NestingKind,Normalizer.Form,
OffsetTime, PKIXReason,PKIXRevocationChecker.Option,
SignStyle, SOAPBinding.ParameterStyle,
SSLEngineResult.HandshakeStatus, SSLEngineResult.Status,
StandardCopyOption,StandardLocation, StandardOpenOption,
ZoneOffsetTransitionRule.TimeDefinition
Vedem că toate clasele wrapper (Integer, Long, Double, Character, Boolean, etc),
comparator.
sorted map) violates the general contract for set (or map), which is
For example, if one adds two keys a and b such that (!a.equals(b) &&
comparator, the second add operation returns false (and the size of
the sorted set does not increase) because a and b are equivalent
A fi consistent with equals() este mai ales necesar în cazul claselor TreeSet și
Clasa LinkedList
LinkedList este asemănător cu ArrayList, cu deosebirea tehnologiei de stocare
utilizată. Fiecare element are câte două referințe către elementele precendent și
următor.
element)), se copiază tot ArrayList-ul punând noul element la locul lui. Din acest
motiv, ArrayList-ul este mai încet. Dacă lucrăm cu arraylisturi foarte mari (milioane de
elemente) și vrem să introducem și să ștergem obiecte de la mijloc frecvent, nu este
În LinkedList, pentru că fiecare element are câte o referință către elementele vecine,
Vector
Vector este o clasă din versiunea 1.0, în timp ce majoritatea claselor din Collection
Ca şi un array, elementele unui Vector pot fi accesate folosind indexul lor. La crearea
următoarele diferenţe:
Vectorul este sincronizat (util pentru firele de execuţie); acest lucru îl face să
Vectorul conţine multe metode proprii care nu fac parte din framework-ul de
colecţii.
început sau dacă avem nevoie să îşi modifice dimensiunea pe timpul programului.
Vectorul suportă 4 constructori. Prima formă creează un vector care are o mărime
iniţială de 10 elemente:
Vector()
A doua formă creează un vector a cărei capacitate este specificată prin parametrul
size:
Vector(int size)
A treia formă crează un vector a cărui capacitate este specificată de parametrul size,
Vector(Collection c)
Exemplu
import java.util.*;
v.addElement(newInteger(1));
v.addElement(new Integer(2));
v.addElement(new Integer(3));
v.addElement(new Integer(4));
v.capacity());
v.addElement(new Double(5.45));
v.addElement(new Double(6.08));
v.addElement(new Integer(7));
v.addElement(new Float(9.4));
v.addElement(new Integer(10));
System.out.println("Current capacity: " + v.capacity());
v.addElement(new Integer(11));
v.addElement(new Integer(12));
v.firstElement());
v.lastElement());
if (v.contains(new Integer(3)))
System.out.println("\nElements in vector:");
while(vEnum.hasMoreElements())
Initial size:0
Initial capacity:3
Current capacity:5
Current capacity:7
Current capacity:9
First element:1
Last element:12
Vector contains 3.
Elements in vector:
12345.456.0879.4101112
Stack
Clasa Stack implementează o stivă de elemente de tipul LIFO (last-in-first-out). Vă
puteţi gândi la acesta exact ca la mai multe obiecte puse unul peste celălalt. La
adăugarea unui nou element, acesta va fi pus deasupra celorlalte. Când scoatem un
Acesta defineşte doar un cosntructor implicit prin care creăm un Stack gol. Include
Vă puteţi gândi că Stack este asemenea unei stive de cărți. O carte nouă se adaugă
deasupra, iar pentru a accesa cărțile de mai jos trebuie date cele de deasupra la o
indexului.
Exemplu
import java.util.*;
st.push(new Integer(a));
System.out.println("push(" + a + ")");
System.out.println("stack: " + st);
System.out.println(a);
showpush(st,42);
showpush(st,66);
showpush(st,99);
showpop(st);
showpop(st);
showpop(st);
try {
showpop(st);
} catch(EmptyStackException e) {
System.out.println("empty stack");
stack:[]
push(42)
stack:[42]
push(66)
stack:[42,66]
push(99)
stack:[42,66,99]
pop ->99
stack:[42,66]
pop ->66
stack:[42]
pop ->42
stack:[]
Metode uzuale:
lista este primul care este scos, interfața Queue (coadă) implementează tehnica
Metode importante:
boolean add(E Inserts the specified element into this priority queue.
e)
E poll() Retrieves and removes the head of this queue, or returns null if this
queue is empty.
E peek() Retrieves, but does not remove, the head of this queue, or returns null if
this queue is empty.
Set-urile
Set-ul este o colecție care nu acceptă duplicate, adică 2 elemente care au aceeaşi
valoare.
Setul este o pungă (bag) în care se pun obiectele la grămadă. Obiectele nu sunt
parcurgere.
cu bucla for-each
cu iterator
while (iter.hasNext()) {
...
set1.add("casa");
e duplicat
// true
Set neparametrizat
Putem adăuga în el orice fel de obiecte.
Aici trebuie cast pentru că 4 este de tip integer, iar nouă ne trebuie un byte.
new Byte((byte) 4)
Set de Computere
Cum ne asigurăm că nu adăugăm obiecte duplicate?
foarte ineficient. Mai eficient este să punem cuvintele în „găleți” (bucket). Fiecare
găleată va avea astfel o valoare. Calculăm valoarea cuvntului nostru și apoi căutăm
doar în găleata care are această valoare și verificăm, astfel, doar cuvintele din
această găleată.
Regula 1: Două obiecte identice ca valoare după .equals() (nu neapărat și ca adresă
valoare.
Regula 3: Dacă două obiecte au hashCode-uri diferite, obiectele trebuie să fie diferite
Algortim:
Clasa Object are metoda hashCode() care se moștenește de către toate clasele.
obiectului din memorie. În principiu, două obiecte diferite au hashCoduri diferite, dar
poate fi și la fel.
Pentru a putea adăuga obiecte într-un Set, în clasa Computer trebuie să suprascriem
atât metoda equals() cât și hashCode(). Dacă nu le suprascriem vom putea adăuga
De asemenea, dacă suprascriem doar pe equals() tot nu este suficient. Tot vom
putea adăuga ambele aceste obiecte. Pentru că vor avea hashCoduri diferite, și la
Dar dacă le suprascriem pe ambele, java va căuta în găleata potrivită. Acolo va mai
găsi un obiect de tip Computer. Acum va testa egalitatea lor cu equals(). Dacă
equals() acum dă true, cel de al doilea computer nu mai este adăugat în set.
@Override
int result = 1;
long temp;
temp = Double.doubleToLongBits(frecventa);
32));
marca.hashCode());
return result;
@Override
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
if (Double.doubleToLongBits(frecventa) !=
Double.doubleToLongBits(other.frecventa))
return false;
if (marca == null) {
if (other.marca != null)
return false;
} else if (!marca.equals(other.marca))
return false;
if (ram != other.ram)
return false;
return true;
Set sortat
Există interfața SortedSet care este implemntată de clasa TreeSet.
Această clasă ține toate obiectele sortate după o anumită ordine. Stringurile –
implemtează pe Comparable).
Ori de câte ori se adaugă un nou obiect, el se pune direct la locul lui. Clasa rulează
Pentru a putea introeduce un obiect Computer într-un TreeSet, java trebuie să știe
TreeSet<Computer>(comparator);
când vom adăuga un computer în sortedSet la rulare vom avea această eroare:
setDeComputereSortate.add(new Computer("Lenovo", 4, 3.5));
următorul computer din set. Metoda higher() este specifică luiTreeSet, nu apare nici
facem down-cast.
TreeSet<Computer>(comparator);
Dacă ne trebuie setul să fie sortat doar ocazional, putem folosi un HashSet clasic,
care rulează mai repede. Apoi când ne trebuie sortarea, putem face un TreeSet,
// .....
Constructor
Constructs a new tree set containing the elements in the specified collection, sorted
Dcitionary
Clasa Dictionary este o clasă abstractă care defineşte o structură de date pentru
maparea cheilor la valori. Acest lucru este folositor în cazurile în care vrem să
Fiind o clasă abstractă, aceasta ne pune la dispoziţie doar metodele necesare pentru
un Map. Având o cheie şi o valoare, puteam stoca valoarea într-un obiect Dictionary.
Această clasă nu mai este folosită. Este recomandată implementarea interfeţei Map
Map
Map este o interfață care este implementată de mai multe clase. Aceasta este
asemenea unui dicționar. Este reprezentat printr-un obiect care este cheia și un al
obiect care este valoarea. Asemenea celorlaltor clase din Collection Framework, nu
se acceptă primitive.
Interfaţa Map mapează chei unice la valori. O cheie este un obiect care îl putem
folosi pentru a afla o valoare stocată la un moment dat. Chei foarte uzual folosite sunt
Stringurile. Cheile trebuie să fie unice, să nu fie duplicate. - Ele formează un Set.
obiectul cheie are setteri care permit modificarea obiectului, se poate obține un obiect
Exemplu
import java.util.*;
m1.put("Zara","8");
m1.put("Mahnaz","31");
m1.put("Ayan","12");
m1.put("Daisy","14");
System.out.println();
System.out.print("\t"+ m1);
MapElements
{Mahnaz=31,Ayan=12,Daisy=14,Zara=8}
HashMap
Un Map clasic este clasa HashMap. Aceasta nu are metodele sincronizate.
TreeMap
Clasa TreeMap implementează interfața SortedMap. Cheile sunt sortate, formând un
TreeSet.
Hashtable
Clasa Hashtable ne pune la dispoziţie o modalitate de organizare a datelor folosind o
structură cheie definită de utilizator. De exemplu, într-o listă de adrese dintr-un hash
table putem stoca şi sorta datele pe baza unei chei, cum ar fi codul poştal dau după
1.0) şi este o implementare concretă a Dictionary. Din Java 2, această clasă a fost
redefinită pentru a implementa interfaţa Map, iar acum este integrată în framework-ul
Când folosim un Hashtable, specificăm un obiect care este folosit ca şi cheie, iar
valoarea cerută este legată de cheia respectivă. Se aplică funcţia hash pe cheie, iar
A doua variantă creează un hashtable care are o dimensiune iniţială specificată prin
size:
Hashtable(int size)
A treia variantă creează un hashtable care are o mărime iniţiala specificată prin size
şi o rată de umplemere specificată prin fillRatio. Această raţie trebuie să fie un număr
între 0.0 şi 1.0, şi determină cât de mare să fie tabelul înainte să fie redimensionat.
A patra variantă creează un hashtable care este iniţializat folosind elementele din
Map-ul m. Capacitatea tabelului este de două ori mai mare decât a lui m. Factorul
Hashtable(Map m)
Exemplu
import java.util.*;
String str;
double bal;
names = balance.keys();
while (names.hasMoreElements()) {
}
System.out.println();
balance.get("Zara"));
Qadir:-19.08
Zara:3434.34
Mahnaz:123.22
Daisy:99.22
Ayan:1378.0
de valori în care atât cheile cât şi valorile sunt de tipul String. Clasa Properties este
folosită de multe clase din Java. De exemplu, atunci când dorim să obţinem valorile
Properties defaults;
Properties are doi constructori. Primul (cel implicit) creează un obiect fără valori:
Properties()
Properties(Properties propDefaults)
Exemplu
import java.util.*;
Set states;
String str;
capitals.put("Illinois", "Springfield");
capitals.put("Washington", "Olympia");
capitals.put("California", "Sacramento");
capitals.put("Indiana", "Indianapolis");
while(itr.hasNext()) {
capitals.getProperty(str) + ".");
}
System.out.println();
Exerciții
1. Se dă un map care are câteva înregistrări:
Limba - engleza
Culoare - rosu
valorile introduse - desigur, dacă cheia există deja își va modifica valoarea. De
fiecare dată când informația din map se schimbă, se va afișa în listă înregistrările așa
StringBuffer şi StringBuilder
Clasele StringBuffer şi StringBuilder sunt folosite când există o necesitate pentru a
sincronizate).
Așa cum am vazut, obiectele String sunt imutable (odată create nu se pot modifica)
a = a + "are ";
a = a + "4 ";
a = a + "mere.";
Crează mulțime de obiecte de tip String pe String Pool. Acesta rămân acolo până se
sb.append("Alin ");
sb.append("are ");
sb.append("4 ");
sb.append("mere.");
Se crează un singur obiect care se modifică. Obiectele StringBuffer sunt modificabile.
Clasa StringBuffer este thread-safe (este bună pentru lucrul cu firele de execuție).
Dar din acest motiv este mai lentă. Dacă nu lucrați cu mai multe fire de execuție, ni
StringBuffer.
Este recomandată folosirea unui StringBuilder când este posibilă, fiind mai rapidă
System.out.println(sBuffer);
Metode uzuale
Cele mai importante metode suportate de clasa StringBuffer sunt prezentate mai jos.
offset.
this
this();
// sau
this(nume);
super
super();
// sau
super(nume);
Atribute
this
this.nume = nume;
super
super.nume = nume;
Metode
this
this.deseneazaCerc(); // nu are sens caci poate fi apelat direct cu
deseneazaCerc()
// ...
...
this.deseneazaCerc();
// nu are sens
deseneazaCerc();
super
super.getNume();
Studiu de caz
Clasa Ostas este superclasa. Clasele Pedestru și Calaret extind (moștenesc) pe
Ostas. Clasa Ostas are atributul String nume și atributul Rege rege.
Varianta 1
În superclasa facem aceste atribute protected. În acest fel, ele vor fi vizibile în
subclase. Atenție, nu declarăm noi atribute String nume și Rege rege în clasa fiică!!!!
Clasa Ostas
this.nume = nume;
this.rege = rege;
return nume;
this.nume = nume;
return rege;
}
this.rege = rege;
// fără atribute
subclasa.
super(nume, rege);
return nume;
}
this.nume = nume;
return rege;
this.rege = rege;
Dar dacă facem atributele protected, ele vor putea fi modificate direct, fără setter,
ceea ce nu este bine, atât din subclase fiică, cât și din alte clase din același pachet,
Varianta 2
În superclasa facem aceste atribute private. Ele, însă, nu vor fi vizibile în clasele fiică,
Clasa Ostasu
this.nume = nume;
this.rege = rege;
return nume;
return rege;
this.rege = rege;
// fără atribute
return super.getNume();
super.setNume(nume);
return super.getRege();
...
Ostaș.
@Override
Pedestru) {
return -1;
instanceof Calaret) {
return 1;
instanceof Pedestru) {
return
this.getNume().compareToIgnoreCase(altOstas.getNume());
} else {
return
this.getNume().compareToIgnoreCase(altOstas.getNume());
}
}
Observăm că nu am inclus nici o referire la Rege. Nu are sens să sortăm armata unui
rege după rege, cacă toți ostașii unui rege vor avea o referire la acest rege, nu la
altul.
@Override
int result = 1;
result = prime * result + ((nume == null) ? 0 :
nume.hashCode());
return result;
@Override
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
if (nume == null) {
if (other.nume != null)
return false;
} else if (!nume.equals(other.nume))
return false;
return true;
Un alt aspect:
El trebuie șters din TreeSetul unui rege, și adăugat în TreeSetul altui rege.
Armata1 Armata2
Călăreț Călăreț
Călăreț Pedestru
Călăreț Pedestru
Pedestru Pedestru
Pedestru
Pedestru
Pedestru
Parcurgem TreeSetul armatei mai mici (Armata2), și pentru fiecare dintre ostașii ei,
purtăm câte o luptă. Călărețul se va lupta cu un primul Călăreț din Armata1, dar primii
doi Pedeștri din Armata2 se vor lupta cu câte un Călăreț, iar cel de al treilea Pedestru
folosi un Iterator.
Iterator iterUser;
...
iterUser = user.getArmata().iterator();
iterComputer = computer.getArmata().iterator();
while (iterUser.hasNext()) {
if (iterComputer.hasNext()) {
lupta(ostasUser, ostasComputer);
/**
*/
ostasi sunt
// si crapa programul
computer.getOstasiCapturati().add(ostasUser);
// user.getArmata().remove(ostasUser);
iterUser.remove();
ostasUser.setRege(computer);
Exercițiu
Se dă următoarea ierarhie de clase:
Sa se implementeze:
1. ierarhia de clase
2. principiul de incapsulare
întrecere se folosește un autovehicul aleator din garajul fiecăruia. Câștigă cursa cel
cu mașina mai rapidă, caz în care va "fura" mașina oponentului. Dacă ambele mașini
au aceeași viteză, atunci aleator unul din participanți va lua 2 mașini aleatoare de la
competiție.
Java Streams
Pachetul java.io are în componență clase, numite I/O Streams, care ajuta, la nevoie,
Standard Streams
În Java sunt următoarele stream-uri standard:
Standard Input: Crează fluxuri de intrări, cu ajutorul cărora se pot citi date de
la o sursă externă. Cel mai des întâlnit StandardInput este cel creat pentru
Iată un exemplu în care vom crea o instanță a InputStreamReader care v-a citi
fluxurile primite de la tastatură până când userul v-a apasa litera “q”:
import java.io.IOException;
import java.io.InputStreamReader;
try {
char c;
do {
c = (char) cin.read();
System.out.print(c);
} while (c != 'q');
} finally {
if (cin != null) {
cin.close();
} }
DataInputStream
Acest stream este utilizat în citirea primitivelor. Ca și streamul anterior, se pot creea
Metode
Citește maxim len biți din streamul de date și le scrie într-un array de
tipul byte. Returnează numărul total de biți citiți sau -1 dacă este finalul
fișierului.
Citește numărul de biți din stream și le scrie într-un array de tipul byte.
Returnează numărul total de biți citiți sau -1 dacă este finalul fișierului.
String.
Exemplu
dat test.txt și scrie aceste rânduri în majuscule într-un alt fișier test1.txt.
import java.io.*;
ileInputStream("test.txt"));
FileOutputStream("test1.txt"));
String count;
System.out.println(u);
d.close();
out.close();
FileOutputStream
FileOutputStream este folosit în crearea fișierelor și pentru scrierea datelor în ele.
Acest stream verifică dacă fisierul solicitat pentru scriere există, iar dacă nu există
crează unul.
unui String
Metode
metoda close() a fost apelată când nu mai există referințe la acest stream.
DataOutputStream
Cu acest stream se pot scrie date primitive intr-un output speficat. Constructorul
folosit este:
Metode
public final void write(byte[] w, int off, int len) throws IOException
buffer.
secvență de biți. Fiecare caracter din string este scrie separat prin eliminarea
primilor 8 biți.
Exemplu
try {
os.close();
is.close();
} catch (IOException e) {
System.out.print("Exception");
Următoarea sintaxă crează o nouă instantă a clasei File dintr-o cale a fișierului
Următoarea sintaxă creză o nouă instantă a clasei File prin convertirea unei
File(String pathname);
Exemplu
import java.io.File;
File f = null;
try {
String a = f.getAbsolutePath();
System.out.print(a);
// prints
} catch (Exception e) {
e.printStackTrace();
}
Considerând fișierul test1.txt executabil și fișierul test2.txt neexecutabil, în urma
Clasa FileReader
Această clasă moștenește clasa InputStreamReader. Clasa FileReader este folosită
în citirea fluxurilor de caractere și cei mai uzuali constructori sunt prezentaţi mai jos.
FileReader(File file);
FileReader(FileDescriptor fd);
numele căii unui fișier transmis ca String, fişier din care se va executa citirea.
FileReader(String fileName);
Exemplu
import java.io.*;
file.createNewFile();
writer.flush();
writer.close();
for (char c : a)
fr.close();
}
This
is
an
example
Clasa FileWriter
Această clasă moștenește clasa OutputStreamWriter. Această clasă este folosită în
scrierea fluxurilor de caractere. Constructorii cei mai uzuali sunt prezentaţi mai jos.
FileWriter(File file);
FileWriter(FileDescriptor fd);
numele căii unui fișier transmis ca String, fişier în care se execută scrierea.
FileWriter(String fileName);
Următoarea sintaxă crează o nouă instanță a clasei FileWriter având ca input
numele căii unui fișier transmis ca String și o variabilă boolean în care este
fişierul (false).
Exemplu
import java.io.*;
file.createNewFile();
writer.flush();
writer.close();
for (char c : a)
fr.close();
This
is
an
example
Directoare în Java
Un director este un fișier care conține o listă de alte fișiere și directoare. Cu ajutorul
clasei File, putem să manipulam și să creăm direcotoare și fisiere. Unele dintre cele
Crearea Directoarelor
Există doua metode cu care putem crea directoare:
Dacă parametrul returnat este true, atunci directorul a fost creat cu succes. Dacă
parametrul returnat este false atunci, directorul nu a fost creat pentru că, ori există
Exemplu
import java.io.File;
Notă: În Java se pot folosi ca separatori în compunerea adreselor de pe disc, "/" ori
Afișarea Directoarelor
Pentru lista de fișiere și directoare dintr-un director se poate folosi metoda list()
Exemplu
import java.io.File;
String[] paths;
try {
paths = file.list();
System.out.println(path);
} catch (Exception e) {
e.printStackTrace();
}
În urma executării programului de mai sus, se afiseză conținutul fișierului "/tmp";
Assignment
+———————————————————————————————————+
| #### |
| #### |
| #### |
| |
| |
| Bill Gates |
| 1 Microsoft Way |
| Redmond, WA 98104 |
| |
+———————————————————————————————————+
2. Creați un fișier în care să salvați numele vostru (nume și prenume separate prin
într-un fișier text. Suprascrieţi informația din fișier dacă programul rulează din nou și
program care să citească numerele din fișier, să facă suma lor și să o afiseze pe
fiecare fișier mai multe numere, fiecare pe câte un rând. Scrieți un program care cere
utilizatorului numele fișierului de la tastatură, apoi face suma numerelor din fisierul
respectiv.
fișierului pe ecran.
7. Se dă următorul cod:
import java.net.URL;
import java.util.Scanner;
webIn.close();
System.out.println(one);
Adăugați verificări pentru excepții acolo unde este cazul. Asiguraţi-vă că programul
Cereți utilizatorului să introducă numele unei pagini web. Salvați conținutul paginii
Creați un program care deschide acest fișier și citește literele din trei în trei. Afișați
rezultatul.
Serializare
Serializarea obiectelor este un mecanism prin care un obiect poate fi reprezentat ca
o secvență de biți în care se includ datele obiectului, precum și informații despre tipul
După scrierea unui obiect serializat într-un fișier, acesta poate fi citit, iar prin
lucru permițând serializarea unui obiect într-o platformă și deserializarea lui în alta.
deserializare a obiectelor:
ClassNotFoundExceptio
Exemplu
address);
Pentru a afla dacă o clasă din librăria standard Java este serializabilă, trebuie
generează niciun output, dar studiaţi codul şi determinaţi cum funţionează. Atunci
când se serializează un obiect într-un fişier, Java sufixează fişierului rezultat extensia
.ser.
Exemplu
import java.io.*;
e.SSN = 11122333;
e.number = 101;
try {
FileOutputStream("employee.ser");
ObjectOutputStream(fileOut);
out.writeObject(e);
out.close();
fileOut.close();
} catch (IOException i) {
i.printStackTrace();
Exemplu
import java.io.*;
Employee e = null;
try {
FileInputStream fileIn = new
FileInputStream("employee.ser");
e = (Employee) in.readObject();
in.close();
fileIn.close();
} catch (IOException i) {
i.printStackTrace();
return;
} catch (ClassNotFoundException c) {
c.printStackTrace();
return;
System.out.println("Deserialized Employee...");
DeserializedEmployee...
Name:ReyanAli
Address:PhokkaKuan,AmbehtaPeer
SSN:0
Number:101
De reţinut:
JVM să poată deseriliza un obiect, trebuie să aibă acces la bytecodul clasei. Dacă
ClassNotFoundException.
deoarece câmpul este transient, şi valoarea lui nu a mai fost serializată împreună
Excepţii
O excepţie este o problemă care apare în timpul execuţiei programului. O excepţie
fără memorie
Unele dintre aceste excepţii sunt cauzate de erorile utilizatorilor, alte de erori ale
exemplu, dacă un fişier trebuie deschis, dar nu este găsit, se aruncă o excepţie.
programatorul sau utilizatorul să aibă control asupra lor. Erorile sunt în general
ignorate în cod pentru că în general nu există soluţii pentru ele. De exemplu, dacă
şi la compilare.
Ierarhia de Excepţii
Toate clasele de excepţii sunt subtipuri ale clasei java.lang.Exception. Aceasta este o
subclasă a clasei Throwable. În afară de clasa Exception, mai există o clasă numită
condiţii de căderi majore, care nu pot fi tratate în codul Java. Acestea sunt generate
pentru a indica erori ale mediului de execuţie. De exemplu: JVM a rămas fără
Clasa Exception are două clase principale: IOException şi RuntimeException. Mai jos
Tipuri de Excepţii
Cele mai generale dintre acestea sunt subclase ale tipului standard
array-ului
incompatibil
curentă a thread-ului
format numeric
suportată
sau o interfaţă
metodei getMessage()
fiecare element din stack trace. Elementul de la indexul 0 reprezintă vârful stivei
de apeluri, iar ultimul element din array reprezintă metoda de la finalul stivei de
apeluri.
Exemple de excepţii
int a = 10 / 0; // ArithmeticException.
comp.ruleaza(); // NullPointerException
niciodata
class Animal { }
System.out.println(numere[10]); // ArrayIndexOutOfBoundsException
string.charAt(20); // StringIndexOutOfBoundsException
Prinderea excepţiilor
O excepţie poate fi prinsă prin folosire multiplelor blocuri de try/catch. Acesta este
amplasat în jurul blocului care poate genera una sau mai multe excepţii. Codul din
blocul try/catch este denumit cod protejat, iar sintaxa pentru acesta arată în felul
următor:
try {
// Protected code
//Catch block
Dacă o excepţie este aruncată într-un cod protejat, blocul (sau blocurile) catch care
ţin de blocul try va fi verificat. Dacă tipul excepţiei care s-a produs este listat în blocul
catch, atunci excepţia este trimisă în blocul catch, aşa cum se transmit şi parametrii
metodelor.
Exemplu
import java.io.*;
} catch(ArrayIndexOutOfBoundsException e) {
try {
// Protected code
} catch(ExceptionType1 e1) {
// Catch block
} catch(ExceptionType2 e2) {
// Catch block
} catch(ExceptionType3 e3) {
// Catch block
Exemplul anterior conţine trei blocuri catch, dar putem avea oricât de multe blocuri
după un singur try. Dacă o excepţie este aruncată în cod protejat, aceasta este
trimisă în primul bloc din listă. Dacă tipul de date al excepţiei aruncate este acelaşi
(sau o superclasă) cu cel declarat în blocul catch, atunci excepţia este prinsă acolo.
Dacă nu, este aruncată mai departe la următoarele blocuri până când unul din catch-
uri poate să o prindă. Dacă niciunul din blocuri nu reuşeste să o prindă, metodă
curentă se opreşte din execuţie, iar excepţia este aruncată la metoda anterioară din
stiva de apeluri.
De regulă, ordinea excepţiilor în blocurile catch sunt de la cele mai specifice la cele
try {
// ...
} catch (Exception e) {
// ...
Exemplu
try {
x = (byte) file.read();
} catch(IOException i) {
i.printStackTrace();
return -1;
return -1;
Putem arunca excepţii, fie una abia instanţiată ori una care o prindem, folosind
cuvântul cheie throw. În cercaţi să înţelegeţi diferenţa dintre acestea: practic throw
este punctul de plecare al excepţiei, în timp ce throws ajută aruncarea excepţiei mai
departe.
import java.io.*;
// Method implementation
}
//Remainder of class definition
O metodă poate declara aruncarea mai multor excepţii, caz în care sunt declarate în
semnătura metodei, după cuvântul cheie throws, cu virgulă între ele. De exemplu, o
InsufficientFundsException.
import java.io.*;
InsufficientFundsException {
// Method implementation
IllegalArgumentException().
excepţie.
Prin folosirea blocului finally, putem executa orice instrucţiuni de curăţare a codului,
try {
// Protected code
} catch(ExceptionType1 e1) {
// Catch block
} catch(ExceptionType2 e2) {
// Catch block
} catch(ExceptionType3 e3) {
// Catch block
} finally {
Exemplu
try {
} catch(ArrayIndexOutOfBoundsException e) {
} finally {
a[0] = 6;
Definirea excepţiilor
Putem defini excepții proprii. Creăm o clasă care extinde o clasă de excepții
if (/*ceea ce nu ne convine*/) {
}
public void setNota (int nota) {
de 10”);
this.nota = nota;
// ...
try {
student.setNota(11);
System.out.println(mce.getMessage());
evita:
caractere:
try {
int nr = Integer.parseInt(string);
un numar" );
excepție
try {
System.out.println (introduce());
reprezinta un numar");
trebuie obligatoriu inclus într-un bloc try/catch sau declarată metoda pentru a arunca
eroarea.
try {
metoda();
System.out.println("Ai Grija!");
De reţinut
Fiecare clauză catch nu poate exista fără un try
Blocul try poate fi prezent ori fără clauza catch ori fără clauza finally
Nu putem avea cod între blocurile try, catch, finally
Important!
Nu lăsați niciodată blocul catch gol. Blocul catch este pentru avertisment!
Putem prinde mai multe excepții. Regula este să pornim de la ochiuri mai mici
ale sitei către ochiurile mai mari. Dacă punem mai întâi ochiurile mari care prind
Fire de execuţie
Java este un limbaj de programare pe mai multe fire de execuţie, ceea ce înseamnă
conţine două sau mai multe părţi care pot rula în acelaşi timp, iar fiecare parte se va
ocupa de un task diferit în acelaşi timp, utilizându-se astfel în mod optim de resursele
Prin definiţie, multitasking-ul se întâmplă atunci când mai multe procese împart
specifice dintr-o aplicaţie în fire de execuţie individuale. Fiecare fir de execuţie poate
New: un thread începe ciclul de viaţă în starea new. Rămâne în această stare
până când programul începe să ruleze firul de execuţie. Mai poate fi referit şi ca
Runnable: după ce un thread abia creat este pornit, acesta intră în starea
alt thread să îşi termine task-ul. Acesta trece în starea runnable doar când alt
Timed waiting: un thread runnable poate intra în starea timed waiting pentru
evenimentul aşteptat.
folosită ca punct de intrare pentru firul de execuţie. În aceasta vom pune toată logica
Unde threadObj este o instanţă a clasei care implementează interfaţa Runnable, iar
3. O dată ce obiectul de tip Thread este creat, îl vom porni prin apelarea metodei
start(), care execută un apel către metoda run(). Sintaxa metodei este următoarea:
void start();
Exemplu
private Thread t;
threadName = name;
System.out.println("Creating " + threadName );
try {
i);
Thread.sleep(50);
} catch (InterruptedException e) {
interrupted.");
if (t == null) {
t.start ();
r1.start();
Creating Thread-1
Starting Thread-1
Creating Thread-2
Starting Thread-2
Running Thread-1
Thread: Thread-1, 4
Running Thread-2
Thread: Thread-2, 4
Thread: Thread-1, 3
Thread: Thread-2, 3
Thread: Thread-1, 2
Thread: Thread-2, 2
Thread: Thread-1, 1
Thread: Thread-2, 1
extinde clasa Thread. Puteţi folosi următorii paşi pentru implementare. Această
scrie toate instrucţiunile pe care dorim să le executăm într-un fir de execuţie separat.
2. O dată creat obiectul pentru firul de execuţie, îl putem porni prin apelul metodei
void start();
Exemplu
Mai jos este programul anterior rescris folosind clasa Thread.
private Thread t;
ThreadDemo(String name) {
threadName = name;
try {
i);
// Let the thread sleep for a while.
Thread.sleep(50);
} catch (InterruptedException e) {
interrupted.");
if (t == null) {
t.start ();
}
}
t1.start();
t2.start();
Creating Thread-1
Starting Thread-1
Creating Thread-2
Starting Thread-2
Running Thread-1
Thread: Thread-1, 4
Running Thread-2
Thread: Thread-2, 4
Thread: Thread-1, 3
Thread: Thread-2, 3
Thread: Thread-1, 2
Thread: Thread-2, 2
Thread: Thread-1, 1
Thread: Thread-2, 1
implementează Runnable, o altă clasă care extinde Thread şi o clasă în care găsim
programul principal.
this.message = message;
while(true) {
System.out.println(message);
}
// File Name : GuessANumber.java
this.number = number;
int counter = 0;
int guess = 0;
do {
guess);
counter++;
} while(guess != number);
thread1.setDaemon(true);
thread1.setName("hello");
thread1.start();
Runnable bye = new DisplayMessage("Goodbye");
thread2.setPriority(Thread.MIN_PRIORITY);
thread2.setDaemon(true);
thread2.start();
System.out.println("Starting thread3...");
thread3.start();
try {
thread3.join();
} catch(InterruptedException e) {
System.out.println("Thread interrupted.");
}
System.out.println("Starting thread4...");
thread4.start();
System.out.println("main() is ending...");
Acesta ar putea produce următorul rezultat. Puteţi rula codul anterior de mai multe
Hello
Hello
Hello
Hello
Hello
Hello
Goodbye
Goodbye
Goodbye
Goodbye
Goodbye
.......
Exerciţii
1. Să se creeze o interfaţă grafică care are următoarea compoziţie:
- la apăsarea pe buton se va porni un nou fir de execuţie care va funcţiona ca mai jos
încât să nu fie mai multe fire de execuţie care rulează în acelaşi timp.
2.
Să se creeze o interfaţă grafică care să conţina mai multe componente (de care vreţi,
valoare aleatoare. Acest lucru se va întâmpla într-un Thread. Când cel puţin una din
System.out.printf() și String.format()
În java api clasa Formatter la rubrica Format String Syntax gasiti toate codurile %s
%d %c etc.
PrintStream (System.out.printf())
printf(String format, A convenience method to write a formatted string to this output
Object… args) stream using the specified format string and arguments.
Character ch = '!';
Printează:
Hello, Gelu are 4 frati!
%c înseamnă cu caracter
%s înseamnă un string
String.format()
static String format(String format, Returns a formatted string using the specified format
Object… args) string and arguments.
Character ch = '?';
str2, ch);
System.out.println(str);
Printează:
Găsiti toate codurile %s %d %c etc. în java api clasa Formatter la rubrica Format
String Syntax.
BIGINTEGER
import java.math.BigInteger;
System.out.println(Long.MAX_VALUE);
//9,223,372,036,854,775,807
BigInteger("495885852095809859458205885");
BigInteger("558853485345834584589345805");
System.out.println(suma);
System.out.println(multiplicare);
BigInteger bi3 = new BigInteger("2673");
System.out.println(putere);
System.out.println(impartire);
multiplicare.nextProbablePrime());
import java.math.BigDecimal;
favoarea
// (acuratete / precizie).
double
suma = suma.add(bd1);
}
System.out.println(suma);
//
1.0000000000000000555111512312578270211815834045410156250
// in loc de 1.0
corect
suma2 = suma2.add(bd2);
System.out.println(suma2); // 1.0
}
}
Formatarea Numerelor
NumberFormat (superclasă) și DecimalFormat (subclasă)
exemplu in cazul in care se foloseste virgula in loc de punct, sau se mai foloseste
GERMAN
NumberFormat nf = NumberFormat.getInstance();
DecimalFormat.
// Verificare:
System.out.println(nf.getClass().getName()); //
java.text.DecimalFormat
Formatarea procentului
Locale.setDefault(Locale.US);
System.out.println(nf2Procent.format(0.47)); // 47%
try {
Wrapper numere
BigInteger
System.out.println(number); // 1234.5
german
System.out.println(number2); // 111234.5678909876
} catch (ParseException e) {
e.printStackTrace();
Clasa DecimalFormat
Clasa DecimalFormat este o subclasă a clasei NumberFormat. Ea moștenește toate
metodele acesteia.
Clasa DecimalFormat are diverse patternuri care pot fi folosite pentru formatarea unui
numar, de exemplu: vrem zerouri in față, vrem un anumit număr de zecimale, etc.
USD, $, US Dollar
System.out.println(nfUS.format(12000.4)); // $12,000.40
NumberFormat nfGer =
NumberFormat.getCurrencyInstance(Locale.GERMANY);