Se afișează postările cu eticheta java. Afișați toate postările
Se afișează postările cu eticheta java. Afișați toate postările

miercuri, 25 februarie 2026

Clasa ArrayList. Crearea listelor dinamice de obiecte

După ce am învățat să lucrăm cu vectori de obiecte, este momentul să facem un pas mai departe. Până acum am creat structuri de tipul:  

Elev[] elevi = new Elev[30];

Unde
Elev[] înseamnă un vector care poate stoca obiecte de tip Elev;
30 reprezintă numărul maxim de elemente;
fiecare poziție din vector reține un obiect.

Această metodă este corectă și foarte importantă pentru a înțelege cum funcționează memoria și organizarea datelor. 
Dar în aplicarea în practică, uneori această metodă este ineficientă. 
De ce?  Pentru că așa tip de vector are o dimensiune statică, în sens că dimensiunea acestuia este fixă, iar în cazul exemplului de mai sus nu vom putea adăuga al 31-lea elev, ba mai mult dacă inserăm în listă doar 10 elevi, restul pozițiilor rămân neutilizate. Ștergerea unui element necesită mutarea manuală a celorlalte.

În aplicațiile reale, de cele mai multe ori nu știm din start câte obiecte vom avea. Nu avem cum să cunoaștem câte persoane se vor înscrie la un concurs, câte persoane își vor crea conturi pe platforma educațională a instituției sau câți abiturienți vor depune dosarul pentru a participa la concursul de admitere. Respectiv, este nevoie de o structură dinamică dimensiunea căreia să fie ajustabilă.

Una din soluțiile care le oferă limbajul Java este utilizarea clasei ArrayList din pachetul java.util.  
Un ArrayList este un vector dinamic. Aceasta înseamnă că dimensiunea se modifică automat, avem posibilitatea de a adăuga elemente fără limită fixă, iar ștergerea elementelor este simplificată. 

După cum cunoaștem ca să creăm listă dinamică este necesar de instanțiat clasa ArrayList , deci trebuie să îi cunoaștem constructorii: 
ArrayList() Construiește o listă fără nici un element având capacitatea inițială de 10 elemente. Dacă se încearcă adăugarea a mai mult de 10 elemente, dimensiunea listei se va modifica automat.
ArrayList(Collection c) Construiește o listă ce conține elementele conținute de colecția primită ca argument. Capacitatea inițială este cu 10 procente mai mare decât numărul de elemente din colecția primită ca argument
ArrayList(int intialCapacity) Construiește o listă vidă cu o capacitate specificată de parametrul intialCapacity

Deci pentru a crea un ArrayList respectăm sintaxa: 
ArrayList<Elev> listaElevi = new ArrayList<>();

După cum observați dimensiunea listei nu o mai specificăm, așa cum aceasta crește automat. 

Pentru a putea opera cu elementele din listă vom trebuie să cunoaștem metodele clasei ArrayList și parametrii acestora:
 
1. add(E e)- adaugă la sfârșitul listei obiectul e
ArrayList<String> lista = new ArrayList<>();
lista.add("Ana"); // adaugă "Ana" în listă
lista.add("Ion"); // adaugă "Ion" în listă

2. add(int index, E e) - adaugă obiectul e în listă începând cu poziția index, mutând elementele de după el.
lista.add(1, "Maria"); // inserează "Maria" pe poziția 1

3. get(int index) - returnează elementul de la poziția indicată prin parametrul index
String nume = lista.get(0); // returnează "Ana"

4. set (int index, E e)- Înlocuiește elementul de pe poziția index cu noul element, sau obiect e
lista.set(0, "Andreea"); // înlocuiește "Ana" cu "Andreea" 

5. remove(int index)- șterge elementul de la poziția indicată și mută elementele următoare.
lista.remove(1); // șterge elementul de pe poziția 1 ("Maria")

6. remove(Object o) - șterge prima apariție a obiectului o din listă.
lista.remove("Andreea"); // șterge "Andreea" din listă

7.
size()- returnează numărul de elemente din listă.
int lungime = lista.size(); // returnează 0 dacă lista este goală

8. isEmpty()- returnează true dacă lista este goală.
if (lista.isEmpty()) {
System.out.println("Lista este goală");}

9. contains(Object o) - verifică dacă lista conține elementul dat.
boolean exista = lista.contains("Ion"); // returnează true dacă "Ion" este în listă

10. clear()- șterge toate elementele din listă.
lista.clear(); // lista devine goală

Crearea unei liste de tip ArrayList care să conțină direct tipuri primitive precum int sau double nu este posibilă, așa cum metodele clasei ArrayList operează cu tip de date referință. 

Totuși, încă de la începutul cursului am învățat că fiecărui tip primitiv din Java îi corespunde o clasă de tip Wrapper.
De exemplu:
tipului int îi corespunde clasa Integer
tipului double îi corespunde clasa Double
tipului char îi corespunde clasa Character
tipului boolean îi corespunde clasa Boolean

