Como eu comparo strings em Java?

724

Eu tenho usado o ==operador no meu programa para comparar todas as minhas strings até agora. No entanto, encontrei um bug, mudei um deles para o .equals()lugar e ele corrigiu o erro.

Está ==ruim? Quando deve e não deve ser usado? Qual é a diferença?

Nathan H
fonte
12
Também é bom saber que, se você estiver substituindo o método .equals (), verifique se está substituindo o método .hashcode (); caso contrário, você acabará violando a relação de equivalência entre b / w igual a e hashcode. Para mais informações, consulte java doc.
Nageswaran #
Deixando um link para minha explicação sobre por que ==funciona da maneira que funciona em Objetos: stackoverflow.com/a/19966154/2284641
Johannes H.
==funcionará algumas vezes, já que o java possui um pool de String, onde tenta reutilizar referências de memória de strings usadas com freqüência. Mas ==compara que os objetos são iguais, não os valores ... assim .equals()como o uso adequado que você deseja usar.
James Oravec
Nunca use == para testar se as Strings são iguais, a menos que você goste de rastrear erros sutis e estudar os meandros do processo de internação em Java String. "12"=="1"+2é falso (provavelmente)
Flight Odyssey

Respostas:

5562

== testes para igualdade de referência (se são o mesmo objeto).

.equals() testa a igualdade de valor (se eles são logicamente "iguais").

O Objects.equals () verifica nullantes da chamada .equals()para que você não precise (disponível no JDK7, também disponível no Guava ).

Conseqüentemente, se você quiser testar se duas seqüências têm o mesmo valor, provavelmente desejará usar Objects.equals().

// These two have the same value
new String("test").equals("test") // --> true 

// ... but they are not the same object
new String("test") == "test" // --> false 

// ... neither are these
new String("test") == new String("test") // --> false 

// ... but these are because literals are interned by 
// the compiler and thus refer to the same object
"test" == "test" // --> true 

// ... string literals are concatenated by the compiler
// and the results are interned.
"test" == "te" + "st" // --> true

// ... but you should really just call Objects.equals()
Objects.equals("test", new String("test")) // --> true
Objects.equals(null, "test") // --> false
Objects.equals(null, null) // --> true

Você quase sempre quer usar Objects.equals(). Na rara situação em que você sabe que está lidando com seqüências internas , você pode usar ==.

A partir do JLS 3.10.5. Literais de cordas :

Além disso, uma string literal sempre se refere à mesma instância da classe String. Isso ocorre porque strings literais - ou, mais genericamente, cordas que são os valores das expressões constantes ( §15.28 ) - são "internado" para instâncias exclusivas de compartilhamento, usando o método String.intern.

Exemplos semelhantes também podem ser encontrados no JLS 3.10.5-1 .

Outros métodos a considerar

String.equalsIgnoreCase () igualdade de valor que ignora maiúsculas e minúsculas.

String.contentEquals () compara o conteúdo de Stringcom o conteúdo de any CharSequence(disponível desde o Java 1.5). Evita que você tenha que transformar seu StringBuffer, etc em um String antes de fazer a comparação de igualdade, mas deixa a verificação nula para você.

Aaron Maenpaa
fonte
3
Se == verifica a igualdade de referência, por que n == 5 faz sentido? 5 não é uma variável
Hrit Roy 26/01
2
@HritRoy Porque ==verifica o valor de uma variável. Quando você tem um objeto, a variável que referencia o objeto tem a referência do objeto como valor . Assim, você compara as referências ao comparar duas variáveis ​​com ==. Ao comparar um tipo de dados primitivo, como int, ainda é o mesmo caso. Uma variável do tipo inttem o número inteiro como valor. Assim, você compara os valores de dois ints usando ==. Se intfor o valor de uma variável ou um número mágico, não importa. Além disso: Uma referência não passa de um número que se refere à memória.
akuzminykh 21/03
718

==testa referências a objetos, .equals()testa os valores da string.

Às vezes, parece que ==compara valores, porque o Java faz algumas coisas nos bastidores para garantir que seqüências de caracteres em linha idênticas sejam realmente o mesmo objeto.

