Como faço para comparar strings em Java?

Eu tenho usado o operador == no meu programa para comparar todas as minhas strings até agora. No entanto, me deparei com um bug, mudei um deles para .equals() e consertei o bug.

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

   

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

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

Objects.equals () verifica null antes de chamar .equals() então você não precisa (disponível a partir do JDK7, também disponível em Goiaba ).

String.contentEquals () compara o conteúdo da String com o conteúdo de qualquer CharSequence (disponível desde o Java 1.5).

Conseqüentemente, se você quiser testar se duas strings têm o mesmo valor, provavelmente você 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 sequências internas , você pode usar == .

De JLS 3.10.5. Literais de Cordas :

Além disso, uma string literal sempre se refere à mesma instância da class String . Isso ocorre porque literais de string – ou, mais geralmente, strings que são os valores de expressões constantes ( §15.28 ) – são “internados” para compartilhar instâncias exclusivas, usando o método String.intern .

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

== testa referências de objects, .equals() testa os valores da string.

Às vezes, parece que == compara valores, porque Java faz algumas coisas por trás das cenas para garantir que sequências de caracteres in-line idênticas sejam realmente o mesmo object.

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 com cadeias null , mas chamando .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)); 

Então, se você sabe que fooString1 pode ser nulo, diga ao leitor que escrevendo

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

O seguinte é mais curto, mas é menos óbvio que ele verifique por nulo (do Java 7):

 System.out.print(Objects.equals(fooString1, "bar")); 

== compara referências de objects.

.equals() compara os valores de String.

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

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

Isso ocorre porque, quando você cria qualquer literal String, a JVM primeiro procura esse literal no conjunto de Cadeias e, se encontrar uma correspondência, essa mesma referência será fornecida à nova Cadeia. Por causa disso, conseguimos:

(a == b) ===> true

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

No entanto, == falha no seguinte caso:

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

Neste caso para new String("test") a declaração new String será criada no heap, e essa referência será dada para b , então b receberá uma referência no heap, não no conjunto de strings.

Agora a está apontando para uma String no conjunto String enquanto b está apontando para uma String na pilha. Por causa disso nós temos:

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

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

Enquanto .equals() sempre compara um valor de String para que seja verdade em ambos os 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 

Portanto, usar .equals() é sempre melhor.

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

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

Strings em Java são imutáveis. Isso significa que sempre que você tentar alterar / modificar a string, você receberá uma nova instância. Você não pode alterar a string 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 de caracteres e o armazenamento em cache dessas instâncias pode diminuir o consumo de memory e aumentar o desempenho do programa.

Ao usar o operador == para comparação de string, você não está comparando o conteúdo da string, mas na verdade está comparando o endereço da memory. Se ambos forem iguais, retornará verdadeiro e falso, caso contrário. Considerando que equals in string compara o conteúdo da string.

Portanto, a questão é se todas as strings são armazenadas em cache no sistema, como é que == retorna false enquanto os iguais retornam true? Bem, isso é possível. Se você criar uma nova string como String str = new String("Testing") acabará criando uma nova string no cache, mesmo que o cache já contenha uma string com o mesmo conteúdo. Em suma, "MyString" == new String("MyString") sempre retornará false.

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

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

 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 == só compara referências; o método equals() faz uma comparação caractere por caractere do conteúdo.

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

Sim, é ruim …

== significa que suas duas referências de string são exatamente o mesmo object. Você pode ter ouvido que esse é o caso porque Java mantém uma espécie de tabela literal (o que acontece), mas nem sempre é esse o caso. Algumas strings são carregadas de maneiras diferentes, construídas a partir de outras strings, etc., então você nunca deve presumir que duas strings idênticas são armazenadas no mesmo local.

Equals faz a comparação real para você.

Sim, == é ruim para comparar Strings (quaisquer objects realmente, a menos que você saiba que eles são canônicos). == apenas compara referências de objects. .equals() testa a igualdade. Para Strings, muitas vezes eles serão os mesmos, mas como você descobriu, isso não é garantido sempre.

Java tem um conjunto String sob o qual Java gerencia a alocação de memory para os objects String. Veja String Piscinas em Java

Quando você verifica (compara) dois objects usando o operador == , ele compara a igualdade de endereço com o conjunto de strings. Se os dois objects 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 objects String, deverá replace o método equals .

equals é, na verdade, o método da class Object, mas é Overridden na class String e uma nova definição é dada, a qual compara o conteúdo do object.

 Example: stringObjectOne.equals(stringObjectTwo); 

Mas importa que respeite o caso de String. Se você quiser comparar maiúsculas e minúsculas, então você deve ir para o método equalsIgnoreCase da class 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 

.equals() compara os dados em uma class (supondo que a function seja implementada). == compara locais de ponteiro (localização do object na memory).

== retorna verdadeiro se ambos os objects (NÃO FALANDO SOBRE PRIMITIVOS) apontarem para a mesma instância do object. .equals() retorna verdadeiro se os dois objects contiverem os mesmos dados equals() Versus == em Java

Isso pode te ajudar.

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

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

Se uma comparação de dois objects String usando == for true , isso acontece porque os objects String 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 compare um object String contendo o mesmo conteúdo de outro object String usando == para avaliar como true .

== executa uma verificação de igualdade de referência , se os dois objects (cadeias, neste caso) se referem ao mesmo object na memory.

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

