java - two - integer values compared using== or !=
Comparando nĂºmeros en Java (7)
En Java, todos los tipos numéricos se extienden desde java.lang.Number. ¿Sería una buena idea tener un método como el siguiente:
public boolean areEqual(Number first, Number second) {
if (first != null && second != null) {
return first.equals(second);
}
}
Me preocupan los casos en los que un doble 2.00000 no es igual a un int 2. ¿Estos son manejados por los iguales incorporados? Si no, ¿hay alguna forma de escribir una función de comparación de números simple en java? (Las bibliotecas externas, como los comunes de apache, están bien)
El método específico que sugieras fallaría, porque está utilizando equals()
heredado de Object
. Es decir, verificará si los objetos Number
son iguales, no si sus valores son los mismos.
Si ese fue solo un ejemplo ilustrativo, actualizaré mi respuesta.
La respuesta de Polygene en realidad cubre el terreno al que me dirigía. También te puede interesar esta pregunta: ¿Por qué java.lang.Number implementa Comparable? .
En una tangente a un par de respuestas, puedo sugerir que en lugar de escribir algo como:
boolean compare(Object o1, Object o2)
{
if (o1==null)
return o2==null;
if (o2==null)
return false;
return o1.equals(o2);
}
Es mucho más conciso, y creo que un poco más eficiente, para escribir:
boolean compare(Object o1, Object o2)
{
return o1==o2 || o1!=null && o2!=null && o1.equals(o2);
}
Si ambos son nulos, o1 == o2 devolverá verdadero. Si no lo son, pero son el mismo objeto, también está bien.
Técnicamente, el o2! = Null no es necesario para la mayoría de las implementaciones de iguales, pero si realmente estuviera siendo tan genérico como para hacer esto en los Objetos como en el ejemplo anterior, por supuesto no sabría cómo se escribió cada anulación.
La comparación de números entre enteros y puntos flotantes casi nunca dará lo que está buscando. Sin embargo, si este es un ejercicio simple, podría implementar la comparación comparando las representaciones de cadena de los valores, como en:
public boolean areEqual(Number first, Number second) {
if (first == null) {
return second == null;
}
if (second == null) {
return false;
}
return first.toString().equals(second.toString());
}
Sé que es un tema antiguo, pero ... Para comparar dos números en Java, puedes usar el método compareTo de BigDecimal. BigDecimal puede contener todo, desde corto hasta doble o BigInteger, por lo que es la clase perfecta para esto.
Así que puedes intentar escribir algo como esto:
public int compareTo(Number n1, Number n2) {
// ignoring null handling
BigDecimal b1 = new BigDecimal(n1.doubleValue());
BigDecimal b2 = new BigDecimal(n2.doubleValue());
return b1.compareTo(b2);
}
Este seguramente no es el mejor enfoque con respecto al rendimiento. Las siguientes pruebas funcionaron hasta ahora, al menos con JDK7:
assertTrue(compareTo(new Integer(1), new Integer(2)) == -1);
assertTrue(compareTo(new Integer(1), new Double(2.0)) == -1);
assertTrue(compareTo(new Integer(1), new Double(Double.MAX_VALUE)) == -1);
assertTrue(compareTo(new Integer(1), new Double(Double.MIN_VALUE)) == 1);
assertTrue(compareTo(new Integer(1), new Double(1.000001)) == -1);
assertTrue(compareTo(new Integer(1), new Double(1.000)) == 0);
assertTrue(compareTo(new Integer(1), new Double(0.25*4)) == 0);
assertTrue(compareTo(new Integer(1), new AtomicLong(1)) == 0);
Si desea saber si las referencias de los objetos son iguales, entonces los métodos existentes se ajustan a la factura. Un Double
representa 2.0
y un Integer
representa 2
son objetos definitivamente diferentes, y ciertamente no son intercambiables en un sentido general.
Si solo quiere saber si los valores numéricos son iguales, puede usar el método Number.doubleValue() para convertir ambos números en dobles, luego comparar esos números juntos (probablemente permitiendo una pequeña tolerancia, ya que la mayoría de los números están representados de manera inexacta) , como 1.99999999996583 para lo que debería ser 2, dependiendo de los pasos de cálculo intermedios). Algo como lo siguiente:
private static final double EPSILON = 0.000000000000001d;
public static boolean areEquivalentNumbers(Number a, Number b)
{
if (a == null)
{
return b == null;
}
else if (b == null)
{
return false;
}
else
{
return Math.abs(a.doubleValue() - b.doubleValue()) < EPSILON;
}
}
Un Double
NUNCA es equals
a un Integer
. Además, un double
no es lo mismo que un Double
.
Java tiene tipos primitivos y tipos de referencia. Los tipos verdaderamente numéricos en Java no se extienden desde Number
, porque son primitivos.
Es posible que desee considerar un sistema en el que no esté mezclando tipos, ya que generalmente esto causará muchos problemas con las conversiones implícitas / explícitas que pueden / no perder información, etc.
Preguntas relacionadas
En int
vs Integer
:
- ¿Cuál es la diferencia entre un int y un entero en Java / C #?
- ¿Java está completamente orientado a objetos?
En comparación de Number
:
Ver también
- Guía de lenguaje Java / Autoboxing
- JLS 4.2 4.2 Tipos y valores primitivos
Los tipos numéricos son los tipos integrales y los tipos de punto flotante. Los tipos integrales son
byte
,short
,int
,long
ychar
. Los tipos de puntofloat
sonfloat
ydouble
.
En cómputo de tipo mixto
El cálculo de tipo mixto es el tema de al menos 4 rompecabezas en Java Puzzlers .
Aquí hay varios extractos:
por lo general, es mejor evitar los cálculos de tipo mixto porque son intrínsecamente [...] confusos. En ninguna parte es esto más evidente que en las expresiones condicionales. Las comparaciones de tipo mixto siempre son confusas porque el sistema está obligado a promover un operando para que coincida con el tipo del otro. La conversión es invisible y puede no producir los resultados esperados.
Prescripción : Evite los cálculos que mezclan tipos integrales y de punto flotante. Prefiero aritmética integral a punto flotante.
no puedes llamar
number.equals(number2);
porque, si el número es un Doble y el número2 es un Entero, no serán de la misma clase y obtendrás una excepción informándote de ello.
Podría escribir una clase de comparación usted mismo que acepte los objetos Number, pero tendrá que tener en cuenta las diferentes subclases de Number