Java Language Confronto di stringhe


Esempio

Per confrontare le stringhe per l'uguaglianza, è necessario utilizzare i metodi equals o equalsIgnoreCase dell'oggetto String.

Ad esempio, il seguente snippet determinerà se le due istanze di String sono uguali su tutti i caratteri:

String firstString = "Test123";
String secondString = "Test" + 123;

if (firstString.equals(secondString)) {
   // Both Strings have the same content.
}

Dimostrazione dal vivo

Questo esempio li confronterà, indipendentemente dal loro caso:

String firstString = "Test123";
String secondString = "TEST123";

if (firstString.equalsIgnoreCase(secondString)) {
    // Both Strings are equal, ignoring the case of the individual characters.
}

Dimostrazione dal vivo

Si noti che equalsIgnoreCase non consente di specificare un Locale . Ad esempio, se si confrontano le due parole "Taki" e "TAKI" in inglese sono uguali; tuttavia, in turco sono diversi (in turco, il minuscolo I è ı ). Per casi come questo, la conversione di entrambe le stringhe in minuscolo (o maiuscolo) con Locale e il confronto con gli equals è la soluzione.

String firstString = "Taki";
String secondString = "TAKI";

System.out.println(firstString.equalsIgnoreCase(secondString)); //prints true

Locale locale = Locale.forLanguageTag("tr-TR");

System.out.println(firstString.toLowerCase(locale).equals(
                   secondString.toLowerCase(locale))); //prints false

Dimostrazione dal vivo


Non utilizzare l'operatore == per confrontare le stringhe

A meno che tu non possa garantire che tutte le stringhe siano state internate (vedi sotto), non devi usare gli operatori == o != Per confrontare le stringhe. Questi operatori verificano effettivamente i riferimenti e, poiché più oggetti String possono rappresentare la stessa stringa, è possibile fornire una risposta errata.

Utilizzare invece il String.equals(Object) , che confronterà gli oggetti String in base ai loro valori. Per una spiegazione dettagliata, fai riferimento a Pitfall: usando == per confrontare le stringhe .


Confronto tra stringhe in un'istruzione switch

Java SE 7

A partire da Java 1.7, è possibile confrontare una variabile String a valori letterali in un'istruzione switch . Assicurati che String non sia nullo, altrimenti genererà sempre una NullPointerException . I valori vengono confrontati usando String.equals , ovvero case sensitive.

String stringToSwitch = "A";

switch (stringToSwitch) {
    case "a":
        System.out.println("a");
        break;
    case "A":
        System.out.println("A"); //the code goes here
        break;
    case "B":
        System.out.println("B");
        break;
    default:
        break;
}

Dimostrazione dal vivo

Confronto di stringhe con valori costanti

Quando si confronta una String con un valore costante, è possibile inserire il valore costante sul lato sinistro degli equals per garantire che non si otterrà NullPointerException se l'altra stringa è null .

"baz".equals(foo)

Mentre foo.equals("baz") lancia una NullPointerException se foo è null , "baz".equals(foo) valuterà a false .

Java SE 7

Un'alternativa più leggibile consiste nell'utilizzare Objects.equals() , che esegue un controllo nullo su entrambi i parametri: Objects.equals(foo, "baz") .

( Nota: è discutibile se sia meglio evitare NullPointerExceptions in generale, o lasciarli accadere e quindi correggere la causa principale, vedere qui e qui . Certamente, chiamare la strategia di evitamento "best practice" non è giustificabile).

Ordinamenti di stringhe

La classe String implementa Comparable<String> con il metodo String.compareTo (come descritto all'inizio di questo esempio). Ciò rende l'ordinamento naturale degli oggetti String ordine con distinzione tra maiuscole e minuscole. La classe String fornisce una costante di Comparator<String> chiamata CASE_INSENSITIVE_ORDER adatta per l'ordinamento senza distinzione tra maiuscole e minuscole.

Confronto con stringhe internate

La specifica del linguaggio Java ( JLS 3.10.6 ) afferma quanto segue:

"Inoltre, una stringa letterale fa sempre riferimento alla stessa istanza della classe String poiché stringhe letterali o, più in generale, stringhe che rappresentano i valori delle espressioni costanti, vengono internate in modo da condividere istanze univoche, utilizzando il metodo String.intern . "

Ciò significa che è possibile confrontare i riferimenti a due valori letterali stringa usando == . Inoltre, lo stesso vale per i riferimenti agli oggetti String che sono stati prodotti utilizzando il metodo String.intern() .

Per esempio:

String strObj = new String("Hello!");
String str = "Hello!";

// The two string references point two strings that are equal
if (strObj.equals(str)) {
    System.out.println("The strings are equal");
}

// The two string references do not point to the same object
if (strObj != str) {
    System.out.println("The strings are not the same object");
}

// If we intern a string that is equal to a given literal, the result is
// a string that has the same reference as the literal.
String internedStr = strObj.intern();

if (internedStr == str) {
    System.out.println("The interned string and the literal are the same object");
}

Dietro le quinte, il meccanismo di interning mantiene una tabella hash che contiene tutte le stringhe internamente ancora raggiungibili . Quando si chiama intern() su una String , il metodo cerca l'oggetto nella tabella hash:

  • Se la stringa viene trovata, tale valore viene restituito come stringa internata.
  • Altrimenti, una copia della stringa viene aggiunta alla tabella hash e tale stringa viene restituita come stringa internata.

È possibile utilizzare l'interning per consentire il confronto delle stringhe utilizzando == . Tuttavia, ci sono problemi significativi con questo; vedi Pitfall - Le stringhe Internazionali in modo che tu possa usare == è una cattiva idea per i dettagli. Non è raccomandato nella maggior parte dei casi.