Obviamente == é mais rápido, mas irá (pode) dar resultados falsos em muitos casos, se você quer apenas dizer se 2 String s contém o mesmo texto.

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

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

  1. Implementação de String.equals() primeiro verifica a igualdade de referência (usando == ), e se as duas seqüências são as mesmas por referência, nenhum cálculo adicional é realizado!
  2. Se as referências de 2 cordas não forem as mesmas, String.equals() irá verificar os comprimentos das cordas. Esta também é uma operação rápida porque a class String armazena o tamanho da string, sem a necessidade de contar os caracteres ou pontos de código. Se os comprimentos forem diferentes, nenhuma verificação adicional é executada, sabemos que eles não podem ser iguais.
  3. Somente se chegarmos até aqui, o conteúdo das duas seqüências de caracteres será realmente comparado, e isso será uma comparação de mão curta: nem todos os caracteres serão comparados, se encontrarmos um caráter incompatível (na mesma posição nas duas seqüências de caracteres ), nenhum outro caracter será verificado.

Quando tudo estiver dito e feito, mesmo que tenhamos garantias de que as strings são internas, o uso do método equals() ainda não é a sobrecarga que se poderia pensar, definitivamente a maneira recomendada. Se você quiser uma verificação de referência eficiente, use enums onde a especificação e a implementação da linguagem garantem que o mesmo valor enum será o mesmo object (por referência).

Eu concordo com a resposta dos zacheratos.

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

Do exemplo dos zacheratos:

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

Se você estagiar a igualdade de Cadeia não literal é verdadeira

 new String("test").intern() == "test" ==> true 

Se você é como eu, quando comecei a usar Java, quis 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 strings Java, começando com a abordagem que uso na maioria das vezes. No final deste tutorial de comparação do Java String, também discutirei por que o operador “==” não funciona ao comparar strings Java.

Opção 1: comparação Java String com o método equals Na maioria das vezes (talvez 95% do tempo) eu comparo strings com o método equals da class Java String, assim:

 if (string1.equals(string2)) 

Esse método String equals observa as duas strings Java e, se elas contêm exatamente a mesma string de caracteres, elas são consideradas iguais.

Observando um exemplo rápido de comparação de String 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 os mesmos (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 strings contêm exatamente a mesma string 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 sequências com o método equalsIgnoreCase

Em alguns testes de comparação de strings, você desejará ignorar se as strings são maiúsculas ou minúsculas. Quando você quiser testar suas strings para igualdade dessa maneira que não diferencia maiúsculas e minúsculas, use o método equalsIgnoreCase da class 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 do Java String com o método compareTo

Há também uma terceira maneira, menos comum, de comparar as strings Java, e isso é com o método compareTo da class String. Se as duas cadeias forem exatamente iguais, o método compareTo retornará um valor de 0 (zero). Veja um exemplo rápido do que é 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 estou escrevendo sobre esse conceito de igualdade em Java, é importante observar que a linguagem Java inclui um método equals na class Java Object base. Sempre que você estiver criando seus próprios objects e quiser fornecer um meio de ver se duas instâncias de seu object são “iguais”, você deve replace (e implementar) esse método de igualdade em sua class (da mesma forma que a linguagem Java fornece esse comportamento de igualdade / comparação no método String equals).

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

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); 

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

Observe que o método .equals() pertence à class Object (superclass de todas as classs). Você precisa substituí-lo conforme o requisito de class, mas para o 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 

    Razão: literais de cadeia criados sem nulo são armazenados no conjunto de cadeias na área permgen da pilha. Portanto, s1 e s2 apontam para o mesmo object 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 object String usando a new palavra-chave, um espaço separado será alocado para ele no heap.

== compara o valor de referência dos objects, enquanto o método equals() presente na class java.lang.String compara o conteúdo do object String (para outro object).

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

Se o método equals() estiver presente na class java.lang.Object , espera-se que verifique a equivalência do estado dos objects! Isso significa, o conteúdo dos objects. Enquanto espera-se que o operador == verifique se as instâncias do object real são iguais ou não.

Exemplo

Considere duas variables ​​de referência diferentes, str1 e str2 :

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

Se você usar os equals()

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

Você obterá a saída como TRUE se você usar == .

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

Agora você obterá o FALSE como saída, porque ambos str1 e str2 estão apontando para dois objects diferentes, embora ambos compartilhem o mesmo conteúdo de string. É por causa do new String() um novo object é criado toda vez.

O operador == é sempre destinado à comparação de referências de objects , enquanto o método String .equals () da class é substituído pela 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) 

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

Uma nota chave é que as cadeias de caracteres são armazenadas em um conjunto fixo, portanto, uma vez que uma cadeia é criada, ela é armazenada para sempre em um programa no mesmo endereço. Cordas não mudam, elas são imutáveis. É por isso que é uma má idéia usar a concatenação regular de strings se você tiver uma quantidade séria de processamento de strings para fazer. Em vez disso, você usaria as classs StringBuilder fornecidas. Lembre-se que os pointers para esta string podem mudar e se você estivesse interessado em ver se dois pointers eram os mesmos == seria um bom caminho a percorrer. Cordas em si não.

Você também pode usar o método compareTo() para comparar duas Strings. Se o resultado compareTo for 0, as duas strings serão iguais, caso contrário, as strings comparadas não serão iguais.

O == compara as referências e não compara as cadeias reais. Se você criou todas as strings usando a new String(somestring).intern() então você pode usar o operador == para comparar duas strings, senão os methods equals () ou compareTo só podem ser usados.

Em Java, quando o operador “==” é usado para comparar dois objects, ele verifica se os objects se referem ao mesmo local na memory. Em outras palavras, ele verifica se os 2 nomes de object são basicamente referências ao mesmo local de memory.

A class Java String na verdade substitui a implementação equals () padrão na class Object – e ela substitui o método para que ele verifique apenas os valores das strings, não suas localizações na memory. Isso significa que se você chamar o método equals () para comparar objects de 2 String, contanto que a seqüência real de caracteres seja igual, os dois objects serão considerados iguais.

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

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