Astfel, dacă dorim o listă de numere întregi, vom scrie:
ArrayList<Integer> numere = new ArrayList<>();
numere.add(10);
numere.add(25);

Observați că folosim Integer, nu int.
Java face automat conversia dintre tipul primitiv și obiectul corespunzător. Acest mecanism se numește autoboxing (transformarea automată a unui tip primitiv într-un obiect Wrapper) și unboxing (transformarea inversă).

În exemplele de mai sus, elementele stocate în ArrayList sunt de tip String, pentru a simplifica înțelegerea. În practică însă, lista va conține, de cele mai multe ori, obiecte ale claselor create de programator, cum ar fi Client, Produs, Comandă sau alte tipuri definite în aplicație.

Să vedem în următorul exemplu cum este posibil acest lucru. 
Fie ca avem clasa Elev cu următorul cod sursă:
 
class Elev{
private String nume;
private int grupa;
 
public Elev(String nume, int grupa) {
this.nume = nume;
this.grupa = grupa;
}
public String getNume() {
return nume; }
 
public void setNume(String nume) {
this.nume = nume;
}
 
public int getGrupa() { return grupa; }
 
public void setGrupa(int grupa) {
this.grupa = grupa;
}} 

Următorul exemplu va crea o listă de elevi și va parcurge elementele acesteia folosind instrucțiunea for clasică cu index:

import java.util.*;
class TestCollection1{
    public static void main(String args[]){
        ArrayList<Elev> lista=new ArrayList<Elev>();
        lista.add(new Elev("Ana", 1001));
        lista.add(new Elev("Maria", 1002));
        lista.add(new Elev("Ion", 1001));
        lista.add(new Elev("Mihai", 1002));
        for (int i = 0; i < lista.size(); i++) {
            Elev element = lista.get(i);
            System.out.println(element.getNume()+
                    " "+element.getGrupa());}
    }}

O altă modalitate de a parcurge lista este instrucțiunea for îmbunătățit, dar ... noi deja cunoaștem în ce context o folosim 👌

import java.util.*;
class TestCollection1{
    public static void main(String args[]){
         ArrayList<Elev> lista=new ArrayList<Elev>();
         lista.add(new Elev("Ana", 1001));
         lista.add(new Elev("Maria", 1002));
         lista.add(new Elev("Ion", 1001));
         lista.add(new Elev("Mihai", 1002));
         for (Elev element : lista) {
             System.out.println(element.getNume()+
             " "+element.getGrupa());}

    }}


Voi prezenta mai jos o metodă de parcurgere a listei destul de des folosită în proiecte reale: 
import java.util.*;
class TestCollection1{
    public static void main(String args[]){
        ArrayList<Elev> lista=new ArrayList<Elev>();
        lista.add(new Elev("Ana", 1001));
        lista.add(new Elev("Maria", 1002));
        lista.add(new Elev("Ion", 1001));
        lista.add(new Elev("Mihai", 1002));
        lista.forEach(element -> {
            System.out.println(element.getNume()+
                    " "+element.getGrupa());
        });
    }}

Metoda
forEach(element -> { ... }) din ultimul exemplu folosește o expresie lambda pentru parcurgerea listei.  Expresiile lambda sunt o funcționalitate în limbaj introdusă în Java8. Tradus din limbaj Java în limbaj omenesc ar însemna: ,,pentru fiecare element din listă, execută instrucțiunile din bloc”.

Sunt și alte metode de parcurgere și modificare a listelor de obiecte cum ar fi interfața Iterator, Interfața Enumeration, dar vom discuta despre ele într-o altă postare.

Succes!
❤️

luni, 23 februarie 2026

Expresii regulate. Validarea șirurilor de caractere

În Java, o expresie regulată, numită regex, este un model de verificare a unui text. Ea ne permite să controlăm dacă un șir respectă o anumită regulă sau nu. 
De exemplu putem valida dacă șirul introdus de utilizator este: email, număr de telefon, parolă, cod poștal, doar cifre, doar litere, etc

Pentru aceasta se folosesc clasele din pachetul java.util.regex
import java.util.regex.Pattern;
import java.util.regex.Matcher;
Dar un mod mai simplu de a valida un șire de caractere este metoda matches() a clasei String care are forma:
String.matches("regex");
"regex" este o expresie regulată, adică un model (regulă) după care verificăm textul, cu alte cuvinte anume acesta este șablonul după care validăm șirul de caractere. 
Pentru a construi șablonul trebuie să cunoaștem simbolurile cheie: 

Vom examina în continuare mai multe exemple practice. 

