Noutati despre interfete web si interfete evoluate

joi, 20 noiembrie 2008

Adunarea a doua siruri in Java

La cererea expresa a lui Florin si contrar vointei acestuia, subiectul primului meu post pentru proiectul de la cursul Interfete Evoluate va fi despre un lucru aparent banal: concatenarea a doua siruri in Java.

Operatia de adunare (concatenare) a doua siruri este una foarte raspandita in aplicatiile Java normale. Insa aceasta creaza probleme din cauza faptului ca obiectul String este imutabil. Practic, din adunarea a doua obiecte de tip String, va rezulta o noua instanta, complet diferita de primele doua. In codul compilat (adica in fisierul .class), acest lucru se face prin instantierea clasei StringBuilder si apelarea metodei append. Mai exact, daca vom scrie intr-o functie urmatoarea secventa de cod:


String s1 = "a";
String s2 = "b";
String s3 = s1 + s2;


Ea va fi compilata in:

String s1 = "a";
String s2 = "b";
String s3 = (new StringBuilder(String.valueOf(s1))).append(s2).toString();


Ca observatie, StringBuilder-ul este folosit doar de la Java 1.5. In versiunile mai vechi (care, din pacate inca se mai intalnesc...) se utilizeaza StringBuffer.

Este evident faptul ca apelul String.valueOf este inutil deoarece s1 este nenul (valueOf cu parametru de tip Object, intoarce sirul "null" daca parametrul este nul sau apeleaza functia toString() a obiectului daca acesta este nenul). De asemenea, in cazul in care o asemenea operatie se face des, cum ar fi intr-un ciclu, atunci este mai bine sa se reutilizeze instanta StringBuilder. Mai exact, daca avem urmatoarea secventa de cod:

for (int i=0; i<100; i++) {
String s1 = "a";
String s2 = "b";
String s3 = s1 + s2;
}

ea va fi compilata in:

for (int i=0; i<100; i++) {
String s1 = "a";
String s2 = "b";
String s3 = new StringBuilder(String.valueOf(s1)).append(s2).toString();
}

Evident, acest cod poate fi optimizat in felul urmator (facem abstractie de modul in care functioneaza instantierea obiectelor in Java):

StringBuilder buffer = new StringBuilder();
for (int i=0; i<100; i++) {
String s1 = "a";
String s2 = "b";
buffer.setLength(0);
String s3 = buffer.append(s1).append(s2).toString();
}


Ca incheiere, vreau sa mai adaug doar ca incepand cu Java 1.5, StringBuilder si StringBuffer au un parinte comun, AbstractStringBuilder (aici ma refer la JDK-ul de la Sun). Practic, in clasa abstracta sunt implementate toate operatiile, iar StringBuilder si StringBuffer actioneaza doar ca niste wrapper-e. Diferenta dintre cele doua clase este data de faptul ca StringBuffer este thread-safe deoarece apelurile sale sunt marcate ca synchronized.

Ionut

0 comentarii:

Arhivă blog