¿Cuál es la diferencia entre el String#equals
método y el String#contentEquals
método?
¿Cuál es la diferencia entre el String#equals
método y el String#contentEquals
método?
Respuestas:
El String#equals()
no solo compara el contenido de la Cadena, sino que también comprueba si el otro objeto también es una instancia de a String
. El String#contentEquals()
único compara el contenido (la secuencia de caracteres) y no comprueba si el otro objeto también es una instancia de String
. Puede ser cualquier cosa, siempre y cuando se trata de una aplicación de CharSequence
la que cubre ao String
, StringBuilder
, StringBuffer
, CharBuffer
, etc.
==
operador solo le permitirá comparar las referencias, no el contenido de dos objetos.
==
mencionado es solo JavaScript; nunca se menciona con respecto a Java.
==
en JavaScript es mucho más flexible que contentEquals
, lo que no tocará números, por ejemplo), pero está en lo correcto al equals
verificar una coincidencia de tipo exacta conStrings
(otras clases podrían ser más flexibles con los tipos en sus equals
métodos) .
Para decirlo fácilmente: String.contentEquals()
es el hermano más inteligente de String.equals()
, porque puede ser más libre en la implementación que String.equals()
.
Hay algunas razones por las cuales hay un String.contentEquals()
método separado . La razón más importante que creo es:
equals
método tiene que ser reflexivo. Eso significa que: x.equals(y) == y.equals(x)
. Esto implica que aString.equals(aStringBuffer)
tendría que ser lo mismo que aStringBuffer.equals(aString)
. Esto requeriría que los desarrolladores de la API Java realicen una implementación especial para Strings en el equals()
método de StringBuffer, StringBuilder y CharSequence también. Esto sería un desastre.Aquí es donde String.contentEquals
entra. Se trata de un método independiente que no no tiene por qué seguir los estrictos requisitos y normas para Object.equals
. De esta manera, puede implementar el sentido de "contenido igual" más libremente. Esto le permite hacer comparaciones inteligentes entre un StringBuffer y un String, por ejemplo.
Y para decir cuál es exactamente la diferencia:
String.contentEquals()
puede comparar los contenidos de a String
, a StringBuilder
, a StringBuffer
, a CharSequence
y todas las clases derivadas de estos. Si el parámetro es de tipo String, String.equals()
se ejecuta.
String.equals()
solo compara objetos String. Todos los demás tipos de objetos se consideran no iguales.
String.contentEquals()
puede comparar StringBuffer
y StringBuilder
de manera inteligente. No , no llame a la pesada toString()
método, que copia todo el contenido de un nuevo objeto String. En cambio, se compara con la char[]
matriz subyacente , que es genial.
Esta respuesta ya fue publicada por dbw, pero la eliminó, pero tenía algunos puntos muy válidos para la diferencia al comparar el tiempo de ejecución, qué excepciones se lanzan,
Si observa el código fuente String # equals y String # contentEquals , está claro que hay dos métodos anulados para String#contentEquals
uno que toma StringBuilder
y otro CharSequence
.
La diferencia entre ellos
String#contentEquals
arrojará NPE si el argumento proporcionado es null
pero String#equals
devolveráfalse
String#equals
compara el contenido solo cuando el argumento proporcionado es, de lo instance of String
contrario, volverá false
en todos los demás casos, pero por otro lado String#contentEquals
verifica el contenido de todos los objetos que implementan la interfaz CharSequence
.También puede ajustar el código para que String#contentEquals
devuelva el resultado incorrecto o el resultado que desea anulando el equals
método del argumento pasado como se muestra a continuación, pero no puede hacer esos ajustes String#equals
.
El siguiente código siempre producirátrue
siempre que s
contenga cualquiera de 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á más lento que String#Equals
cuando el argumento proporcionado es instance of String
y la longitud de ambos String
es la misma pero el contenido no es igual.
Ejemplo si las cadenas son String s = "madam"
y String argPassed = "madan"
luego s.contentEquals(argPassed)
tomarán casi el doble de tiempo de ejecución en este caso en comparación cons.equals(argPassed)
Si la longitud del contenido no es la misma para ambas cadenas, la función String#contentEquals
tendrá un mejor rendimiento que String#Equals
en casi todos los casos posibles.
Un punto más para agregar a su respuesta
String#contentEquals
de un String
objeto también se comparará con el StringBuilder
contenido y proporcionará el resultado apropiado, mientras String#Equals
que devolveráfalse
String
El equals(Object o)
método de clase solo hace String
comparación. Pero las contentEquals(CharSequence cs)
comprobaciones para las clases se extienden , AbstractStringBuilder
es decir StringBuffer
, StringBuilder
y la String
clase también (todas son de tipo CharSequence
).
String str = "stackoverflow";
StringBuilder builder = new StringBuilder(str);
System.out.println(str.equals(builder));
System.out.println(str.contentEquals(builder));
salida:
false
true
La salida del primero stmt es false
porque builder
no es de tipo String
de modo equals()
rendimientos false
pero los contentEquals()
controles para el contenido de todo el tipo como StringBuilder
, StringBuffer
, String
y como el contenido es el mismo, por lo tanto true
.
contentEquals
lanzará NullPointerException
si el argumento proporcionado es null
pero equals()
devolverá falso porque equals () verifica por ejemplo Of ( if (anObject instance of String)
) que devuelve falso si el argumento es null
.contentEquals(CharSequence cs)
:
java.lang.CharacterSequence
(por ejemplo, CharBuffer
, Segment
, String
, StringBuffer
, StringBuilder
)equals(Object anObject)
:
java.lang.String
solamenteRTFC :)
Como leer la fuente es la mejor manera de entenderla, comparto las implementaciones de ambos métodos (a partir de 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;
}
Hay otro método de String # contentEquals ():
public boolean contentEquals(StringBuffer sb) {
synchronized(sb) {
return contentEquals((CharSequence)sb);
}
}
equals()
y contentEquals()
son dos métodos en String
clase para comparar dos strings
y string
con StringBuffer
.
Los parámetros de contentEquals()
son StringBuffer
y String(charSequence)
. equals()
se usa para comparar dos strings
y contentEquals()
se usa para comparar el contenido de String
y StringBuffer
.
Método contentEquals
y equals
son
public boolean contentEquals(java.lang.StringBuffer);
public boolean contentEquals(java.lang.CharSequence);
public boolean equals(Object o)
Aquí hay un código que describe ambos 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);
}
}
Salida:
str1.equals(str2) - true
str1.equals(sb1) - false
str1.contentEquals(sb1) - true
str1.contentEquals(sb2) - false
str1.contentEquals(str2) - true
String # equals toma Object como argumento y comprueba si es una instancia de String object o no. Si el objeto de argumento es String Object, compara el contenido carácter por carácter. Devuelve verdadero en caso de que el contenido de ambos objetos de cadena sea el mismo.
La cadena # contentEquals toma la interfaz CharSequence como argumento. CharSequence se puede implementar de 2 maneras: usando i) la clase String o (ii) AbstractStringBuilder (clase padre de StringBuffer, StringBuilder)
En contentEquals () la longitud se compara antes de cualquier comprobación de instancia de objeto. Si la longitud es la misma, comprueba si el objeto argumento es una instancia de AbstractStringBuilder o no. Si es así (es decir, StringBuffer o StringBuilder), el contenido se verifica carácter por carácter. En caso de que el argumento sea una instancia del objeto String, String # es igual a llamado desde String # contentEquals.
En resumen,
Cadena # igual compara el contenido carácter por carácter en caso de que el argumento sea también un objeto Cadena. Y String # contentEquals compara el contenido en caso de que el objeto de argumento implemente la interfaz CharSequence.
String # contentEquals es más lento en caso de que comparemos dos contenidos de cadena de la misma longitud que String # contentEquals internamente llama a String # igual para el objeto String.
En caso de que intentemos comparar objetos con diferente longitud de contenido (digamos "abc" con "abcd"), String # contentEquals es más rápido que String # igual. Porque la longitud se compara antes de cualquier comprobación de instancia de objeto.
Los contentEquals()
cheques método es el contenido son los mismos entre una String
, StringBuffer
, etc, que algún tipo de secuencia de carbón.
Por cierto, la razón histórica de la diferencia es que String originalmente no tenía superclase, por lo que String.equals () toma un String como argumento. Cuando se introdujo CharSequence como la superclase de String, necesitaba una prueba de igualdad propia que funcionara en todas las implementaciones de CharSequence, y que no colisionaría con los equals () ya en uso por String ... así que obtuvimos CharSequence.contentEquals ( ), que es heredado por String.
Si CharSequence ha estado presente en Java 1.0, probablemente solo tendríamos CharSequence.equals () y String simplemente implementaría eso.
Ah, las alegrías de los lenguajes en evolución ...
==
(contentEquals) y===
(equals) en javascript?