Tengo dos listas con diferentes objetos en ellas.
List<Object1> list1;
List<Object2> list2;
Quiero verificar si el elemento de list1 existe en list2, según un atributo específico (Object1 y Object2 tienen (entre otros), un atributo mutuo (con tipo Long), llamado attributeSame).
ahora mismo, lo hago así:
boolean found = false;
for(Object1 object1 : list1){
for(Object2 object2: list2){
if(object1.getAttributeSame() == object2.getAttributeSame()){
found = true;
//also do something
}
}
if(!found){
//do something
}
found = false;
}
Pero creo que hay una manera mejor y más rápida de hacer esto :) ¿Alguien puede proponerlo?
¡Gracias!
Respuestas:
Si solo necesita probar la igualdad básica, esto se puede hacer con el JDK básico sin modificar las listas de entrada en una línea
Si necesita probar una propiedad específica, es más difícil. Recomendaría, por defecto,
... que recopila los distintos valores
list2
y prueba lalist1
presencia de cada valor .fuente
list1
en aSet
antes de comparar, obtendrá O (n) + O (m), es decir, O (n + m), a costa de algo de RAM adicional; es cuestión de elegir entre velocidad o memoria.Puede utilizar Apache Commons CollectionUtils :
Esto supone que ha sobrecargado correctamente la funcionalidad de iguales para sus objetos personalizados.
fuente
Para acortar la lógica de Narendra, puede usar esto:
fuente
list1.stream().anyMatch(list2::contains);
Hay un método para
Collection
nombrarretainAll
pero que tiene algunos efectos secundarios para su referenciaEs como
fuente
La respuesta de Loius es correcta, solo quiero agregar un ejemplo:
fuente
forma más rápida requerirá espacio adicional.
Por ejemplo:
ponga todos los elementos en una lista en un HashSet (debe implementar la función hash usted mismo para usar object.getAttributeSame ())
Revise la otra lista y verifique si algún elemento está en el HashSet.
De esta forma, cada objeto se visita como máximo una vez. y HashSet es lo suficientemente rápido para verificar o insertar cualquier objeto en O (1).
fuente
Según JavaDoc para
.contains(Object obj)
:Entonces, si anula su
.equals()
método para su objeto dado, debería poder hacer:if(list1.contains(object2))...
Si los elementos serán únicos (es decir. Tener diferentes atributos) que podría invalidar la
.equals()
e.hashcode()
y almacenar todo enHashSets
. Esto le permitirá comprobar si uno contiene otro elemento en tiempo constante.fuente
para hacerlo más rápido, puede agregar un descanso; de esa manera, el bucle se detendrá si se encuentra establecido en verdadero:
Si tuviera mapas en lugar de listas con como claves el atributo Igual, podría verificar más rápido un valor en un mapa si hay un valor correspondiente en el segundo mapa o no.
fuente
¿Puede definir el tipo de datos que tiene? ¿es big data? esta ordenado? Creo que debe considerar diferentes enfoques de eficiencia en función de los datos.
Por ejemplo, si sus datos son grandes y no están clasificados, puede intentar iterar las dos listas juntas por índice y almacenar cada atributo de lista en otro asistente de lista. luego podría verificar los atributos actuales en las listas de ayuda.
buena suerte
editado: y no recomendaría sobrecargar iguales. es peligroso y probablemente en contra de su objeto oop significado.
fuente
org.springframework.util.CollectionUtils
fuente
Con
java 8
, podemos hacer lo siguiente para verificar si una lista contiene algún elemento de otra listafuente
Si desea verificar si un elemento existe en una lista, use el método contiene.
fuente