Java String.equals versus ==

Esse código separa uma string em tokens e os armazena em uma matriz de strings e compara uma variável com a primeira home … por que ela não está funcionando?

public static void main(String...aArguments) throws IOException { String usuario = "Jorman"; String password = "14988611"; String strDatos = "Jorman 14988611"; StringTokenizer tokens = new StringTokenizer(strDatos, " "); int nDatos = tokens.countTokens(); String[] datos = new String[nDatos]; int i = 0; while (tokens.hasMoreTokens()) { String str = tokens.nextToken(); datos[i] = str; i++; } //System.out.println (usuario); if ((datos[0] == usuario)) { System.out.println("WORKING"); } } 

Use a function string.equals(Object other) para comparar strings, não o operador == .

A function verifica o conteúdo real da string, o operador == verifica se as referências aos objects são iguais. Observe que as constantes de string geralmente são “internadas” de forma que duas constantes com o mesmo valor possam ser comparadas com == , mas é melhor não contar com isso.

 if (usuario.equals(datos[0])) { ... } 

NB: a comparação é feita em ‘usuario’ porque isso é garantido como não-nulo em seu código, embora você deva checar se você realmente tem alguns tokens no array de datos caso contrário você terá um array fora dos limites exceção.

Conheça Jorman

Jorman é um empresário de sucesso e tem duas casas.

insira a descrição da imagem aqui

Mas outros não sabem disso.

É o mesmo Jorman?

Quando você pergunta a vizinhos das ruas Madison ou Burke, essa é a única coisa que eles podem dizer:

insira a descrição da imagem aqui

Usando apenas a residência, é difícil confirmar que é o mesmo Jorman. Já que são dois endereços diferentes, é natural supor que são duas pessoas diferentes.

É assim que o operador == se comporta. Por isso vai dizer que datos[0]==usuario é falso, porque só compara os endereços .

Um investigador para o resgate

E se nós enviarmos um investigador? Sabemos que é o mesmo Jorman, mas precisamos provar isso. Nosso detetive examinará de perto todos os aspectos físicos. Com uma investigação minuciosa, o agente será capaz de concluir se é a mesma pessoa ou não. Vamos ver isso acontecer em termos Java.

Aqui está o código-fonte do método equals() de String:

insira a descrição da imagem aqui

Ele compara o caractere de Strings por caractere, a fim de chegar a uma conclusão de que eles são de fato iguais.

É assim que o método String equals se comporta. Então, datos[0].equals(usuario) retornará true, porque realiza uma comparação lógica .

É bom notar que, em alguns casos, o uso do operador “==” pode levar ao resultado esperado, porque a maneira como o java manipula strings – literais de strings são internados (veja String.intern() ) durante a compilation – então quando você escreve para exemplo "hello world" em duas classs e compare essas strings com “==” você poderia obter resultado: true, o que é esperado de acordo com a especificação ; quando você compara as mesmas strings (se elas tiverem o mesmo valor) quando a primeira é string literal (ou seja, definida através de "i am string literal" ) e a segunda é construída durante a execução, isto é. com a palavra-chave “new” como new String("i am string literal") , o operador == (igualdade) retorna false, porque ambos são instâncias diferentes da class String .

Apenas o caminho certo é usar .equals() -> datos[0].equals(usuario) . == diz apenas se dois objects são a mesma instância de object (ou seja, tem o mesmo endereço de memory)

Atualização : 01.04.2013 Eu atualizei este post devido comentários abaixo que são de alguma forma direito. Originalmente, declarei que interning (String.intern) é o efeito colateral da otimização da JVM. Embora certamente economize resources de memory (que era o que eu quis dizer com “otimização”) é principalmente característica da linguagem

equals() function equals() é um método da class Object que deve ser sobrescrito pelo programador. String class String substitui para verificar se duas strings são iguais, isto é, em conteúdo e não em referência.

== operador verifica se as referências de ambos os objects são as mesmas.

Considere os programas

 String abc = "Awesome" ; String xyz = abc; if(abc == xyz) System.out.println("Refers to same string"); 

Aqui o abc e xyz , ambos se referem a mesma String "Awesome" . Portanto, a expressão (abc == xyz) é true .

 String abc = "Hello World"; String xyz = "Hello World"; if(abc == xyz) System.out.println("Refers to same string"); else System.out.println("Refers to different strings"); if(abc.equals(xyz)) System.out.prinln("Contents of both strings are same"); else System.out.prinln("Contents of strings are different"); 

Aqui abc e xyz são duas strings diferentes com o mesmo conteúdo "Hello World" . Daí aqui a expressão (abc == xyz) é false onde como (abc.equals(xyz)) é true .

Espero que você tenha entendido a diferença entre == e .equals()

Obrigado.

Ao invés de

 datos[0] == usuario 

usar

 datos[0].equals(usuario) 

== compara a referência da variável onde .equals() compara os valores que é o que você quer.

== testes para igualdade de referência.

.equals() testa a igualdade de valor.

Conseqüentemente, se você realmente quer testar se duas strings têm o mesmo valor, você deve usar .equals() (exceto em algumas situações onde você pode garantir que duas strings com o mesmo valor serão representadas pelo mesmo object, por exemplo: String interning ).

== é para testar se duas strings são o mesmo Object .

 // 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 // concatenation of string literals happens at compile time resulting in same objects "test" == "te" + "st" ==> true // but .substring() is invoked at runtime, generating distinct objects "test" == "!test".substring(1) ==> false 

É importante notar que == é muito mais barato que equals() (uma única comparação de ponteiro em vez de um loop), portanto, em situações em que é aplicável (ou seja, você pode garantir que está lidando apenas com strings internadas) apresentar uma importante melhoria de desempenho. No entanto, essas situações são raras.

 The == operator checks if the two references point to the same object or not. .equals() checks for the actual string content (value). 

Observe que o método .equals () pertence à class Object (superclass de todas as classs). Você precisa sobrescrevê-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.

 Case1) String s1 = "Stack Overflow"; String s2 = "Stack Overflow"; s1 == s1; // true s1.equals(s2); // true Reason: String literals created without null are stored in the string pool in the permgen area of the heap. So both s1 and s2 point to the same object in the pool. Case2) String s1 = new String("Stack Overflow"); String s2 = new String("Stack Overflow"); s1 == s2; // false s1.equals(s2); // true Reason: If you create a String object using the `new` keyword a separate space is allocated to it on the heap. 

