2011-07-22 36 views
112

Consideremos la sencilla clase de prueba:BigDecimal es igual a() frente compareTo()

import java.math.BigDecimal; 

/** 
* @author The Elite Gentleman 
* 
*/ 
public class Main { 

    /** 
    * @param args 
    */ 
    public static void main(String[] args) { 
     // TODO Auto-generated method stub 
     BigDecimal x = new BigDecimal("1"); 
     BigDecimal y = new BigDecimal("1.00"); 
     System.out.println(x.equals(y)); 
     System.out.println(x.compareTo(y) == 0 ? "true": "false"); 
    } 

} 

Puede (consciente) dice que x es igual a y (no objeto de referencia), pero cuando se ejecuta el programa, el siguiente resultado muestra:

false 
true 

pregunta: ¿Cuál es la diferencia entre compareTo() y equals() en BigDecimal que compareTo puede determinar que es x EQUA l a y?

PD: Veo que BigDecimal tiene un método inflate() en el método equals(). ¿Qué hace realmente inflate()?

+0

anuncio 'inflar()': no es parte de la API pública, ya que sólo manipula la representación interna y no tiene efecto visible para el "exterior". Entonces, a menos que realmente desee estudiar la implementación de 'BigDecimal' en profundidad, le sugiero que ignore este método. –

+0

Puede encontrar una breve explicación y fragmentos de código fuente [aquí] (http://stackoverflow.com/a/39163942/4723795) – xenteros

Respuesta

157

La respuesta está en the JavaDoc of the equals() method:

diferencia de compareTo, este método considera dos BigDecimal objetos iguales sólo si son iguales en valor y la escala (por lo tanto 2,0 no es igual a 2,00 cuando se compara con este método).

En otras palabras: equals() comprueba si los objetos son BigDecimalexactamente la misma en todos los aspecto. compareTo() "solo" compara su valor numérico.

+13

Esa es una parte muy complicada de 'BigDecimal' si no lee el JavaDoc con cuidado. :) - Tenemos algunos errores extraños hasta que nos dimos cuenta de la diferencia. – Thomas

+3

Muchas partes de la API estándar actúan "de forma no intuitiva", cuando lo intuitivo no sería correcto. 'BigDecimal' es una de esas cosas. Por lo tanto, uno siempre debe verificar el JavaDoc. * Al menos * una vez que descubres que algo extraño está sucediendo. –

+6

Gracioso. Después de leer su respuesta, comprobé Comparable y afirma que la consistencia con iguales "es muy recomendable (pero no obligatoria)" – SJuan76

1

Veo que BigDecimal tiene un método inflate() en el método equals(). ¿Qué hace inflar() en realidad?

Básicamente, inflate() llamadas BigInteger.valueOf(intCompact) si es necesario, es decir, se crea el valor sin escala que se almacena como un BigInteger de long intCompact. Si no necesita ese BigInteger y el valor sin escalar cabe en un longBigDecimal parece intentar ahorrar espacio el mayor tiempo posible.

+0

No tengo idea de lo que escribió (especialmente con la última frase). –

+0

@The Elite Gentlement La última oración debería simplemente decir que internamente 'BigDecimal' conserva su valor sin escalar en 'long' y' BigInteger'. Si el 'BigInteger' no se necesita internamente, no se crea, pero si se necesita (por ejemplo, cuando 'iguales' encuentra un' BigDecimal 'inflado y no inflado) 'inflate()' se usa para crearlo. - Para resumir: 'inflate()' maneja las conversiones internas si es necesario y dado que es privado, no debería importar a los usuarios de la clase. – Thomas

-3

También puede comparar con el valor doble

BigDecimal a= new BigDecimal("1.1"); BigDecimal b =new BigDecimal("1.1"); 
System.out.println(a.doubleValue()==b.doubleValue()); 
+3

Esto no funcionará una vez que el número sea lo suficientemente grande. – xenteros

+2

Por favor, evite esta solución tanto como sea posible. Incluso los dobles deben compararse con "épsilon". No tiene sentido tener BigDecimal y compararlo como dobles ... hay una gran probabilidad de que dispares tu propia pierna. –