2011-11-30 9 views
22

tengo algún objetoencargo de ArrayList Contiene método

class A { 
    private Long id; 
    private String name; 
    public boolean equals(Long v) { 
    return this.id.equals(v); 
    } 
} 

y ArrayList de estos objetos. Lo que quiero es poder verificar si esa lista contiene algún objeto por campo de objeto. Por ejemplo:

ArrayList<A> list = new ArrayList<A>(); if (list.contains(0L)) {...} 

pero overrided Igual método no se me ayuda. ¿Que estoy haciendo mal? Gracias método

ACTUALIZACIÓN Y debería anular un código hash() también?

+0

has anulado igual() en tu clase A? si es así, ¿puedes publicarlo aquí? – c05mic

+0

A juzgar por las respuestas a continuación, supongo que no hay una solución conveniente para esto. Creo que esto podría resolverse con una implementación de clase anónima, como la que se usa al llamar a Collections.sort() con su propio Comparador. – kodu

+0

Después de buscar un poco más, encontré algunas respuestas útiles aquí: http://stackoverflow.com/questions/587404/finding-all-objects-that-have-a-given-property-inside-a-collection – kodu

Respuesta

38

aquí hay un código que podría demostrar cómo funciona:

import java.util.ArrayList; 

class A { 
    private Long id; 
    private String name; 

    A(Long id){ 
     this.id = id; 
    } 

    @Override 
    public boolean equals(Object v) { 
     boolean retVal = false; 

     if (v instanceof A){ 
      A ptr = (A) v; 
      retVal = ptr.id.longValue() == this.id; 
     } 

    return retVal; 
    } 

    @Override 
    public int hashCode() { 
     int hash = 7; 
     hash = 17 * hash + (this.id != null ? this.id.hashCode() : 0); 
     return hash; 
    } 
} 

public class ArrayList_recap { 
    public static void main(String[] args) { 
     ArrayList<A> list = new ArrayList<A>(); 

     list.add(new A(0L)); 
     list.add(new A(1L)); 

     if (list.contains(new A(0L))) 
     { 
      System.out.println("Equal"); 
     } 
     else 
     { 
      System.out.println("Nah."); 
     }  
    } 

} 

primer lugar, no es un reemplazo del método equals (Object o). Luego está la anulación del hashCode() también. También tenga en cuenta que la instancia de A check en los iguales garantizará que no intente comparar diferentes objetos.

¡Eso debería hacer el truco! Espero que haya sido de ayuda! Saludos :)

+0

buen ejemplo ¡Gracias! –

+0

¿Funciona también para el método containsAll? – Amriteya

+0

Funciona para containsAll – Amriteya

8

No ha anulado el método en su clase. Para anular, los parámetros del método también deben ser del mismo tipo.

debe ser

public boolean equals(Object o) { 

} 

mientras que en su caso es

public boolean equals(Long o) { 

} 

es probable que tenga que hacer esto

public boolean equals(Object o) 
    { 
     if (o == null) return false; 
     if (o == this) return true; //if both pointing towards same object on heap 

      A a = (A) o; 
     return this.id.equals(a.id); 
    } 
+0

He actualizado el código, pero el resultado es el mismo. Contiene no puede encontrar un objeto con id. Específico – nKognito

+0

puede publicar el código correspondiente. – Zohaib

+1

Ver mi respuesta para una posible explicación - * "El otro problema ..." * –

7

Lo que estoy haciendo mal?

Usted no está anulando. Estás sobrecargando

El método contains llama al método equals con firma equals(Object), por lo que este (nuevo) método que ha agregado no se ejecutará.

El otro problema es que su método equals tiene una semántica incorrecta para contains. El método contains necesita comparar this con un objeto que podría ser un miembro de la lista. Su lista no contiene Long objetos. Contiene objetos del tipo A.

Ahora puede salirse con la suya con esto ... si usa tipos de listas sin procesar ... pero lo que está tratando de hacer es una violación del contrato de la API y una mala práctica. Una mejor solución es iterar y probar los elementos de la lista explícitamente.


Y debería reemplazar un método hashCode() también?

Si se reemplaza equals(Object) entonces también debería anular hashcode().

Aquí no hará ninguna diferencia, pero es esencial si alguna vez coloca sus objetos A en estructuras de datos hash. Y como no sabe qué va a hacer el siguiente tipo con su código, es una buena práctica asegurarse de que equals(Object) y hashCode() tengan semántica compatible.

+0

Gracias por la explicación – nKognito