Por exemplo:

String fooString1 = new String("foo");
String fooString2 = new String("foo");

// Evaluates to false
fooString1 == fooString2;

// Evaluates to true
fooString1.equals(fooString2);

// Evaluates to true, because Java uses the same object
"bar" == "bar";

Mas cuidado com os nulos!

==lida nullbem com as strings, mas chamar .equals()de uma string nula causará uma exceção:

String nullString1 = null;
String nullString2 = null;

// Evaluates to true
System.out.print(nullString1 == nullString2);

// Throws a NullPointerException
System.out.print(nullString1.equals(nullString2));

Portanto, se você sabe que fooString1pode ser nulo, diga ao leitor que, escrevendo

System.out.print(fooString1 != null && fooString1.equals("bar"));

A seguir, são mais curtos, mas é menos óbvio que ele verifique nulo:

System.out.print("bar".equals(fooString1));  // "bar" is never null
System.out.print(Objects.equals(fooString1, "bar"));  // Java 7 required
Whatsit
fonte
86
Às vezes parece como se "==" compara valores, - == fazê valores sempre comparar! (É só que certos valores são referências!)
aioobe
6
Infelizmente, não há método estático para isNullOrEmpty () e nenhuma sobrecarga personalizada de operadores, o que torna essa parte do Java mais desajeitada do que em C # ou Python. E como o Java não possui métodos de extensão, você não pode escrever seu próprio utilitário para estender o java.lang.String. Direita? Você pensa em subclassificar String, adicionando esse método utilitário estático e sempre usando MyString? Um método estático com dois parâmetros para fazer comparações com segurança nula também seria bom ter nessa subclasse.
Jon Coombs
7
O Groovy torna isso um pouco mais fácil com o operador de navegação segura ( groovy.codehaus.org/… ) ?.,. Isso seria convertido nullString1?.equals(nullString2);em uma declaração totalmente nula. No entanto, não ajuda se você tiver validString?.equals(nullString);- isso ainda gera uma exceção.
Charles Wood
5
Métodos curtos para comparar cadeias anuláveis ​​em java: stackoverflow.com/questions/11271554/…
Vadzim
5
@JonCoombs Java suporta a subclassificação e criação de método próprio. No entanto, poucas classes são marcadas como finais devido a certas razões, String é uma delas, portanto não podemos estender. Podemos criar outra classe e criar uma classe utilitária lá, que recebe duas strings como argumentos e implementa nossa lógica lá. Também para verificação nula, algumas outras bibliotecas, como spring e apache, são boas coleções de métodos, pode-se usar isso.
Pantera
442

== compara referências de objetos.

.equals() compara valores de String.

Às vezes ==dá ilusões de comparar valores de String, como nos seguintes casos:

String a="Test";
String b="Test";
if(a==b) ===> true

Isso ocorre porque quando você cria qualquer literal de String, a JVM primeiro procura por ele no pool de String e, se encontrar uma correspondência, a mesma referência será fornecida para a nova String. Por isso, obtemos:

(a == b) ===> verdadeiro

                       String Pool
     b -----------------> "test" <-----------------a

No entanto, ==falha no seguinte caso:

String a="test";
String b=new String("test");
if (a==b) ===> false

Nesse caso, para new String("test")a instrução new String será criada no heap, e essa referência será fornecida b, portanto, bserá fornecida uma referência no heap, não no pool de String.

Agora aestá apontando para uma String no pool String enquanto bestá apontando para uma String na pilha. Por isso, obtemos:

if (a == b) ===> falso.

                String Pool
     "test" <-------------------- a

                   Heap
     "test" <-------------------- b

Embora .equals()sempre compare um valor de String, ele é verdadeiro nos dois casos:

String a="Test";
String b="Test";
if(a.equals(b)) ===> true

String a="test";
String b=new String("test");
if(a.equals(b)) ===> true

Então, usar .equals()é sempre melhor.

