Compararea șirurilor în Java

1. Prezentare generală

În acest articol, vom vorbi despre diferitele moduri de a compara șirurile în Java.

Deoarece String este unul dintre cele mai utilizate tipuri de date în Java, aceasta este în mod natural o operație foarte frecvent utilizată.

2. String Comparație cu șir de clasă

2.1. Utilizarea operatorului de comparație „==”

Folosirea operatorului „==” pentru compararea valorilor textului este una dintre cele mai frecvente greșeli pe care le fac începătorii Java. Acest lucru este incorect deoarece „==” verifică doar egalitatea referențială a două șiruri , adică dacă fac referire la același obiect sau nu.

Să vedem un exemplu al acestui comportament:

String string1 = "using comparison operator"; String string2 = "using comparison operator"; String string3 = new String("using comparison operator"); assertThat(string1 == string2).isTrue(); assertThat(string1 == string3).isFalse();

În exemplul de mai sus, prima afirmație este adevărată deoarece cele două variabile indică același literal String .

Pe de altă parte, a doua afirmație este falsă, deoarece șirul 1 este creat cu un literal și șirul 3 este creat folosind noul operator - prin urmare, acestea fac referire la diferite obiecte.

2.2. Folosind egal ()

String Clasa suprascrie egal () moștenite de la obiect. Această metodă compară două șiruri caracter cu caracter, ignorând adresa acestora.

Le consideră egale dacă au aceeași lungime și caracterele sunt în aceeași ordine:

String string1 = "using equals method"; String string2 = "using equals method"; String string3 = "using EQUALS method"; String string4 = new String("using equals method"); assertThat(string1.equals(string2)).isTrue(); assertThat(string1.equals(string4)).isTrue(); assertThat(string1.equals(null)).isFalse(); assertThat(string1.equals(string3)).isFalse();

În acest exemplu, variabilele string1, string2 și string4 sunt egale deoarece au același caz și valoare, indiferent de adresa lor.

Pentru string3 , metoda returnează false, deoarece este sensibilă la majuscule și minuscule.

De asemenea, dacă oricare dintre cele două șiruri este nulă , atunci metoda returnează false.

2.3. Folosind equalsIgnoreCase ()

Metoda equalsIgnoreCase () returnează o valoare booleană. Așa cum sugerează și numele, această metodă ignoră carcasa în caractere, comparând șirurile :

String string1 = "using equals ignore case"; String string2 = "USING EQUALS IGNORE CASE"; assertThat(string1.equalsIgnoreCase(string2)).isTrue();

2.4. Folosind compareTo ()

Metoda compareTo () returnează o valoare de tip int și compară două șiruri caracter cu caracter lexicografic pe baza unui dicționar sau a unei ordonări naturale.

Această metodă returnează 0 dacă două șiruri sunt egale sau dacă ambele sunt nule, un număr negativ dacă primul șir apare înaintea argumentului și un număr mai mare decât zero dacă primul șir vine după argumentul Șir.

Să vedem un exemplu:

String author = "author"; String book = "book"; String duplicateBook = "book"; assertThat(author.compareTo(book)) .isEqualTo(-1); assertThat(book.compareTo(author)) .isEqualTo(1); assertThat(duplicateBook.compareTo(book)) .isEqualTo(0);

2.5. Folosind compareToIgnoreCase ()

CompareToIgnoreCase () este similară cu metoda anterioară, cu excepția faptului că ignoră caz:

String author = "Author"; String book = "book"; String duplicateBook = "BOOK"; assertThat(author.compareToIgnoreCase(book)) .isEqualTo(-1); assertThat(book.compareToIgnoreCase(author)) .isEqualTo(1); assertThat(duplicateBook.compareToIgnoreCase(book)) .isEqualTo(0);

3. Comparația șirurilor cu clasa de obiecte

Obiecte este o clasă de utilitate care conține o metodă static equals () , utilă în acest scenariu - pentru a compara două șiruri.

Metoda returnează adevărat dacă două șiruri sunt egale comparându-le mai întâi folosind adresa lor, adică „ ==” . În consecință, dacă ambele argumente sunt nule , returnează adevărat și dacă exact un argument este nul , returnează fals.

În caz contrar, atunci pur și simplu apelează metoda equals () a clasei de tip a argumentului trecut - care în cazul nostru este metoda clasei lui String equals () . Această metodă este sensibilă la majuscule și minuscule, deoarece apelează intern metoda lui equals () a clasei String .

Să testăm acest lucru:

