W3docs

Como Comparar Strings em Java

Compare strings em Java com equals, equalsIgnoreCase, compareTo e evite armadilhas comuns com ==.

Comparar dois valores String em Java é uma das primeiras coisas que um iniciante erra, porque o operador == compara silenciosamente referências em vez de conteúdo. Este capítulo mostra as formas corretas e idiomáticas de testar igualdade e ordenação de strings — equals, equalsIgnoreCase, compareTo e o Objects.equals seguro para null — e explica exatamente quando cada um é a ferramenta certa.

Para entender o motivo pelo qual literais idênticos podem ser ==, veja o pool de strings; para uma visão mais ampla das técnicas de comparação, veja comparação de strings em Java.

Igualdade de conteúdo com equals

Para verificar se duas strings contêm os mesmos caracteres, chame equals:

String a = "hello";
String b = new String("hello");

boolean same = a.equals(b);   // true — same characters

equals percorre as duas sequências de caracteres e retorna true somente quando elas têm o mesmo comprimento e os mesmos caracteres na mesma ordem. É o método que você quer 99% das vezes em que pergunta "essas duas strings são o mesmo texto?".

Um truque defensivo comum é chamar equals em um literal de string para que o receptor nunca seja null:

if ("yes".equals(userInput)) { ... }   // safe even if userInput is null

Por que == é a armadilha clássica

== não examina caracteres de forma alguma — ele pergunta "esses são exatamente o mesmo objeto na memória?". Como o compilador interna literais de string (armazena uma cópia compartilhada em um pool), dois literais idênticos podem ser == por acaso, o que leva as pessoas a pensar que == compara texto. Não é assim: no momento em que uma string vem de new, entrada do usuário ou concatenação em tempo de execução, == retorna false mesmo para textos idênticos.

ExpressãoResultadoPor quê
"java" == "java"trueAmbas se referem ao mesmo literal internado
"java" == new String("java")falsenew cria um objeto distinto
"java".equals(new String("java"))trueCompara conteúdo, não identidade

Regra prática: nunca use == para comparar strings. Use equals.

Comparação sem distinção de maiúsculas com equalsIgnoreCase

Quando a capitalização não importa — nomes de usuário, extensões de arquivo, nomes de cabeçalho — use equalsIgnoreCase:

"Java".equalsIgnoreCase("JAVA");   // true

Ele aplica a mesma lógica caractere por caractere que equals após normalizar a capitalização, então "README".equalsIgnoreCase("readme") é true.

Ordenação com compareTo

Para ordenar ou classificar strings em vez de apenas testar igualdade, use compareTo, que retorna o sinal da diferença lexicográfica (estilo dicionário):

"apple".compareTo("banana");   // negative — apple comes first
"apple".compareTo("apple");    // 0       — equal
"banana".compareTo("apple");   // positive — banana comes later

Um resultado negativo significa que o receptor vem antes do argumento, 0 significa igual, e positivo significa depois. Existe uma variante compareToIgnoreCase e String.CASE_INSENSITIVE_ORDER para uso como Comparator. Note que a ordenação padrão é por ponto de código Unicode, então todas as letras maiúsculas (AZ) aparecem antes de todas as letras minúsculas.

Um exemplo prático

Este programa exercita cada abordagem lado a lado para que você veja exatamente como cada uma se comporta.

java— editable, runs on the server

O que observar na execução:

  • a == b imprime false mesmo que ambas as strings leiam "java", porque new String("java") é um objeto separado — prova de que == compara identidade, não texto.
  • a.equals(b) imprime true: equals examina os caracteres, que é o que você quase sempre quer dizer com "a mesma string".
  • a == c imprime true somente porque ambos são literais que compartilham um objeto internado — esse sucesso acidental é exatamente o motivo pelo qual == atrai iniciantes para um bug.
  • equalsIgnoreCase imprime true para "Java" vs "JAVA", enquanto compareTo retorna 0 para texto idêntico e um sinal diferente de zero (-1 para apple antes de banana) quando diferem.
  • Objects.equals(null, "x") imprime false em vez de lançar exceção, e o array ordenado imprime [Cherry, apple, banana] — o C maiúsculo (ponto de código 67) aparece antes das letras minúsculas (ponto de código 97+).

Qual método devo usar?

Escolha a comparação pela pergunta que você está realmente respondendo:

Você quer saber…UseNotas
O texto é exatamente igual?a.equals(b)A escolha padrão para igualdade
Igual, ignorando maiúsculas/minúsculas?a.equalsIgnoreCase(b)Normaliza a capitalização primeiro
Igual, mas algum lado pode ser null?Objects.equals(a, b)Retorna true para dois nulls, nunca lança exceção
Qual é a ordem de classificação?a.compareTo(b)Negativo / 0 / positivo
Ordem de classificação, ignorando maiúsculas?a.compareToIgnoreCase(b)Ou String.CASE_INSENSITIVE_ORDER como Comparator

Um bom hábito: quando você só precisa de igualdade, prefira equals (ou Objects.equals quando null for possível) e nunca compareTo(...) == 0, que realiza estritamente mais trabalho. Para explorar os métodos nos quais esses são baseados, veja métodos de string Java e a classe String.

Prática

Prática
Por que a expressão new String('hi') == 'hi' resulta em false em Java?
Por que a expressão new String('hi') == 'hi' resulta em false em Java?
Was this page helpful?