Ganesh
fonte
3
.equals () compara as duas instâncias, porém igual é implementado para compará-las. Isso pode ou não estar comparando a saída de toString.
Jacob
3
@Jacob classe Object .equals()método compara as instâncias (referências / endereço) onde como classe String .equals()métodos é substituído para comparar conteúdo (caracteres)
Satyadev
1
É bom ressaltar as diferenças de heap do pool de strings versus Java, pois elas certamente não são as mesmas. No pool de cadeias, Java tenta "armazenar em cache" Stringobjetos para economizar espaço na memória, como Stringé conhecido por ser imutável (espero, eu digo corretamente aqui). Verifique também stackoverflow.com/questions/3052442/…
Roland
1
Esta é a resposta que eu estava procurando.
Weezy
Que ótima resposta!
alwbtc 13/04
223

O ==operador verifica se as duas cadeias são exatamente o mesmo objeto.

O .equals()método irá verificar se as duas seqüências têm o mesmo valor.

Clayton
fonte
5
Geralmente eu recomendo fortemente Apache Commons biblioteca: commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/... , java.lang.String)
Marcin Erbel
179

Strings em Java são imutáveis. Isso significa que sempre que você tenta alterar / modificar a string, você obtém uma nova instância. Você não pode alterar a sequência original. Isso foi feito para que essas instâncias de cadeia possam ser armazenadas em cache. Um programa típico contém muitas referências de cadeia e o armazenamento em cache dessas instâncias pode diminuir o espaço ocupado pela memória e aumentar o desempenho do programa.

Ao usar o operador == para comparação de cadeias, você não está comparando o conteúdo da cadeia, mas na verdade comparando o endereço de memória. Se ambos são iguais, retornará verdadeiro e falso, caso contrário. Enquanto equals in string compara o conteúdo da string.

Portanto, a questão é se todas as seqüências de caracteres estão armazenadas em cache no sistema, como ==retornos falsos, enquanto iguais retornam verdadeiros? Bem, isso é possível. Se você criar uma nova sequência como String str = new String("Testing")você acaba criando uma nova sequência no cache, mesmo que o cache já contenha uma sequência com o mesmo conteúdo. Em resumo "MyString" == new String("MyString"), sempre retornará falso.

Java também fala sobre a função intern () que pode ser usada em uma string para torná-la parte do cache, e "MyString" == new String("MyString").intern()retornará true.

Nota: == O operador é muito mais rápido do que igual apenas porque você está comparando dois endereços de memória, mas você precisa ter certeza de que o código não está criando novas instâncias de String no código. Caso contrário, você encontrará bugs.

Faisal Feroz
fonte
147
String a = new String("foo");
String b = new String("foo");
System.out.println(a == b); // prints false
System.out.println(a.equals(b)); // prints true

Certifique-se de entender o porquê. É porque a ==comparação compara apenas referências; o equals()método faz uma comparação caractere por caractere do conteúdo.

Quando você chama new para ae b, cada um recebe uma nova referência que aponta para "foo"na tabela de cadeias. As referências são diferentes, mas o conteúdo é o mesmo.

duffymo
fonte
128

Sim, é ruim ...

==significa que suas duas referências de string são exatamente o mesmo objeto. Você deve ter ouvido dizer que esse é o caso, pois o Java mantém uma espécie de tabela literal (o que ocorre), mas nem sempre é o caso. Algumas cadeias são carregadas de maneiras diferentes, construídas a partir de outras, etc., portanto, você nunca deve assumir que duas cadeias idênticas são armazenadas no mesmo local.

Igual a comparação real para você.

Uri
fonte
124

Sim, ==é ruim para comparar Strings (objetos realmente, a menos que você saiba que eles são canônicos). ==apenas compara referências a objetos. .equals()testes de igualdade. Para Strings, geralmente eles são os mesmos, mas como você descobriu, isso nem sempre é garantido.

cletus
fonte
118

Java possui um conjunto de String no qual o Java gerencia a alocação de memória para os objetos String. Consulte Pools de strings em Java

Quando você verifica (compara) dois objetos usando o ==operador, ele compara a igualdade de endereço no conjunto de cadeias. Se os dois objetos String tiverem as mesmas referências de endereço, ele retornará true, caso contrário false. Mas se você quiser comparar o conteúdo de dois objetos String, deverá substituir o equalsmétodo