Exemplul următor va valida dacă șirul de caractere conține doar cifre. Expresia regulată în acest caz va conține \\d,  adică doar cifre, și + ceea ce înseamnă una sau  mai multe apariții, deci verificăm dacă în șirul de caractere apare una sau mai multe cifre: 
class Testare{
public static void main(String [] args){
String text = "12345";
if (text.matches("\\d+")) {
System.out.println("Codul este valid!");}
else
System.out.println("Codul trebuie să conțină doar cifre!");
}}

O astfel de verificare este frecvent utilizată în aplicații reale: validarea unui cod numeric, a unui ID, a unui PIN sau a unui număr de ordine.

De exemplu cunoaștem că un code PIN are 4 cifre, deci expresia care va valida dacă șirul de caractere este un cod corecte va conține {} și acesta este: 
class Testare{
public static void main(String [] args){
String pin = "2255";
if (pin.matches("\\d{4}")) {
System.out.println("Codul pin valid");
}
}}

Exemplul următor va valida dacă șirul de caractere conține doar litere. Expresia regulată în acest caz va conține [a-zA-Z],  adică doar litere mari și mici, și semnul + ceea ce înseamnă una sau  mai multe apariții, deci verificăm dacă în șirul de caractere apare una sau mai multe litere, fie litere mari, fie litere mici: 
class Testare{
public static void main(String [] args){
String text = "ProgramareJava";
if (text.matches("[a-zA-Z]+")) {
System.out.println("Valid - doar litere");
}
}}

Următorul exemplu verifică dacă șirul de caractere va conține cel puțin o literă acesta nu va promova validarea: 
class Testare{
 public static void main(String [] args){
     String text = "1F2345";
     if (text.matches(".*[a-zA-Z].*")) {
         System.out.println("Codul este valid!");}
     else System.out.println("Codul trebuie să conțină cel puțin o literă!");
 }}

În cazul condițiilor combinate este necesar de utilizat simbolurile:
^  - începutul șirului
$  - sfârșitul șirului

De exemplu, vom verifica dacă șirul conține litere și cifre: 
class Testare{
public static void main(String [] args){
String text = "Java2026";
if (text.matches("^[a-zA-Z0-9]+$")) {
System.out.println("Valid - doar litere si cifre");
}
else {
System.out.println("Invalid");
}
}}

De asemenea, în condițiile combinate se folosește (?=…), numit lookahead, care verifică o condiție fără să „consume” textul, adică se uită dacă regula este respectată, dar nu modifică șirul și nu utilizează caracterele verificate, nu-i modifică dimensiunea, astfel încât restul expresiei să poată continua să analizeze întreg șirul.

Următoarele două exemple evidențiază utilitatea lookahead-ului în condiții combinate, dorim să validăm dacă parola conține cel puțin o cifră și minim 6 caractere : 

Exemplu fără lookahead
class Testare{
public static void main(String [] args){
String parola = "abc123";
// Regex fără lookahead
// Caută să înceapă cu o cifră, apoi 5 sau mai multe caractere
if (parola.matches("\\d.{6,}")) {
System.out.println("Parola este validă");
}
else { System.out.println("Parola NEVALIDĂ");}
}}


Deși parola conține cel puțin o cifră și minim 6 caractere, aceasta nu trece testul de validare. Este din motiv că regex fără lookahead caută să înceapă cu o cifră, în caz contrar rezultatul este false.

Exemplu cu lookahead
class Testare{
public static void main(String [] args){
String parola = "abc123";
if (parola.matches("^(?=.*\\d).{6,}$")) {
System.out.println("Parola este validă");
}
else { System.out.println("Parola NEVALIDĂ");}
}}

Exemplu în care vom verifica dacă utilizatorul indică un email corect: 

class Testare{
public static void main(String [] args){
String email = "test@gmail.com";
if (email.matches("^[A-Za-z0-9+_.-]+@(.+)$")) {
System.out.println("Email valid");
}
else { System.out.println("Email nu este valid");}
}}

Exemple de expresii regex și destinația acestora:

.matches("^[a-zA-Z0-9_]+$") - verifică dacă expresia conține litere, cifre și underscore, util pentru validare username


.matches("^\\d{6}$") - verifică dacă șase cifre, util pentru verificarea unui cod poștal

.matches("^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d).{8,}$") - verifică dacă șirul de caractere conține cifre, litere mici, litere mari, util pentru verificarea unei parole mai complexe

.matches("^[A-Za-z].*$") - verifică dacă șirul de caractere începe cu o litera

.matches(".*\\d$") - verifică dacă șirul de caractere finisează cu o cifră

.matches("^\\d+(\\.\\d+)?$") - verifică dacă șirul de caractere  este un număr zecimal. Va accepta de exemplu 10, la fel și 10.5. Nu va accepta litere

.matches("^[A-Za-z][A-Za-z0-9_]*$") - verifică dacă șirul de caractere  începe cu o literă după care urmează litere, cifre sau semnul underscore

