1. StringTokenizerclasa

Și acum câteva scenarii mai comune care implică lucrul cu șiruri. Cum împărțiți un șir în mai multe părți? Există mai multe moduri de a face acest lucru.

split()metodă

Prima modalitate de a împărți un șir în mai multe părți este să utilizați split()metoda. O expresie regulată care definește un șir special de delimitare trebuie să fie transmisă ca argument. Veți afla ce este o expresie regulată în misiunea Java Multithreading .

Exemplu:

Cod Rezultat
String str = "Good news everyone!";
String[] strings = str.split("ne");
System.out.println(Arrays.toString(strings));
Rezultatul va fi o matrice de trei șiruri de caractere:
["Good ", "ws everyo", "!"]

Simplu, dar uneori această abordare este excesivă. Dacă există o mulțime de delimitatori (de exemplu, spații, caractere newline, tab-uri, puncte), atunci trebuie să construiți o expresie regulată destul de complexă. Este greu de citit și deci greu de modificat.

StringTokenizerclasă

Java are o clasă specială a cărei sarcină este de a împărți un șir în subșiruri.

Această clasă nu folosește expresii regulate: în schimb, pur și simplu treceți un șir format din delimitatori. Avantajul acestei abordări este că nu rupe întregul șir în bucăți dintr-o dată, ci se mișcă de la început la sfârșit pe rând.

Clasa are un constructor și două metode importante. Transmitem constructorului un șir pe care îl împărțim în părți și un șir format dintr-un set de caractere delimitare.

Metode Descriere
String nextToken()
Returnează următorul subșir
boolean hasMoreTokens()
Verifică dacă există mai multe subșiruri.

Această clasă amintește cumva de clasa Scanner, care are nextLine()și hasNextLine()metode.

Puteți crea un StringTokenizerobiect cu această comandă:

StringTokenizer name = new StringTokenizer(string, delimiters);

Unde stringeste șirul care trebuie împărțit în părți. Și delimiterseste un șir, iar fiecare caracter din el este tratat ca un delimitator. Exemplu:

Cod Ieșire de consolă
String str = "Good news everyone!";

StringTokenizer tokenizer = new StringTokenizer(str,"ne");
while (tokenizer.hasMoreTokens())
{
   String token = tokenizer.nextToken();
   System.out.println(token);
}
Good 
ws 
v
ryo
!

Rețineți că fiecare caracter din șir transmis ca al doilea șir către StringTokenizerconstructor este considerat un separator.



2. String.format()metoda si StringFormatterclasa

O altă metodă interesantă a clasei String este format().

Să presupunem că aveți diverse variabile care stochează date. Cum le afișați pe ecran într-o singură linie? De exemplu, avem câteva date (coloana din stânga) și rezultatul dorit (coloana din dreapta):

Cod Ieșire de consolă
String name = "Amigo";
int age = 12;
String friend = "Diego";
int weight = 200;
User = {name: Amigo, age: 12 years, friend: Diego, weight: 200 kg.}

Codul dvs. va arăta probabil cam așa:

Cod program
String name = "Amigo";
int age = 12;
String friend = "Diego";
int weight = 200;

System.out.println("User = {name: " + name + ", age:" + age + " years, friend: " + friend+", weight: " + weight + " kg.}");

Un astfel de cod nu este foarte lizibil. Și dacă numele variabilelor ar fi mai lungi, atunci codul ar deveni și mai dificil:

Cod program

class User {
    ......
    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public List<String> getFriends() {
        return friends;
    }

    public ExtraInformation getExtraInformation() {
        return extraInformation;
    }
}

User user = new User();

System.out.println("User = {name: " + user.getName() + ", age:" + user.getAge() + " years, friend: " + user.getFriends().get(0) + ", weight: " + user.getExtraInformation().getWeight() + " kg.}");

Nu foarte lizibil, nu-i așa?

Dar aceasta este o situație comună în programele din lumea reală, așa că vreau să vă spun despre o modalitate de a scrie acest cod mai simplu și mai concis.

String.format

Clasa String are o format()metodă statică: vă permite să specificați un model pentru asamblarea unui șir cu date. Aspectul general al comenzii este următorul:

String name = String.format(pattern, parameters);

Exemplu:

Cod Rezultat
String.format("Age=%d, Name=%s", age, name);
Age=12, Name=Amigo
String.format("Width=%d, Height=%d", width, height);
Width=20, Height=10
String.format("Fullname=%s", name);
Fullname=Diego

Primul format()parametru al metodei este un șir de format care conține tot textul dorit împreună cu caractere speciale numite specificatori de format (cum ar fi %dși %s) în locurile în care trebuie să inserați date.

Metoda format()înlocuiește aceștia %sși %dspecificatorii de format cu parametrii care urmează șirul de format din lista de parametri. Dacă vrem să inserăm un șir, atunci scriem %s. Dacă dorim să inserăm un număr, atunci specificatorul de format este %d. Exemplu:

Cod Rezultat
String s = String.format("a=%d, b=%d, c=%d", 1, 4, 3);
seste egal cu"a=1, b=4, c=3"

Iată o listă scurtă de specificatori de format care pot fi utilizați în interiorul șirului de format:

Specificator Sens
%s
String
%d
interger: byte, short, int,long
%f
număr real: float,double
%b
boolean
%c
char
%t
Date
%%
%caracter

Acești specificatori indică tipul datelor, dar există și specificatori care indică ordinea datelor. Pentru a obține un argument după numărul său (numerotarea începe de la unu), trebuie să scrieți " " în loc de " ". Exemplu:%1$d%d

Cod Rezultat
String s = String.format("a=%3$d, b=%2$d, c=%d", 11, 12, 13);
seste egal cu"a=13, b=12, c=11"

%3$dva primi al treilea argument, %2$dva primi al doilea argument și %dva primi chiar primul argument. Specificatorii de format %sși %dse referă la argumente, indiferent de specificatorii precum %3$dsau%2$s



3. String Pool

Fiecare șir specificat în cod ca șir literal este stocat într-o zonă de memorie numită în StringPooltimp ce programul rulează. StringPooleste o matrice specială pentru stocarea șirurilor de caractere. Scopul său este de a optimiza stocarea șirurilor:

În primul rând, șirurile specificate în cod trebuie să fie stocate undeva, nu? Codul constă din comenzi, dar datele (în special, șiruri mari) trebuie să fie stocate în memorie separat de cod. În cod apar doar referințe la obiecte șir.

În al doilea rând, toate literalele șir identice trebuie să fie stocate în memorie o singură dată. Și așa funcționează. Când codul dvs. de clasă este încărcat de mașina Java, toate literalele șir sunt adăugate la StringPooldacă nu sunt deja acolo. Dacă sunt deja acolo, atunci pur și simplu folosim o referință șir din StringPool.

În consecință, dacă atribuiți același literal mai multor Stringvariabile din codul dvs., atunci aceste variabile vor conține aceeași referință. O singură dată va fi adăugat un literal StringPool. În toate celelalte cazuri, codul va primi o referință la șirul deja încărcat în fișierul StringPool.

Iată aproximativ cum funcționează:

Cod Lucrul cu StringPool
String a = "Hello";
String b = "Hello";
String c = "Bye";
String[] pool = {"Hello", "Bye"};
a = pool[0];
b = pool[0];
c = pool[1];

De aceea variabilele ași bvor stoca aceleași referințe.

intern()metodă

Și cea mai bună parte este că puteți adăuga în mod programatic orice șir la fișierul StringPool. Pentru a face acest lucru, trebuie doar să apelați metoda Stringvariabilei intern().

Metoda intern()va adăuga șirul la StringPooldacă nu este deja acolo și va returna o referință la șirul în fișierul StringPool.

Dacă două șiruri identice sunt adăugate la metoda StringPoolfolosind intern(), metoda returnează aceeași referință. Acesta poate fi folosit pentru a compara șiruri prin referință. Exemplu:

Cod Notă
String a = new String("Hello");
String b = new String("Hello");
System.out.println(a == b);


false
String a = new String("Hello");
String b = new String("Hello");

String t1 = a.intern();
String t2 = b.intern();
System.out.println(a == b);
System.out.println(t1 == t2);





false
true

Este puțin probabil să utilizați această metodă des, dar oamenilor le place să întrebe despre ea în interviuri . Deci este mai bine să știi despre asta decât să nu știi.