equals é realmente o método da classe Object, mas é substituído na classe String e é fornecida uma nova definição que compara o conteúdo do objeto.

Example:
    stringObjectOne.equals(stringObjectTwo);

Mas lembre-se de respeitar o caso de String. Se você deseja comparar sem distinção entre maiúsculas e minúsculas, deve-se usar o método equalsIgnoreCase da classe String.

Vamos ver:

String one   = "HELLO"; 
String two   = "HELLO"; 
String three = new String("HELLO"); 
String four  = "hello"; 

one == two;   // TRUE
one == three; // FALSE
one == four;  // FALSE

one.equals(two);            // TRUE
one.equals(three);          // TRUE
one.equals(four);           // FALSE
one.equalsIgnoreCase(four); // TRUE
Saurabh Agarwal
fonte
7
Vejo que esta é uma resposta tardia à grande questão. Posso perguntar o que ele fornece que ainda não foi mencionado nas respostas existentes?
Mysticial
6
@Mysticial ele adicionou o equalsIgnoreCaseque pode ser informativo para os mais novos.
AmitG
103

Eu concordo com a resposta de Zacherates.

Mas o que você pode fazer é chamar intern()suas strings não literais.

Do exemplo de zacherates:

// ... but they are not the same object
new String("test") == "test" ==> false 

Se você internar a igualdade não literal da String é true:

new String("test").intern() == "test" ==> true 
pgras
fonte
8
Isso geralmente não é uma boa ideia. A internação é relativamente cara e pode (paradoxalmente) >> aumentar << a pegada de memória de suas JVMs e aumentar os custos de GC. Na maioria dos casos, isso supera os benefícios de desempenho do uso ==para comparação de cadeias.
Stephen C
101

==compara referências de objeto em Java e isso não é exceção para Stringobjetos.

Para comparar o conteúdo real de objectos (incluindo String), deve-se usar o equalsmétodo .

Se uma comparação de dois Stringobjetos usando ==for true, isso ocorre porque os Stringobjetos foram internados e a Java Virtual Machine está tendo várias referências apontando para a mesma instância de String. Não se deve esperar que comparar um Stringobjeto contendo o mesmo conteúdo que outro Stringobjeto usando ==para avaliar como true.

coobird
fonte
99

.equals()compara os dados em uma classe (assumindo que a função esteja implementada). ==compara a localização do ponteiro (localização do objeto na memória).

==retorna true se os dois objetos (NÃO FALANDO EM PRIMITIVOS) apontam para a mesma instância do objeto. .equals()retorna true se os dois objetos contiverem os mesmos dados equals()Versus ==em Java

Isso pode ajudá-lo.

Matt Razza
fonte
95

==executa uma verificação de igualdade de referência , se os 2 objetos (neste caso, cadeias) se referem ao mesmo objeto na memória.

O equals()método verificará se o conteúdo ou os estados de 2 objetos são iguais.

Obviamente ==é mais rápido, mas (pode) fornecer resultados falsos em muitos casos, se você quiser apenas dizer se 2 Strings contêm o mesmo texto.

Definitivamente, o uso do equals()método é recomendado.

Não se preocupe com o desempenho. Algumas coisas para incentivar o uso String.equals():

  1. Implementação das String.equals()primeiras verificações da igualdade de referência (usando ==) e, se as duas cadeias forem iguais por referência, nenhum outro cálculo será realizado!
  2. Se as referências de duas strings não forem as mesmas, String.equals()a seguir verificará o comprimento das strings. Essa também é uma operação rápida, porque a Stringclasse armazena o comprimento da string, sem a necessidade de contar os caracteres ou pontos de código. Se os comprimentos diferirem, nenhuma verificação adicional será realizada, sabemos que eles não podem ser iguais.
  3. Somente se chegarmos até aqui, o conteúdo das 2 strings será comparado e essa será uma comparação abreviada: nem todos os caracteres serão comparados, se encontrarmos um caracter incompatível (na mesma posição nas 2 strings) ), nenhum outro caractere será verificado.

