2009-09-09 10 views
29

¿Hay algún método en el JDK que compare dos objetos para la igualdad, teniendo en cuenta los nulos? Algo como esto:Comparar dos objetos con un cheque para nulo

public static boolean equals(Object o1, Object o2) 
{ 
    if (o1 == null) 
    { 
     return o2 == null; // Two nulls are considered equal 
    } 
    else if (o2 == null) 
    { 
     return false; 
    } 

    return o1.equals(o2); 
} 

Parece tonto para escribir este método a mí mismo ya yo creo que tiene que existir ya en alguna parte.

Respuesta

51

Java 7.0 agregó una nueva clase útil: Objects.

Tiene un método exactamente para esto: Objects.equals(Object a, Object b)

+0

Bueno, tenga en cuenta que Java 7 aún no está disponible universalmente. Por lo general, trato de no utilizar una API hasta que su implementación haya alcanzado al menos el 95% –

+1

@EdwardFalk Sí, y también tenga en cuenta que Java 7 (o cualquier otra versión) nunca alcanzará el 100% de disponibilidad. Hoy es 12 de julio de 2015, Java 7 tiene exactamente 4 años, Java 6 ** ** 9 años **. Incluso Java 7 alcanzó ** el final de la vida útil **, lo que significa que no habrá más actualizaciones públicas, incluso para Java 7. ¿Por qué alentarías a usar solo Java 6.0 API? Sí, hay computadoras que solo tienen Java 6.0, pero personalmente no quiero desarrollar software para sistemas con una década de antigüedad, a expensas de renunciar a las características agregadas en Java 7 y 8. – icza

+0

Sí, ese es mi estilo de trabajo . Solo comencé a usar las características de Java 6 en los últimos años, y aún no uso las características de Java 7 u 8. He sido así toda mi vida; No comencé a usar Ansi C hasta que K & R C ya no estaba disponible en ninguna parte. Usaré nuevas funciones cuando las necesite, pero siempre que sea posible, prefiero que mi código se compile y se ejecute en todas partes. –

4

Si usted está preocupado por NullPointerExceptions usted podría probar la igualdad como:

if (obj1 != null && obj1.equals(obj2)) { ... } 

El contrato general de equals() es que un objeto no nulo no debe ser nunca igual a una referencia nula, y que el método equals() debería devolver falso si está comparando un objeto con una referencia nula (y no arrojar un NPE).

+2

uso esa lógica en otros escenarios, pero aquí específicamente quiere dos nulos que se consideran iguales (y por lo tanto para ejecutar la cláusula de verdad). Hacer esto en línea sería bastante detallado: if ((obj1 == null && obj2 == null) || (obj1! = Null && obj1.equals (obj2))) {...} – dcstraw

+1

Este es uno de esos construcciones (como comprobar una cadena para nulo y vacío o cerrar una secuencia sin preocuparse por una IOException) que es difícil para los ojos y para lo que commons-lang tiene una solución. – SingleShot

+0

Estoy de acuerdo con SingleShot y uso commons-lang a menudo para cosas como esta. –

17

Apache Commons Lang tiene dicho método: ObjectUtils.equals(object1, object2). No desea los medicamentos genéricos en tal método, dará lugar a errores de compilación falsos, al menos en el uso general. Iguala sabe muy bien (o debería, es parte del contrato) comprobar la clase del objeto y devolver falso, por lo que no necesita ningún tipo de seguridad adicional.

+0

Sí, supongo que los genéricos realmente no le comprarán nada en este caso. Todavía podría pasar en tipos completamente diferentes y la inferencia de tipo solo seleccionará Object como parámetro de tipo. No estoy seguro de a qué se refieren los "falsos errores de compilación" a los que se refiere. – dcstraw

+0

Definitivamente he visto intentos de hacer genéricos como ese tienen problemas (con parámetros genéricos, y similares). No pude reproducirlo rápidamente en este escenario, así que puede que tengas razón, pero si es así, entonces los genéricos no tienen sentido, ya que aceptarán cualquier cosa, entonces ¿por qué no declaras Objeto? – Yishai

+1

De acuerdo. Usar Object es mejor en este caso. – dcstraw

2

Cada vez que me encuentro con una necesidad y pienso "esto es tan común que Java debe tenerla", pero creo que no, reviso el proyecto de Jakarta Commons. Casi siempre lo tiene. Una búsqueda rápida de la API commons-lang (que tiene las utilidades más básicas comunes) muestra un método equals() que proporciona lo que desea.

14

Fwiw, este fue mi aplicación:

private static boolean equals(Object a, Object b) { 
    return a == b || (a != null && a.equals(b)); 
} 

En mi solicitud, sé que A y B será siempre el mismo tipo, pero sospecho que esto funciona bien, incluso si no lo son, siempre que a.equals() se implemente razonablemente.

+2

La nueva forma es 'Objects.equals (Object a, Object b)' – tmin

+1

New in 1.7. Bonito. –

+0

'return (a == null)? (a == b): a.equals (b); 'solo parece mucho más legible que lo que tienes allí (incluso si llama igual para el mismo objeto). – Dukeling

5
public static boolean equals(Object object1, Object object2) { 
    if (object1 == null || object2 == null) { 
     return object1 == object2; 
    } 
    return object1.equals(object2); 
}