Qual é a diferença entre o String#equals
método e o String#contentEquals
método?
Qual é a diferença entre o String#equals
método e o String#contentEquals
método?
Respostas:
A String#equals()
não só compara o conteúdo da string, mas também verifica se a outro objeto também é uma instância de um String
. O String#contentEquals()
único compara o conteúdo (a sequência de caracteres) e não verifica se o outro objeto também é uma instância de String
. Pode ser qualquer coisa, desde que ele é uma implementação CharSequence
que abrange Ao String
, StringBuilder
, StringBuffer
, CharBuffer
, etc.
==
operador permitirá apenas comparar as referências e não o conteúdo de dois objetos.
==
mencionado é apenas JavaScript; isso nunca é mencionado em Java.
==
em JavaScript é looser longe do que contentEquals
, o que não vai tocar números, por exemplo), mas você está correto sobre equals
a verificação de uma partida tipo exato comStrings
(outras classes poderia ser mais flexível com os tipos em seus equals
métodos) .
Para simplificar: String.contentEquals()
é o irmão mais inteligente de String.equals()
, porque pode ser mais livre na implementação do que String.equals()
.
Existem algumas razões pelas quais existe um String.contentEquals()
método separado . A razão mais importante que eu acho é:
equals
método deve ser reflexivo. Isso significa que: x.equals(y) == y.equals(x)
. Isso implica que aString.equals(aStringBuffer)
teria que ser o mesmo que aStringBuffer.equals(aString)
. Isso exigiria que os desenvolvedores da API Java fizessem alguma implementação especial para Strings no equals()
método StringBuffer, StringBuilder e CharSequence também. Isso seria uma bagunça.Isto é onde String.contentEquals
entra. Este é um método autônomo que não não tem que seguir os requisitos e regras estritas para Object.equals
. Dessa forma, você pode implementar o senso de "conteúdo igual" mais livremente. Isso permite que você faça comparações inteligentes entre um StringBuffer e um String, por exemplo.
E para dizer qual é exatamente a diferença:
String.contentEquals()
pode comparar o conteúdo de a String
, a StringBuilder
, a StringBuffer
, a CharSequence
e todas as classes derivadas delas. Se o parâmetro for do tipo String, então String.equals()
seja executado.
String.equals()
compara apenas objetos String. Todos os outros tipos de objetos são considerados diferentes.
String.contentEquals()
pode comparar StringBuffer
e de StringBuilder
forma inteligente. Ele não chama o toString()
método pesado , que copia todo o conteúdo para um novo objeto String. Em vez disso, ele se compara à char[]
matriz subjacente , o que é ótimo.
Essa resposta já foi postada pelo dbw, mas ele a excluiu, mas tinha alguns pontos válidos para a diferença ao comparar o tempo de execução, quais exceções são lançadas,
Se você observar o código-fonte String # equals e String # contentEquals , ficará claro que existem dois métodos substituídos para String#contentEquals
um que aceita StringBuilder
e outro CharSequence
.
A diferença entre eles,
String#contentEquals
lançará NPE se o argumento fornecido for, null
mas String#equals
retornaráfalse
String#equals
compara o conteúdo apenas quando o argumento fornecido é o instance of String
contrário, ele retornará false
em todos os outros casos, mas, por outro lado, String#contentEquals
verifica o conteúdo de todos os objetos que implementam a interface CharSequence
.Você também pode ajustar o código para String#contentEquals
retornar o resultado errado ou o resultado desejado, substituindo o equals
método do argumento passado conforme mostrado abaixo, mas não pode fazer esses ajustes String#equals
.
O código abaixo sempre produzirátrue
contanto que s
contenha string
3 caracteres
String s= new String("abc");// "abc";
System.out.println(s.contentEquals(new CharSequence()
{
@Override
public CharSequence subSequence(int arg0, int arg1) {
// TODO Auto-generated method stub
return null;
}
@Override
public int length() {
// TODO Auto-generated method stub
return 0;
}
@Override
public char charAt(int arg0) {
// TODO Auto-generated method stub
return 0;
}
@Override
public boolean equals(Object obj)
{
return true;
}
}));
String#contentEquals
será mais lento que String#Equals
o argumento fornecido instance of String
e o comprimento de ambos String
será o mesmo, mas o conteúdo não será igual.
Exemplo se a string for String s = "madam"
e, em String argPassed = "madan"
seguida s.contentEquals(argPassed)
, levará quase o dobro do tempo de execução nesse caso, em comparação coms.equals(argPassed)
Se o comprimento do conteúdo não for o mesmo para as duas cadeias, a função String#contentEquals
terá melhor desempenho do que String#Equals
em quase todos os casos possíveis.
Mais um ponto a acrescentar à sua resposta
String#contentEquals
de um String
objeto também será comparado ao StringBuilder
conteúdo e fornecerá o resultado apropriado enquanto String#Equals
retornaráfalse
String
O equals(Object o)
método de classe faz apenas String
comparação. Mas as contentEquals(CharSequence cs)
verificações de classes se estendem , AbstractStringBuilder
ou seja StringBuffer
, StringBuilder
e String
também de classe (todas elas são do tipo CharSequence
).
String str = "stackoverflow";
StringBuilder builder = new StringBuilder(str);
System.out.println(str.equals(builder));
System.out.println(str.contentEquals(builder));
resultado:
false
true
A saída do primeiro stmt é false
porque builder
não é do tipo, String
então equals()
retorna, false
mas contentEquals()
verifica o conteúdo de todo o tipo StringBuilder
, como StringBuffer
, String
e como o conteúdo é o mesmo true
.
contentEquals
jogará NullPointerException
se o argumento fornecido for, null
mas equals()
retornará false, porque o equals () verifica instanceOf ( if (anObject instance of String)
) que retorna false se o argumento for null
.contentEquals(CharSequence cs)
:
java.lang.CharacterSequence
(por exemplo, CharBuffer
, Segment
, String
, StringBuffer
, StringBuilder
)equals(Object anObject)
:
java.lang.String
únicaRTFC :)
Como ler a fonte é a melhor maneira de entendê-la, estou compartilhando as implementações dos dois métodos (a partir do jdk 1.7.0_45)
public boolean contentEquals(CharSequence cs) {
if (value.length != cs.length())
return false;
// Argument is a StringBuffer, StringBuilder
if (cs instanceof AbstractStringBuilder) {
char v1[] = value;
char v2[] = ((AbstractStringBuilder) cs).getValue();
int i = 0;
int n = value.length;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
// Argument is a String
if (cs.equals(this))
return true;
// Argument is a generic CharSequence
char v1[] = value;
int i = 0;
int n = value.length;
while (n-- != 0) {
if (v1[i] != cs.charAt(i))
return false;
i++;
}
return true;
}
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String) anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
Há outro método da String # contentEquals ():
public boolean contentEquals(StringBuffer sb) {
synchronized(sb) {
return contentEquals((CharSequence)sb);
}
}
equals()
e contentEquals()
são dois métodos na String
classe para comparar dois strings
e string
com StringBuffer
.
Os parâmetros de contentEquals()
são StringBuffer
e String(charSequence)
. equals()
é usado para comparar dois strings
e contentEquals()
é usado para comparar o conteúdo de String
e StringBuffer
.
Método contentEquals
e equals
são
public boolean contentEquals(java.lang.StringBuffer);
public boolean contentEquals(java.lang.CharSequence);
public boolean equals(Object o)
Aqui está um código que descreve os dois métodos
public class compareString {
public static void main(String[] args) {
String str1 = "hello";
String str2 = "hello";
StringBuffer sb1 = new StringBuffer("hello");
StringBuffer sb2 = new StringBuffer("world");
boolean result1 = str1.equals(str2); // works nice and returns true
System.out.println(" str1.equals(str2) - "+ result1);
boolean result2 = str1.equals(sb1); // works nice and returns false
System.out.println(" str1.equals(sb1) - "+ result2);
boolean result3 = str1.contentEquals(sb1); // works nice and returns true
System.out.println(" str1.contentEquals(sb1) - "+ result3);
boolean result4 = str1.contentEquals(sb2); // works nice and returns false
System.out.println(" str1.contentEquals(sb2) - "+ result4);
boolean result5 = str1.contentEquals(str2); // works nice and returns true
System.out.println(" str1.contentEquals(str2) - "+ result5);
}
}
Resultado:
str1.equals(str2) - true
str1.equals(sb1) - false
str1.contentEquals(sb1) - true
str1.contentEquals(sb2) - false
str1.contentEquals(str2) - true
String # equals usa Object como argumento e verifica se é uma instância do objeto String ou não. Se o objeto do argumento for String Object, ele compara o conteúdo caracter por caracter. Retorna true caso o conteúdo dos dois objetos de string seja o mesmo.
A sequência # contentEquals usa a interface CharSequence como argumento. CharSequence pode ser implementado de duas maneiras - usando i) classe String ou (ii) AbstractStringBuilder (classe pai de StringBuffer, StringBuilder)
Em contentEquals (), o comprimento é comparado antes de qualquer verificação da instância do objeto. Se o comprimento for o mesmo, ele verifica se o objeto do argumento é uma instância do AbstractStringBuilder ou não. Se assim for (por exemplo, StringBuffer ou StringBuilder), o conteúdo é verificado, caractere por caractere. Caso o argumento seja uma instância do objeto String, a String # é igual a chamada da String # contentEquals.
Então, resumindo,
String # equals compara o caractere de conteúdo por caractere, caso o argumento também seja objeto de String. E String # contentEquals compara o conteúdo caso o objeto de argumento implemente a interface CharSequence.
String # contentEquals é mais lenta, caso comparemos dois conteúdos de string com o mesmo comprimento que String # contentEquals chama internamente String # igual a para o objeto String.
Caso tentemos comparar objetos com diferentes tamanhos de conteúdo (digamos "abc" com "abcd"), a String # contentEquals é mais rápida que a String # igual. Porque o comprimento é comparado antes de qualquer verificação de instância do objeto.
Os contentEquals()
método verifica se os conteúdos são os mesmos entre um String
, StringBuffer
, etc, que algum tipo de sequcia de carvão animal.
BTW, a razão histórica para a diferença é que String originalmente não tinha superclasse, então String.equals () usa uma String como argumento. Quando o CharSequence foi introduzido como a superclasse de String, ele precisava de um teste de igualdade próprio que funcionasse em todas as implementações do CharSequence e que não colidisse com os equals () já em uso pelo String ... então obtivemos CharSequence.contentEquals ( ), que é herdado por String.
Se CharSequence estivesse presente no Java 1.0, provavelmente teríamos apenas CharSequence.equals () e String simplesmente implementaria isso.
Ah, as alegrias das línguas em evolução ...
==
(contentEquals) e===
(iguais) em javascript?