Expresiile regulate sunt foarte utile în programare, oferind o metodă rapidă și precisă pentru verificarea și manipularea șirurilor de caractere, astfel asigurând securitatea datelor cu care lucrează aplicația. 

Îți dorești un anumit conținut să apară în această postare? 
Vezi meniul 👉 CONTACTE 
Aștept un e-mail 💬

Succes!
❤️

luni, 16 februarie 2026

Set de probleme. Clasa StringBuilder. Clasa StringBuffer


1. Scrieți un program în care creați un obiect StringBuffer și un obiect StringBuilder cu textul "Salut" la care adăugați folosind append() numele dvs și un semn de punctuație. La final, afișați rezultatul pentru ambele obiecte. Rezultat așteptat: "Salut, [numele tău]!"

2. Scrieți un program în care creați un obiect StringBuffer și un obiect StringBuilder cu textul "Salut dragă lume", ștergeți cuvântul "dragă " folosind delete(). Afișați rezultatul pentru ambele clase. Rezultat așteptat: "Salut lume"

3. Scrieți un program în care creați un obiect StringBuffer și un obiect StringBuilder cu textul "Salut lume!". Folosiți deleteCharAt() pentru a elimina semnul de exclamare, aplicând metoda atât pe StringBuffer, cât și pe StringBuilder. Rezultat așteptat: "Salut lume"

4. Scrieți un program în care creați un obiect StringBuffer și un obiect StringBuilder cu textul "Buna ziua". Înlocuiți "ziua" cu "seara" folosind replace(). Afișați rezultatul pentru ambele clase. Rezultat așteptat: "Buna seara"

5. Scrieți un program în care creați un obiect StringBuffer și un obiect StringBuilder cu textul "Java". Folosiți reverse() pentru a inversa șirul, aplicând metoda atât pe StringBuffer, cât și pe StringBuilder. Rezultat așteptat: "avaJ"

6. Scrieți un program în care creați un obiect StringBuffer și un obiect StringBuilder cu textul "Salut lume. Eu programez în Java". Afișați caracterul aflat la poziția pe o anumită poziție folosind metoda charAt() pentru ambele clase.

7. Scrieți un program în care creați un obiect StringBuffer și un obiect StringBuilder cu textul "salut lume". Folosiți metoda setCharAt() pentru a schimba prima literă în majusculă, atât pentru StringBuffer, cât și pentru StringBuilder. Rezultat așteptat: "Salut lume"

8. Scrieți un program în care creați un obiect StringBuffer și un obiect StringBuilder cu textul "Programare Java". Extrageți cu ajutorul metodei substring() doar cuvântul "Java" pentru ambele clase.

9. Scrieți un program în care creați un obiect StringBuffer și un obiect StringBuilder în baza unui text citit de la tastatură. Afișați la ecran, folosind metoda length() câte caractere are textul citit.

10. Scrieți un program în care creați un obiect StringBuffer și un obiect StringBuilder cu textul "Salut". Afișați capacitatea inițială. Apoi adăugați mai multe caractere. Afișați capacitatea după modificarea textului. Observați cum se schimbă capacitatea pentru ambele clase.

11. Scrieți un program în care creați un obiect StringBuffer și un obiect StringBuilder cu textul "Invat programare". Introduceți cuvântul „Java ” după cuvântul „Invat ” folosind metoda insert(). Adăugați punct la final folosind metoda append(). Afișați rezultatul. Încercați să utilizați apelul în lanț al metodelor.

12. Un elev a stocat o listă de teme pentru acasă într-un șir de caractere:

tema1: matematica, tema2: informatica, tema3: fizica

Scrieți un program în care să utilizați StringBuilder sau StringBuffer pentru a obține la afișare:

TEMA1: MATEMATICA | TEMA2: INFORMATICA | TEMA3: FIZICA

Pentru aceasta:
- Transformă fiecare temă în majuscule.
- Înlocuiește virgulele cu simbolul |.
- Afișează rezultatul final.

13. Un magazin online a stocat titlurile comenzilor într-un șir de caractere:

comanda1: telefon, comanda2: laptop, comanda3: tableta

Scrieți un program în care să utilizați fie StringBuilder, sau StringBuffer pentru a obține la afișare:

Comanda3: TABLETA | Comanda2: LAPTOP | Comanda1: TELEFON

Pentru aceasta:
- Eliminați spațiile inutile de la început și sfârșit folosind trim().
- Inversați ordinea comenzilor folosind reverse().
- Transformați numele produselor în majuscule.
- Înlocuiți virgulele cu simbolul |.


Succes!
💓

marți, 10 februarie 2026

Conceptul de încapsularea datelor

Încapsularea este un principiu fundamental al programării orientate pe obiecte (POO).

Ea înseamnă gruparea datelor (atribute) și a metodelor (funcții) într-o clasă, dar mai ales protejarea datelor interne și oferirea unui acces controlat la acestea.

