Comparando contenido de StringBuffer con iguales

StringBuffer sb1 = new StringBuffer("Java"); StringBuffer sb2 = new StringBuffer("Java"); System.out.println(sb1 == sb2); System.out.println(sb1.equals(sb2)); 

Aquí ambos regresan falsos. ¿Como es posible?

El método equals de StringBuffer no se reemplaza desde Object , por lo que es solo referencia de igualdad, es decir, lo mismo que usar == . Sospecho que la razón de esto es que StringBuffer es modificable, y anular equals es más útil para las clases de valor que podría querer usar como claves (aunque las listas también tienen un equals anulado y StringBuffer es una especie de lista, así que esto es un poco inconsistente).

Está comparando las referencias a los objetos StringBuffer en lugar de las cadenas reales dentro de StringBuffer.

System.out.println(sb1.toString().equals(sb2.toString())) devolvería true y supongo que esto es lo que esperaba o quería lograr.

  1. System.out.println(sb1 == sb2); 

El método equals de StringBuffer devuelve verdadero solo cuando un objeto StringBuffer se compara consigo mismo. Devuelve falso cuando se compara con cualquier otro StringBuffer, incluso si los dos contienen los mismos caracteres.

Esto se debe a que “==” verifica la igualdad de referencia y dado que tanto sb1 como sb2 son referencias de objeto diferentes, por lo que el resultado en este caso es “falso”

Aún así, si desea verificar si el contenido es igual en estos dos Objetos StringBuffer, puede usar esto:

 sb1.toString().equals(sb2.toString()) 2. System.out.println(sb1.equals(sb2)); 

Esto está dando salida como “falso” porque el método .equals () no ha sido anulado en la clase StringBuffer. Entonces está usando el método .equals () de su clase padre “Object”. En la clase de objeto, se ha escrito .equals () para verificar la igualdad de referencia.

Tenga en cuenta que sb3.equals (sb4) devolverá “verdadero” en caso de Cadena. Porque el método .equals () ha sido anulado en la clase String para verificar y hacer coincidir el contenido de dos cadenas diferentes.

La respuesta simple es que StringBuffer (y StringBuilder) no redefinen la semántica base de Object.equals (). Así que equals en un StringBuffer simplemente comparará referencias de objetos.

De hecho, String, StringBuffer, StringBuilder y CharBuffer implementan la interfaz CharSequence , y el javadoc para esta interfaz dice esto:

Esta interfaz no refina los contratos generales de los métodos iguales y hashCode. El resultado de comparar dos objetos que implementan CharSequence es, en general, indefinido. Cada objeto puede ser implementado por una clase diferente, y no hay garantía de que cada clase sea capaz de probar sus instancias para la igualdad con las de la otra. Por lo tanto, es inapropiado utilizar instancias arbitrarias de CharSequence como elementos en un conjunto o como claves en un mapa.

StringBuffer parece no tener el mismo método, por lo que mi primera suposición sería que StringBuffer hereda el método equals de Object , que se compara con sb1 == sb2 . Por lo tanto, ambos métodos producen el mismo resultado.

ambos comparan dos referencias a objetos (sb1 es uno, y sb2 es el segundo), por lo tanto, ambos son diferentes.

Si está intentando comparar contenido, use el método compareTo (…) en la clase String , es decir, primero obtenga el contenido String de StringBuffer utilizando el método toString () ( .toString (). CompareTo ).

PD. a partir de JDK 5, hay otra clase mucho más rápida que se comporta exactamente como StringBuffer – es StringBuilder , y también es pero no es segura para subprocesos.

 StringBuffer sb1 = new StringBuffer("Java"); StringBuffer sb2 = new StringBuffer("Java"); System.out.println(sb1.toString().compareTo(sb2.toString())); 

Preguntándose por qué StringBuffer no anula el método equals . Probablemente porque el contenido del objeto se obtiene mediante el método toString() y que tiene el método deseado.

Con JDK / 11 , ahora se pueden comparar dos StringBuffer s sin una toString adicional, esto se puede hacer utilizando la API recién presentada –

 public int compareTo​(StringBuffer another) 

Compara dos ejemplos de StringBuffer lexicográficamente. Este método sigue las mismas reglas para la comparación lexicográfica como se define en el CharSequence.compare(this, another) . Para una comparación de Cadena sensible a la configuración local más detallada, consulte el Clasificador.

Nota de implementación : este método sincroniza en esto , el objeto actual, pero no StringBuffer, otro con el que se compara este StringBuffer.

Devuelve : el valor 0 si este StringBuffer contiene la misma secuencia de caracteres que la del argumento StringBuffer; un entero negativo si este StringBuffer es lexicográficamente menor que el argumento StringBuffer; o un entero positivo si este StringBuffer es lexicográficamente mayor que el argumento StringBuffer.

Uso de muestra:

 StringBuffer stringBuffer = new StringBuffer("null"); StringBuffer anotherStringBuffer = new StringBuffer("NULL"); System.out.println(stringBuffer.compareTo(anotherStringBuffer) == 0); // shall print 'false' 

Stringbuffer’s equals() no se anula. No compara valores, solo compara asignaciones de valores de referencia. Es por eso que estás obteniendo información falsa ya que ambos se están refiriendo a diferentes objetos.