String string1 = "using objects equals"; String string2 = "using objects equals"; String string3 = new String("using objects equals"); assertThat(Objects.equals(string1, string2)).isTrue(); assertThat(Objects.equals(string1, string3)).isTrue(); assertThat(Objects.equals(null, null)).isTrue(); assertThat(Objects.equals(null, string1)).isFalse();

4. Comparația șirurilor cu Apache Commons

Biblioteca Apache Commons conține o clasă de utilitate numită StringUtils pentru operațiuni legate de String ; aceasta are și câteva metode foarte benefice pentru comparația String .

4.1. Folosind equals () și equalsIgnoreCase ()

Metoda equals () a clasei StringUtils este o versiune îmbunătățită a metodei clasei String equals (), care gestionează și valori nule:

assertThat(StringUtils.equals(null, null)) .isTrue(); assertThat(StringUtils.equals(null, "equals method")) .isFalse(); assertThat(StringUtils.equals("equals method", "equals method")) .isTrue(); assertThat(StringUtils.equals("equals method", "EQUALS METHOD")) .isFalse();

Metoda equalsIgnoreCase () a StringUtils returnează o valoare booleană . Acest lucru funcționează similar cu equal (), cu excepția faptului că ignoră carcasa caracterelor din șiruri:

assertThat(StringUtils.equalsIgnoreCase("equals method", "equals method")) .isTrue(); assertThat(StringUtils.equalsIgnoreCase("equals method", "EQUALS METHOD")) .isTrue();

4.2. Folosind equalsAny () și equalsAnyIgnoreCase ()

EqualsAny () primul argument metodei este un String , iar al doilea este un multi-args tip CharSequence. Metoda returnează adevărat dacă oricare dintre celelalte șiruri date se potrivește sensibil cu primul caz String .

În caz contrar, se returnează false:

assertThat(StringUtils.equalsAny(null, null, null)) .isTrue(); assertThat(StringUtils.equalsAny("equals any", "equals any", "any")) .isTrue(); assertThat(StringUtils.equalsAny("equals any", null, "equals any")) .isTrue(); assertThat(StringUtils.equalsAny(null, "equals", "any")) .isFalse(); assertThat(StringUtils.equalsAny("equals any", "EQUALS ANY", "ANY")) .isFalse();

Metoda equalsAnyIgnoreCase () funcționează similar cu metoda equalsAny () , dar ignoră și carcasa:

assertThat(StringUtils.equalsAnyIgnoreCase("ignore case", "IGNORE CASE", "any")).isTrue();

4.3. Folosind compare () și compareIgnoreCase ()

Metoda compare () din clasa StringUtils este o versiune null-sigură a metodei compareTo () a clasei String și gestionează valorile nule considerând o valoare nulă mai mică decât o valoare non-nulă . Două valori nule sunt considerate egale.

În plus, această metodă poate fi utilizată pentru a sorta o listă de șiruri cu intrări nule :

assertThat(StringUtils.compare(null, null)) .isEqualTo(0); assertThat(StringUtils.compare(null, "abc")) .isEqualTo(-1); assertThat(StringUtils.compare("abc", "bbc")) .isEqualTo(-1); assertThat(StringUtils.compare("bbc", "abc")) .isEqualTo(1);

Metoda compareIgnoreCase () se comportă similar, cu excepția faptului că ignoră carcasa:

assertThat(StringUtils.compareIgnoreCase("Abc", "bbc")) .isEqualTo(-1); assertThat(StringUtils.compareIgnoreCase("bbc", "ABC")) .isEqualTo(1); assertThat(StringUtils.compareIgnoreCase("abc", "ABC")) .isEqualTo(0);

Cele două metode pot fi utilizate și cu o opțiune nullIsLess . Acesta este un al treilea argument boolean care decide dacă valorile nule ar trebui considerate mai mici sau nu .

O valoare nulă este mai mică decât un alt șir dacă nullIsLess este adevărat și mai mare dacă nullIsLess este fals.

Să încercăm:

assertThat(StringUtils.compare(null, "abc", true)) .isEqualTo(-1); assertThat(StringUtils.compare(null, "abc", false)) .isEqualTo(1);

Metoda compareIgnoreCase () cu un al treilea argument boolean funcționează similar, cu excepția ignorării majusculelor.

5. Concluzie

În acest tutorial rapid, am discutat diferite moduri de a compara șirurile.

Și, ca întotdeauna, codul sursă pentru exemple poate fi găsit pe GitHub.