Așa cum se vede și în imagine, ne putem imagina clasa ca o cutie închisă: datele din interior sunt ascunse, dar accesul se face doar prin „uși speciale” controlate  – getter și setter.

Pentru a controla accesul la date și metode, folosim modificatori de acces:

  • public – acces liber, din orice clasă
  • private – acces doar în interiorul clasei
  • protected – acces în interiorul clasei și în același pachet (sau în clase derivate)
  • fără modificator de acces - acces doar în interiorul clasei și în pachetul în care face parte clasa respectivă.

Prin acești modificatori noi decidem cine are voie să vadă sau să modifice datele.

Datele importante sau sensibile trebuie să fie private, pentru a nu fi modificate direct, fie intenționat, fie accidental. Astfel, le protejăm și creștem siguranța informațiilor.

De exemplu:

class ContBancar {
private String numarCont; // acces doar în clasa ContBancar
public String titular; // acces oriunde
protected double sold; // acces în clasa ContBancar și în același pachet
}

Pentru a lucra cu atributele private, folosim metode speciale numite getter și setter pentru a proteja datele și a nu le modifica direct din exteriorul clasei:

  • Getter – citește valoarea unui atribut privat și o returnează.
  • Setter – modifică valoarea unui atribut privat, controlat, numaidecât cu validare.

Astfel:

  • protejăm datele,
  • prevenim valori greșite,
  • menținem codul sigur și corect.

De exemplu:

class ContBancar {
private String numarCont;
public String titular;
protected double sold;

public ContBancar(String numarCont, String titular, double sold) {
this.numarCont = numarCont;
this.titular = titular;
this.sold = sold;
}

// Getter pentru numarCont
public String getNumarCont() {
return numarCont;
}

// Getter pentru sold
public double getSold() {
return sold;
}

// Setter pentru sold cu validare
public void setSold(double suma) {
if(suma >= 0) {
sold = suma;
}
else {
System.out.println("Suma nu poate fi negativa!");
}
}}


Pentru a asigura corectitudinea și siguranța informațiilor, respectăm câteva reguli simple:

  1. Datele importante trebuie să fie private
  2. Accesul se face prin metode publice controlate, getter și setter
  3. Setter-ii permit verificarea și validarea datelor înainte să le modificăm, astfel datele incorecte nu se salvează
  4. Programul poate afișa mesaje de eroare în cazul în care nu este promovată validarea datelor.

Exemplu: 

public class Elev {
    private int nota;

public void setNota(int n) {
if(n >= 1 && n <= 10) {
nota = n;
} else {
System.out.println("Nota trebuie să fie între 1 și 10!");
}
}

public int getNota() {
return nota;
}
}
În acest exemplu, atributul nota este declarat private, deci nu poate fi accesat sau modificat direct din afara clasei. Metoda setNota() este un setter și permite modificarea controlată a notei. Înainte de a salva valoarea, metoda verifică dacă nota este între 1 și 10. Dacă valoarea nu este corectă, nota nu se schimbă și se afișează un mesaj de eroare. Metoda getNota() este un getter și permite citirea valorii notei fără a o modifica. 

Pe scurt, încapsularea ne învață să avem grijă de datele noastre din program, exact ca în viața reală. Nu lăsăm pe oricine să modifice informații importante, ci oferim acces doar prin reguli clare. Folosind modificatori de acces, getter și setter, codul devine mai sigur, mai ordonat și mai ușor de înțeles.

Succes!

❤️

luni, 9 februarie 2026

Tipuri de relații între obiecte. Set de probleme

1. Un magazin comercializează diferite produse electronice. Pentru a gestiona aceste produse, se dorește realizarea unei aplicații în Java. Proiectați în UML clasele. Despre produse se cunosc următoarele. Fiecare produs are denumire și preț. Există două tipuri de produse:
- Laptop, care are ca caracteristică specifică memorie RAM
- Telefon, care are ca caracteristică specifică capacitate baterie.
Creați un sistem în care:
- Definiți clasele Produs, Laptop, Telefon și stabiliți în ce relație se află acestea.
- Definiți atributele și constructori pentru toate clasele.
- Adăugați claselor metoda afisare() pentru a afișa informațiile despre clase
- În metoda main(), instanțiați clasele Laptop și Telefon și afișați informația despre fiecare.

2. O platformă online gestionează cursuri și instructori. Pentru organizarea activității, se dorește realizarea unei aplicații în Java. Proiectați în UML clasele. Despre entități se cunosc următoarele:
- fiecare instructor are nume și specializare
- fiecare curs are titlu și durată.
Platforma are denumire instructor și cursuri.
Creați un sistem în care:
- Definiți clasele Instructor, Curs și Platforma și stabiliți relația dintre acestea.
- Definiți constructori pentru toate clasele.
- Adăugați claselor metoda afisare() pentru a afișa informațiile despre obiecte.
- În metoda main(), creați mai mulți instructori și cursuri, apoi o platformă și asociați aceste obiecte.
- Afișați informația despre platformă, instructorii și cursurile disponibile.