Ele também funcionará se você chamar intern() na string antes de inseri-lo na matriz. Seqüências internas são de referência igual ( == ) se e somente se elas forem iguais a valor ( equals() .)

 public static void main (String... aArguments) throws IOException { String usuario = "Jorman"; String password = "14988611"; String strDatos="Jorman 14988611"; StringTokenizer tokens=new StringTokenizer(strDatos, " "); int nDatos=tokens.countTokens(); String[] datos=new String[nDatos]; int i=0; while(tokens.hasMoreTokens()) { String str=tokens.nextToken(); datos[i]= str.intern(); i++; } //System.out.println (usuario); if(datos[0]==usuario) { System.out.println ("WORKING"); } 

Vamos analisar o seguinte Java, para entender a identidade e igualdade de Strings:

 public static void testEquality(){ String str1 = "Hello world."; String str2 = "Hello world."; if (str1 == str2) System.out.print("str1 == str2\n"); else System.out.print("str1 != str2\n"); if(str1.equals(str2)) System.out.print("str1 equals to str2\n"); else System.out.print("str1 doesn't equal to str2\n"); String str3 = new String("Hello world."); String str4 = new String("Hello world."); if (str3 == str4) System.out.print("str3 == str4\n"); else System.out.print("str3 != str4\n"); if(str3.equals(str4)) System.out.print("str3 equals to str4\n"); else System.out.print("str3 doesn't equal to str4\n"); } 

Quando a primeira linha de código String str1 = "Hello world." executa, uma string \Hello world." é criada, e a variável str1 se refere a ela. Outra string "Hello world." não será criada novamente quando a próxima linha de código for executada devido à otimização. A variável str2 também se refere à existente ""Hello world." .

O operador == verifica a identidade de dois objects (se duas variables ​​se referem ao mesmo object). Como str1 e str2 referem-se à mesma string na memory, eles são idênticos entre si. O método equals igualdade de verificação de dois objects (se dois objects têm o mesmo conteúdo). Naturalmente, o conteúdo de str1 e str2 é o mesmo.

Quando o código String str3 = new String("Hello world.") executado, uma nova instância de string com o conteúdo "Hello world." é criado e é referido pela variável str3 . E, em seguida, outra instância de string com conteúdo "Hello world." é criado novamente e referido por str4 . Como str3 e str4 referem-se a duas instâncias diferentes, elas não são idênticas, mas seu conteúdo é o mesmo.

Portanto, a saída contém quatro linhas:

 Str1 == str2 Str1 equals str2 Str3! = str4 Str3 equals str4 

Você deve usar string igual para comparar duas strings por igualdade, não operator == que compara as referências.

== operador == compara a referência de um object em Java. Você pode usar o método equals da string.

 String s = "Test"; if(s.equals("Test")) { System.out.println("Equal"); } 

O operador == é uma comparação simples de valores.
Para referências de objects, os (valores) são os (referências). Então x = = y retorna verdadeiro se xey referenciar o mesmo object.

Eu sei que esta é uma questão antiga, mas aqui está como eu olho para ela (acho muito útil):


Explicações técnicas

Em Java, todas as variables ​​são tipos primitivos ou referências .

(Se você precisa saber o que é uma referência: “variables ​​de object” são apenas pointers para objects. Portanto, com o Object something = ... , algo é realmente um endereço na memory (um número).)

== compara os valores exatos. Por isso, compara se os valores primitivos são os mesmos ou se as referências (endereços) são iguais. É por isso que geralmente não funciona em Strings; Strings são objects, e fazer == em duas variables ​​string apenas compara se o endereço é o mesmo na memory, como outros apontaram. .equals() chama o método de comparação de objects, que irá comparar os objects reais apontados pelas referências. No caso de Strings, ele compara cada caractere para ver se eles são iguais.


A parte interessante :

Então, por que às vezes == retorna true para Strings? Note que Strings são imutáveis. No seu código, se você fizer

 String foo = "hi"; String bar = "hi"; 

Como as strings são imutáveis ​​(quando você chama .trim() ou algo assim, produz uma nova string, não modificando o object original apontado na memory), você não precisa realmente de dois objects String("hi") . Se o compilador for inteligente, o bytecode será lido para gerar apenas um object String("hi") . Então, se você fizer

 if (foo == bar) ... 

logo depois, eles estão apontando para o mesmo object e retornarão true. Mas você raramente pretende isso. Em vez disso, você está pedindo a input do usuário, que está criando novas sequências em diferentes partes da memory, etc. etc.

Nota : Se você fizer algo como baz = new String(bar) o compilador ainda pode descobrir que eles são a mesma coisa. Mas o ponto principal é quando o compilador vê strings literais, pode facilmente otimizar as mesmas strings.

Eu não sei como funciona em tempo de execução, mas eu suponho que a JVM não mantém uma lista de “live strings” e verifique se existe uma mesma string. (por exemplo, se você ler uma linha de input duas vezes e o usuário inserir a mesma input duas vezes, ela não verificará se a segunda string de input é igual à primeira e apontará para a mesma memory). Isso economizaria um pouco de memory, mas é tão insignificante que a sobrecarga não vale a pena. Novamente, o ponto é que é fácil para o compilador otimizar cadeias literais.

Lá você tem … uma explicação para == vs. .equals() e por que parece random.

@ Melkhiah66 Você pode usar o método equals em vez do método ‘==’ para verificar a igualdade. Se você usar intern (), então ele verifica se o object está no pool, se presente, então retorna igual a outro desigual. O método equals usa internamente hashcode e obtém o resultado desejado.

 public class Demo { public static void main(String[] args) { String str1 = "Jorman 14988611"; String str2 = new StringBuffer("Jorman").append(" 14988611").toString(); String str3 = str2.intern(); System.out.println("str1 == str2 " + (str1 == str2)); //gives false System.out.println("str1 == str3 " + (str1 == str3)); //gives true System.out.println("str1 equals str2 " + (str1.equals(str2))); //gives true System.out.println("str1 equals str3 " + (str1.equals(str3))); //gives true } } 

Geralmente .equals é usado para comparação de Object , onde você deseja verificar se dois Objects têm um valor idêntico.

== para comparação de referência (são os dois Objects o mesmo Object na pilha) e para verificar se o Object é nulo. Também é usado para comparar os valores dos tipos primitivos.

Se você for comparar qualquer valor atribuído da string ie string primitiva, ambos “==” e .equals funcionarão, mas para o novo object de string você deve usar apenas .equals, e aqui “==” não funcionará.

Exemplo:

 String a = "name"; String b = "name"; 

if(a == b) e (a.equals(b)) retornarão verdadeiro.

Mas

 String a = new String("a"); 

Neste caso, if(a == b) retornará false

Então é melhor usar o operador .equals

O .equals() irá verificar se as duas strings têm o mesmo valor e retornam o valor boolean onde o operador == verifica se as duas strings são o mesmo object.

Alguém disse em um post mais alto que == é usado para int e para verificar nulos. Também pode ser usado para verificar operações e tipos de caracteres booleanos.

Tenha muito cuidado e verifique novamente se você está usando um caractere e não uma String. por exemplo

  String strType = "a"; char charType = 'a'; 

para seqüências de caracteres, você verificaria isso seria correto

  if(strType.equals("a") do something 

mas

  if(charType.equals('a') do something else 

seria incorreto, você precisaria fazer o seguinte

  if(charType == 'a') do something else 

a==b

Compara referências, não valores. O uso de == com referências de object é geralmente limitado ao seguinte:

  1. Comparando para ver se uma referência é null .

  2. Comparando dois valores enum. Isso funciona porque há apenas um object para cada constante de enum .

  3. Você quer saber se duas referências são para o mesmo object

"a".equals("b")

Compara valores por igualdade. Como esse método é definido na class Object , da qual todas as outras classs são derivadas, ele é definido automaticamente para cada class. No entanto, ela não realiza uma comparação inteligente para a maioria das classs, a menos que a class a substitua. Ele foi definido de maneira significativa para a maioria das classs principais do Java. Se não estiver definido para uma class (usuário), ela se comporta da mesma forma que == .

Use Split em vez de tokenizer, ele certamente irá fornecer u saída exata para por exemplo:

 string name="Harry"; string salary="25000"; string namsal="Harry 25000"; string[] s=namsal.split(" "); for(int i=0;i 

Depois disso, tenho certeza que você obterá melhores resultados .....