2010-04-11 18 views
6

Tengo un escenario en mi código donde necesito comparar dos listas y eliminar de la primera lista, los objetos que están presentes en la segunda lista. Similar a cómo funciona el objeto "removeAll" para List. Como mi Lista se crea en un objeto personalizado, el método removeAll no funcionará para mí.Problema al implementar removeAll para Lista de objetos personalizados

que han intentado varios métodos para hacer este trabajo: - iguales implementadas() y hashCode para el objeto personalizado que comprende la lista - implementado la interfaz Comparable para el objeto personalizado - implementado la interfaz Comparador para el objeto personalizado

Incluso he intentado utilizar los métodos CollectionUtils y ListUtils de Apache Common (resta, intersecta, removeAll). Ninguno parece funcionar.

Entiendo que tal vez necesite escribir algún código de eliminación personalizado. Pero no estoy seguro de cómo hacer eso. Cualquier sugerencia que me ayude a avanzar en la dirección correcta será muy apreciada.

Gracias, Jay

+3

para empezar, ingrese un código para que no adivinemos – Bozho

+0

Creo que la pregunta podría ser más clara si pudiera mostrar el código de lo que está tratando de hacer. – ig0774

+0

Se ha sugerido aquí y debajo, pero específicamente publique el código para sus métodos 'equals' y' hashCode'. Probablemente probó esto pero lo escribió incorrectamente. Este es el enfoque correcto y funcionará con 'removeAll()' si se hace bien. –

Respuesta

14

colecciones de Java ya se atienden a su escenario. Llame al Collection.removeAll(Collection) y eliminará todos los artículos de la colección aprobada utilizando el método equals() para evaluar la igualdad.

List<String> list1 = new ArrayList<String>(); 
Collections.addAll(list1, "one", "two", "three", "four"); 
List<String> list2 = new ArrayList<String>(); 
Collections.addAll(list2, "three", "four", "five"); 
list1.removeAll(list2); // now contains "one", "two" 

para hacer este trabajo los objetos que está guardando sólo tiene que aplicar correctamente el/los iguales contrato hashCode, que es: Dados dos objetos a y b:

a.equals(b) == b.equals(a) 

y

:
a.hashCode() == b.hashCode() if a.equals(b) 

Los métodos equals y hashCode definidos incorrectamente crean un comportamiento indefinido y son la causa común de los problemas relacionados con las colecciones.

+0

@Cletus: en realidad dice (un poco más abajo) que lo intentó y que no funcionó para él. – Roman

+8

@Roman hasta que publique un código, no lo creo. Lo más probable es que se reduzca a algo así como el uso incorrecto de la API o la violación del contrato equal/hashCode, etc. – cletus

+0

Este era mi problema. Regenerated equals y hashCode luego las cosas comenzaron a funcionar nuevamente. Gracias :-) – Avec

6

Anulación de equals y hashCode métodos es suficiente para que el método removeAll funcione en objetos personalizados.

Es probable que no los haya anulado de manera adecuada. Algún código nos ayudará mucho.

4

Usted dijo:

... Desde que se crea en mi lista de un objeto personalizado, el método removeAll no va a funcionar para mí.

Como otros han dicho, .removeAll() debería funcionar para el escenario que usted describe, incluso para objetos personalizados, siempre y cuando los objetos personalizados obedecen a los contratos que las colecciones de Java espera de sus objetos, aplicar adecuadamente a los iguales() y el método hashCode().

He intentado varios métodos para hacer este trabajo: - iguales implementadas() y hashCode para el objeto personalizado que comprende la lista - implementa la interfaz Comparable para el objeto personalizado - implementa la interfaz Comparador para el objeto personalizado .. .

Parece que su se tiran-fuego sobre diferentes enfoques: uno de codificación, intentando que, de forma rápida codificación de otra, tratando de que, de codificación otra, ... Se hacen valer la pena ir más despacio y tratar de entender por qué cada uno enfoque fallido y/o determinar por qué ese enfoque no funcionará para su situación, antes de pasar al siguiente. Si ya investigó y determinó por qué cada enfoque no funcionará, explique en su pregunta. Si no lo has hecho, entonces ayúdenos a publicar el código.

Como la mayoría de las personas están de acuerdo en la primera aproximación (.removeall()) deberían tener trabajo y ya que los objetos personalizados están involucrados, por qué no hacer una revisión rápida de esta cuestión StackOverflow para ver si algo salta de que:

Overriding equals and hashCode in Java

"¿Qué problemas/riesgos debo tener en cuenta al anular equals y hashCode en una clase java?"

0

He encontrado que su declaración original es verdadera. removeAll funciona automáticamente solo si anulas la eliminación en el iterador. Simplemente anulando la eliminación en la Colección no es suficiente porque removeAll (y clear y retainAll) todos usan el iterador para funcionar. Como no debe cambiar la colección subyacente mientras usa el iterador excepto para eliminar en el iterador, si no anula la eliminación en el iterador, removeAll, clear y retainAll no funcionarán. Si lanza una UnsupportedOperationException en el método remove dentro del iterador, eso es lo que verá si llama a uno de los tres métodos discutidos.

Cuestiones relacionadas