3. Un calculator este format din componente interne. Pentru a simula structura unui calculator, se dorește realizarea unei aplicații în Java. Proiectați în UML clasele. Se cunoaște că fiecare componentă are denumire și specificații. Un calculator are model și conține componente (procesor, memorie RAM, hard disk).
Creați un sistem în care:
- Definiți clasele Componenta și Calculator și stabiliți relația dintre acestea.
- Definiți constructori pentru toate clasele.
- Adăugați claselor metoda afisare() pentru a afișa informațiile despre obiecte.
- În clasa Calculator, creați componentele (în constructor).
- În metoda main(), creați un obiect de tip Calculator.
- Afișați informația despre calculator și componentele sale.

4. Un Smartwatch este format din componente electronice integrate. Pentru a simula structura unui ceas inteligent, se dorește realizarea unei aplicații în Java. Proiectați în UML clasele. Se cunoaște că fiecare componentă are denumire și consum energetic. Un ceas are model și conține componente (ecran, baterie, senzor).
Creați un sistem în care:
- Definiți clasele Componenta și Smartwatch și stabiliți relația dintre acestea.
- Definiți constructori pentru toate clasele.
- Adăugați claselor metoda afisare() pentru a afișa informațiile despre obiecte.
- În clasa Smartwatch, creați componentele (în constructor).
- În metoda main(), creați un obiect de tip Smartwatch.
- Afișați informația despre ceas și componentele sale.

5. Un spital colaborează cu medici specialiști care pot activa și în alte clinici. Pentru a simula structura unui cabinet medical, se dorește realizarea unei aplicații în Java. Proiectați în UML clasele. Se cunoaște că fiecare Medic are nume și specializare. Un Cabinet are denumire și colaborează cu medici (un tablou de obiecte).
Creați un sistem în care:
- Definiți clasele Medic și Cabinet și stabiliți relația dintre acestea.
- Definiți constructori pentru toate clasele (constructorul clasei Cabinet primește tabloul de medici).
- Adăugați claselor metoda afisare() pentru a afișa informațiile despre obiecte.
- În clasa Cabinet, parcurgeți tabloul de medici pentru a le afișa datele.
- În metoda main(), creați obiectele de tip Medic independent de cabinet.
- Transmiteți tabloul de medici la crearea obiectului de tip Cabinet și afișați informația completă.

6. O Facultate este formată dintr-un grup de angajați care pot activa și în alte instituții. Pentru a simula structura academică, se dorește realizarea unei aplicații în Java. Proiectați în UML clasele. Se cunoaște că există o superclasă Persoana cu nume și prenume. Din aceasta derivă clasa Profesor care are în plus titlu academic. O Facultate are denumire și conține profesori (un tablou de obiecte).
Creați un sistem în care:
- Definiți superclasa Persoana și subclasa Profesor, stabilind relația de moștenire.
- Definiți clasa Facultate și stabiliți relația de agregare cu clasa Profesor.
- Definiți constructori pentru toate clasele.
- Adăugați claselor metoda afisare() pentru a afișa informațiile despre obiecte.
- În clasa Facultate, parcurgeți tabloul de profesori pentru a le afișa datele complete (nume, prenume și titlu).
- În metoda main(), creați 3 obiecte de tip Profesor în mod independent (ca entități separate).
- Creați un tablou cu acești profesori și transmiteți-l ca parametru la crearea obiectului de tip Facultate.
- Afișați informația despre facultate și lista membrilor corpului didactic.

Succes! 
❤️

joi, 5 februarie 2026

Tip de date șir de caracter. Clasa String

String-urile, numite șiruri de caractere, sunt pe larg utilizate în  orice limbaj de programare, și reprezintă o succesiune finită de caractere (litere, cifre, simboluri), tratată ca un singur obiect.

În Java string-urile sunt considerate obiecte, adică sunt de tip referință.
 
Una din clasele Java ce permit prelucrarea șirurilor de caractere este clasa String.

Definiție:
public final class String extends Object
implements Serializable, Comparable<String>, CharSequence


Descriere:
Clasa String se află în pachetul java.lang și este utilizată pentru crearea și prelucrarea șirurilor de caractere. Este o clasă închisă spre modificare (immutable), adică o clasă obiectele căreia nu se modifică. Orice valoare atribuită  obiectului rămâne în sistem creând astfel a mulțime de obiecte neutilizate. 

Pentru a crea un șir de caractere puteți utiliza sintaxa:
String identificator = ”Valoare”;
De exempluString zi = ”Luni”;