Quando tudo estiver dito e feito, mesmo que tenhamos a garantia de que as strings são estagiárias, o uso do equals()método ainda não é aquele sobrecarga que se possa pensar, definitivamente a maneira recomendada. Se você deseja uma verificação de referência eficiente, use enumerações onde é garantido pela especificação e implementação da linguagem que o mesmo valor de enumeração será o mesmo objeto (por referência).

icza
fonte
2
Obviously == is faster- na verdade, a implementação das .equals(String)primeiras verificações ==antes de qualquer outra coisa, então eu diria que a velocidade é quase idêntica.
Razzle Shazl
2
public boolean equals(Object anObject) { if (this == anObject) { return true; } ...
Razzle Shazl
82

Se você é como eu, quando comecei a usar Java, queria usar o operador "==" para testar se duas instâncias de String eram iguais, mas para melhor ou para pior, essa não é a maneira correta de fazer isso em Java.

Neste tutorial, demonstrarei várias maneiras diferentes de comparar corretamente as seqüências Java, começando com a abordagem que utilizo na maioria das vezes. No final deste tutorial de comparação de seqüências Java, também discutirei por que o operador "==" não funciona ao comparar sequências Java.

Opção 1: Comparação de Java String com o método equals Na maioria das vezes (talvez 95% do tempo), comparo strings com o método equals da classe Java String, desta forma:

if (string1.equals(string2))

Esse método String equals examina as duas seqüências Java e, se elas contiverem exatamente a mesma sequência de caracteres, serão consideradas iguais.

Examinando um exemplo rápido de comparação de strings com o método equals, se o teste a seguir fosse executado, as duas strings não seriam consideradas iguais porque os caracteres não são exatamente iguais (o caso dos caracteres é diferente):

String string1 = "foo";
String string2 = "FOO";

if (string1.equals(string2))
{
    // this line will not print because the
    // java string equals method returns false:
    System.out.println("The two strings are the same.")
}

Mas, quando as duas cadeias contêm exatamente a mesma cadeia de caracteres, o método equals retornará true, como neste exemplo:

String string1 = "foo";
String string2 = "foo";

// test for equality with the java string equals method
if (string1.equals(string2))
{
    // this line WILL print
    System.out.println("The two strings are the same.")
}

Opção 2: comparação de cadeias com o método equalsIgnoreCase

Em alguns testes de comparação de cadeias, você deve ignorar se as cadeias são maiúsculas ou minúsculas. Quando você quiser testar suas seqüências de caracteres quanto à igualdade dessa maneira, não use maiúsculas e minúsculas, use o método equalsIgnoreCase da classe String, desta forma:

String string1 = "foo";
String string2 = "FOO";

 // java string compare while ignoring case
 if (string1.equalsIgnoreCase(string2))
 {
     // this line WILL print
     System.out.println("Ignoring case, the two strings are the same.")
 }

Opção 3: Comparação de Java String com o método compareTo

Há também uma terceira maneira menos comum de comparar seqüências de caracteres Java, e isso é com o método compareTo da classe String. Se as duas strings forem exatamente iguais, o método compareTo retornará um valor 0 (zero). Aqui está um exemplo rápido de como é essa abordagem de comparação de String:

String string1 = "foo bar";
String string2 = "foo bar";

// java string compare example
if (string1.compareTo(string2) == 0)
{
    // this line WILL print
    System.out.println("The two strings are the same.")
}

Enquanto escrevo sobre esse conceito de igualdade em Java, é importante observar que a linguagem Java inclui um método equals na classe Java Object básica. Sempre que você estiver criando seus próprios objetos e desejar fornecer um meio de verificar se duas instâncias do seu objeto são "iguais", você deve substituir (e implementar) esse método equals em sua classe (da mesma forma que a linguagem Java fornece esse comportamento de igualdade / comparação no método String equals).

Você pode dar uma olhada nisso ==, .equals (), compareTo () e compare ()

Mohamed E. ManSour
fonte
5
para literais de string Like String string1 = "foo bar"; String string2 = "barra de foo"; você pode usar diretamente == operador igualdade conteúdo do teste
JAVA
1
No google apps script "compareTo" não é possibe. Eu tentei instaed "é igual a" Esta foi a única solução que funciona ....
user3887038
77

Função:

public float simpleSimilarity(String u, String v) {
    String[] a = u.split(" ");
    String[] b = v.split(" ");

    long correct = 0;
    int minLen = Math.min(a.length, b.length);

    for (int i = 0; i < minLen; i++) {
        String aa = a[i];
        String bb = b[i];
        int minWordLength = Math.min(aa.length(), bb.length());

        for (int j = 0; j < minWordLength; j++) {
            if (aa.charAt(j) == bb.charAt(j)) {
                correct++;
            }
        }
    }

    return (float) (((double) correct) / Math.max(u.length(), v.length()));
}

Teste:

String a = "This is the first string.";

String b = "this is not 1st string!";

// for exact string comparison, use .equals

boolean exact = a.equals(b);

// For similarity check, there are libraries for this
// Here I'll try a simple example I wrote

float similarity = simple_similarity(a,b);
Khaled.K
fonte
6
Como isso difere de outras respostas? e por que fazê-lo da maneira que você sugere
user151019
2
@ Mark A pergunta na diferença entre ==e equalsjá foi respondido por outras soluções, eu só ofereceu uma maneira diferente para comparar strings de uma forma solta
Khaled.K
77

O ==operador verifica se as duas referências apontam para o mesmo objeto ou não. .equals()verifique o conteúdo real da string (valor).

Observe que o .equals()método pertence à classe Object(superclasse de todas as classes). Você precisa substituí-lo conforme o requisito da classe, mas para String ele já está implementado e verifica se duas cadeias têm o mesmo valor ou não.

  • Caso 1

    String s1 = "Stack Overflow";
    String s2 = "Stack Overflow";
    s1 == s2;      //true
    s1.equals(s2); //true

    Motivo: literais de string criados sem nulo são armazenados no pool de String na área permgen da pilha. Portanto, s1 e s2 apontam para o mesmo objeto no pool.

  • Caso 2

    String s1 = new String("Stack Overflow");
    String s2 = new String("Stack Overflow");
    s1 == s2;      //false
    s1.equals(s2); //true

    Motivo: se você criar um objeto String usando a newpalavra-chave, um espaço separado será alocado a ele no heap.

Aniket Thakur
fonte
53

==compara o valor de referência dos objetos, enquanto o equals()método presente na java.lang.Stringclasse compara o conteúdo do Stringobjeto (para outro objeto).

samkit shah
fonte
15
para não ser exigente, mas o equals()método para Stringestá na Stringclasse, não na Object. O padrão equals()em Objectnão compararia se o conteúdo é o mesmo e, de fato, retorna true quando a referência é a mesma.
precisa
1
@ JacobSchoen: O link acima não funciona mais, pois o GrepCode está inoperante. Aqui está a alternativa para implementação igual: [Link embutido ] ( zgrepcode.com/java/openjdk/10.0.2/java.base/java/lang/… )
Amandeep Singh
50

Eu acho que quando você define um, Stringvocê define um objeto. Então você precisa usar .equals(). Ao usar tipos de dados primitivos, você deve usar, ==mas com String(e qualquer objeto) .equals().

fabricioflores
fonte
7
"char []" não é um tipo de dados primitivo! É uma matriz de "caracteres". E matrizes não são tipos de dados primitivos.
Christian
48

Se o equals()método estiver presente na java.lang.Objectclasse, e espera-se verificar a equivalência do estado dos objetos! Isso significa que o conteúdo dos objetos. Enquanto o ==operador deve verificar se as instâncias reais do objeto são iguais ou não.

Exemplo

Considere duas variáveis ​​de referência diferentes str1e str2:

str1 = new String("abc");
str2 = new String("abc");

Se você usar o equals()

System.out.println((str1.equals(str2))?"TRUE":"FALSE");

Você obterá a saída como TRUEse estivesse usando ==.

System.out.println((str1==str2) ? "TRUE" : "FALSE");

Agora você obterá a FALSEsaída as, porque ambos str1e str2estão apontando para dois objetos diferentes, embora ambos compartilhem o mesmo conteúdo de string. É por causa de new String()um novo objeto é criado toda vez.

Rakesh KR
fonte
43

Operador == sempre se destina à comparação de referência de objeto , enquanto o método String .equals () da classe String é substituído para comparação de conteúdo :

String s1 = new String("abc");
String s2 = new String("abc");
System.out.println(s1 == s2); // It prints false (reference comparison)
System.out.println(s1.equals(s2)); // It prints true (content comparison)
sham.y
fonte
40

Todos os objetos têm garantia de ter um .equals()método, pois Object contém um método .equals(),, que retorna um booleano. É tarefa da subclasse substituir esse método se uma definição adicional for necessária. Sem ele (isto é, usando ==), apenas os endereços de memória são verificados entre dois objetos em busca de igualdade. String substitui esse .equals()método e, em vez de usar o endereço de memória, retorna a comparação de strings no nível de caractere para igualdade.

Uma observação importante é que as strings são armazenadas em um conjunto fixo; portanto, uma vez criada, ela é armazenada para sempre em um programa no mesmo endereço. As cordas não mudam, são imutáveis. É por isso que é uma má ideia usar a concatenação regular de cadeias se você tiver uma quantidade séria de processamento de cadeias para fazer. Em vez disso, você usaria as StringBuilderclasses fornecidas. Lembre-se de que os ponteiros dessa string podem mudar e se você estiver interessado em ver se dois ponteiros são iguais, ==seria um bom caminho a percorrer. As próprias cordas não.

James
fonte
2
"uma vez criada, uma string é armazenada para sempre em um programa no mesmo endereço" - Isso é totalmente errado. Somente expressões de seqüência constante em tempo de compilação (possivelmente envolvendo final Stringvariáveis) e seqüências de caracteres explicitamente armazenadas pelo programa são armazenadas no que você chama de "conjunto fixo". Todos os outros Stringobjetos estão sujeitos à coleta de lixo quando não houver mais referências ativas a eles, assim como qualquer outro tipo de objeto. Além disso, embora a imutabilidade seja necessária para que todo o mecanismo interno funcione, isso é irrelevante para isso.
Ted Hopp
A comparação de strings é feita através do método equals ou equalsIgnoreCase, que na verdade compara o conteúdo da string. Mas == assine apenas verifique os valores de referência. Para literais de string do pool de strings funcionará bem neste caso. String s1 = new String ("a"); String s2 = new String ("a"); neste caso, s1 == s2 é falso, mas s1.equals (s2) é verdadeiro.
Shailendra Singh
39

Você também pode usar o compareTo()método para comparar duas seqüências de caracteres. Se o resultado compareTo for 0, as duas cadeias serão iguais; caso contrário, as cadeias comparadas não serão iguais.

O ==compara as referências e não compara as seqüências reais. Se você criou todas as strings usando new String(somestring).intern(), pode usar o ==operador para comparar duas strings, caso contrário, os métodos equals () ou compareTo podem ser usados ​​apenas.

AlvaroAV
fonte
35

Em Java, quando o operador "==" é usado para comparar 2 objetos, ele verifica se os objetos se referem ao mesmo local na memória. Em outras palavras, verifica se os 2 nomes de objetos são basicamente referências ao mesmo local de memória.

A classe Java String, na verdade, substitui a implementação padrão equals () na classe Object - e substitui o método para que verifique apenas os valores das cadeias, e não seus locais na memória. Isso significa que, se você chamar o método equals () para comparar objetos 2 String, desde que a sequência real de caracteres seja igual, os dois objetos serão considerados iguais.

O ==operador verifica se as duas cadeias são exatamente o mesmo objeto.

O .equals()método verifica se as duas seqüências têm o mesmo valor.

Lijo
fonte
1
a menos que um deles seja nulo, pois s.equals (s2) falhará se s for nulo, causando falha na comparação. Claro, isso realmente não contradiz a resposta; é apenas uma ressalva.
Jon Coombs
1
Não, não irá falhar, lançará uma NullPointerException, fazendo com que a comparação não ocorra.
Bludzee