Ori de cîte ori compilatorul găsește un literal String în codul sursă acesta crează un obiect de tipul clasei String ce va conține ca valoare literalul.

La fel ca și în cazul celorlalte obiecte, puteți folosi constructorul clasei String pentru a crea o instanță a acestei clase.
De exempluString zi = new String(”Luni”);
 
Metode:
a) char charAt(int index) - returnează caracterul ce se află pe poziția index. Indicele caracterului din șir variază de la 0 la length()-1.

De exemplu:
String s = "Java";
System.out.println(s.charAt(1)); //a

b) public boolean equals(Object unObiect) returnează true dacă obiectul curent este echivalent ca valoare cu string-ul unObiect, în caz contrar returnează false. Se ține cont de litere mari și mici.

De exemplu:
String s = "Java";
String s1 = "Java";
String s2 = "java";
System.out.println(s.equals(s1)); //true
System.out.println(s.equals(s2)); //false

c) public boolean equalsIgnoreCase(String altString) - returnează true dacă obiectul curent este echivalent ca valoare cu string-ul altString, în caz contrar returnează false. Nu se ține cont de litere mari si mici.  

De exemplu:
String s = "Java";
String s1 = "java";
String s2 = "Java";
System.out.println(s.equalsIgnoreCase(s1));
//true
System.out.println(s.equalsIgnoreCase(s2)); //true

Notă!  
Operatorul == aplicat asupra a două șiruri de caractere nu va verifica egalitatea acestora ci identitatea șirurilor, adică se vor compara referințele și se va returna true dacă acestea vor fi egale. Se va  verifica dacă cele două șiruri indică unul și același obiect.

De exemplu:
String s = "Java";
String s1 = "POO";
String s2 = s;
System.out.println(s==s1);
//false
System.out.println(s2==s); //true

d. public int length()- returnează lungimea șirului de caractere.  

De exemplu:
String s = "Java";
System.out.println(s.length()); //4

e. public boolean isEmpty()  - returnează true dacă  și numai dacă length() este 0

De exemplu:
String s = "Java" ;
String s2 = "";
System.out.println(s.isEmpty());
// false
System.out.println(s2.isEmpty()); // true

f. public boolean startsWith(String prefix, int toffset) - verifică dacă substrigul din șirul dat începînd cu poziția toffset începe cu prefixul prefix.

De exemplu:
String s = "Programare" ;
System.out.println(s.startsWith("ram", 3));  //false
System.out.println(s.startsWith("ram", 4));  
//true
System.out.println(s.startsWith("ram", 10)); //false
System.out.println(s.startsWith("ram", -3)); //false

g. public boolean startsWith(String prefix)- verifică dacă șirul dat începe cu prefixul prefix.

De exemplu:
String s = "Programare" ;
System.out.println(s.startsWith("Prog"));
//true
System.out.println(s.startsWith("ram")); //false

h. public boolean endsWith(String suffix)- verifică dacă șirul dat finisează cu sufixul suffix.

De exemplu:
String s = "Programare" ;
System.out.println(s.endsWith("re"));
//true

i. public int indexOf(String ch)- Returnează indicele caracterului ch  în cadrul unui șir de caractere.

De exemplu:
String s = "Programare" ;
System.out.println(s.indexOf("r"));
//1
System.out.println(s.indexOf("b")); //-1
System.out.println(s.indexOf("P")); //0
System.out.println(s.indexOf("p")); //-1

j. public int lastIndexOf(String ch) - Returnează indicele ultimei apariții a caracterului ch în cadrul unui șir de caractere.

De exemplu:
String s = "Programare";
System.out.println(s.lastIndexOf("r"));
//8
System.out.println(s.lastIndexOf("b")); //-1
System.out.println(s.lastIndexOf("o")); //2

k. public String concat(String str)– concatinează două șiruri de caractere.

De exemplu:
String s = "programez in " ;
String s1 = " Java" ;
s.concat(s1);
System.out.println(s);
// programez
String s3 = s.concat(s1);
System.out.println(s3); // programez in Java
System.out.println("Eu ".concat(s3)+" azi"); //Eu programez in Java azi

l. public String replace(char oldChar, char newChar) - returnează un string rezultat din înlocuirea tuturor aparițiilor caracterelor specificate în oldChar prin newChar.   

De exemplu:
String s = "tata";
System.out.println(s.replace("t", "m"));
//mama
System.out.println("Ei pleaca".replace("Ei", "Ele")); //Ele pleaca

m. public boolean contains(CharSequence s)– returnează true daca și numai dacă șirul de caractere conține secvența căutată specificată prin s.

De exemplu:
String s = "Programez in Java";
System.out.println(s.contains("Java"));
//true
System.out.println("Ei pleaca".contains("Ele")); //false

n. public String toLowerCase()- Convertește toate literele șirului de caractere în litere mici.

De exemplu:
String s = "Programez";
System.out.println(s.toLowerCase());
//programez
System.out.println("Ei pleaca".toLowerCase()); //ei pleaca

o. public String toUpperCase()- Convertește toate literele șirului de caractere în litere mari.

De exemplu:
String s = "Programez";
System.out.println(s.toUpperCase());
//PROGRAMEZ
System.out.println("in java".toUpperCase()); //IN JAVA

p. public String substring(int beginIndex)- returnează un subșir din șirul asupra căruia s-a apelat metoda începând cu indexul elementului din șir specificat prin beginIndex.

De exemplu:
String s = "Programez";
System.out.println(s.substring(3)); // gramez
System.out.println(s.substring(-1)); 
// StringIndexOutOfBoundsException
System.out.println(s.substring(9)); // nu se afiseaza nimic

q. substring(int IndexInitial, int IndexFinal)- returnează un subșir din șirul asupra căruia s-a apelat metoda data începând cu  caracterul aflat pe poziția IndexInitial până la caracterul cu indicele IndexFinal.

De exemplu:
String s = "Programez";
System.out.println(s.substring(0,7)); // Program
System.out.println(s.substring(0,10)); //StringIndexOutOfBoundsException
System.out.println(s.substring(1,1)); // nu se afiseaza nimic
System.out.println(s.substring(3,1)); 
// StringIndexOutOfBoundsException

r. public String trim() - întoarce o copie a șirului fără spațiile de la începutul și sfârșitul șirului.  

De exemplu:
String s = " Programez ";
String s1 = "Programez";
System.out.println(s.equals(s1));
//false
System.out.println(s.trim().equals(s1)); //true

s. boolean Character.isDigit(char c)– verifică dacă caracterul c este o cifră (0–9). Returnează true dacă este cifră și false în caz contrar.

De exemplu:
char c = '5';
System.out.println(Character.isDigit(c)); // true
char c = 'A';
System.out.println(Character.isDigit(c)); // false

t. boolean Character.isUpperCase(char c) – verifică dacă caracterul c este o literă mare. Returnează true dacă este literă mare și false în caz contrar.

De exemplu:
char c = 'J';
System.out.println(Character.isUpperCase(c)); // true
char c = 'j';
System.out.println(Character.isUpperCase(c)); // false

u. boolean Character.isLowerCase(char c) – verifică dacă caracterul c este o literă mică. Returnează true dacă este literă mică și false în caz contrar.

De exemplu:
char c = 'a';
System.out.println(Character.isLowerCase(c)); // true
char c = 'A';
System.out.println(Character.isLowerCase(c)); // false

Aceste metode nu aparțin clasei String, ci clasei Character, dar sunt utilizate frecvent împreună cu String.charAt(), atunci când analizăm caracterele unui șir. De exemplu: 
String text = "Java2026";

// parcurgem fiecare caracter din șir
for (int i = 0; i < text.length(); i++) {
    char c = text.charAt(i);

    System.out.print(c + " -> ");

    if (Character.isUpperCase(c)) {
        System.out.println("literă mare");
    } else if (Character.isLowerCase(c)) {
        System.out.println("literă mică");
    } else if (Character.isDigit(c)) {
        System.out.println("cifră");
    } else {
        System.out.println("alt caracter");
    }
}

Deci:
  • charAt() extrage un caracter dintr-un String;
  • Character.isDigit(), isUpperCase(), isLowerCase() analizează caracterul extras.

Rețineți ! 
A se acorda o deosebită atenție atunci când lucrați cu operatorul de concatenare +. Se va ține cont de următoarele reguli:
1. Dacă ambii operanzi sunt numerici operatorul + va efectua operația de adunare.
2. Dacă unul din operanzi este String operatorul + va efectua concatenarea.
3. Expresia este evaluată de la stânga la dreapta.

De exemplu:
String s1 = "Hello";
int a = 3;
String s2 ="4";
String s3 ="4";
System.out.println(a+s1); // 3Hello
System.out.println(s1+a); // Hello3
System.out.println(s2+s3); // 44
System.out.println(1+2); // 3
System.out.println("a"+"b"); // ab
System.out.println("a"+3); // a3
System.out.println("a"+3+4); // a34
System.out.println(3+"a"); // 3a
System.out.println(3+4+"a"+6+1); // 7a61
System.out.println("a"+6+1); // a61
System.out.println(6+1+"a"); // 7a


Restricții impuse de limbaj

Obiectele de tip String sunt imutabile adică conținutul nu poate fi modificat după creare

String s = "abc";
s = s + "d";
// se creează un obiect nou

Accesarea caracterelor se face doar prin metode, nu prin index direct:
char c = s.charAt(0);
 
Metode pentru conversii

String t = String.valueOf(456); - convertește valoarea de tip întreg în șir de caractere

int x = Integer.parseInt("123"); - convertește un șir de caractere în valoare întreagă.