Cómo buscar en una Lista de objetos Java

Tengo una lista de objetos y la lista es muy grande. El objeto es

class Sample { String value1; String value2; String value3; String value4; String value5; } 

Ahora tengo que buscar un valor específico de un objeto en la lista. Di si value3=='three' tengo que devolver esos objetos (Mi búsqueda no siempre se basa en value3)

La lista es

 List list = new ArrayList(); 

¿Cuál es la forma eficiente de hacerlo?

Gracias.

Puede probar con las Colecciones de Apache Commons .

Hay una clase CollectionUtils que le permite seleccionar o filtrar elementos por predicado personalizado.

Tu código sería así:

 Predicate condition = new Predicate() { boolean evaluate(Object sample) { return ((Sample)sample).value3.equals("three"); } }; List result = CollectionUtils.select( list, condition ); 

Actualizar:

En java8 , usando Lambdas y StreamAPI esto debería ser:

 List result = list.stream() .filter(item -> item.value3.equals("three")) .collect(Collectors.toList()); 

¡mucho más bonito!

Usando Java 8

Con Java 8 puede simplemente convertir su lista en una secuencia que le permite escribir:

 import java.util.List; import java.util.stream.Collectors; List list = new ArrayList(); List result = list.stream() .filter(a -> Objects.equals(a.value3, "three")) .collect(Collectors.toList()); 

Tenga en cuenta que

  • a -> Objects.equals(a.value3, "three") es una expresión lambda
  • result es una List con un tipo de Sample
  • Es muy rápido, sin lanzamiento en cada iteración
  • Si su lógica de filtro se vuelve más pesada, puede hacer list.parallelStream() lugar de list.stream() ( leer esto )

Apache Commons

Si no puede usar Java 8, puede usar la biblioteca de Apache Commons y escribir:

 import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.Predicate; Collection result = CollectionUtils.select(list, new Predicate() { public boolean evaluate(Object a) { return Objects.equals(((Sample) a).value3, "three"); } }); // If you need the results as a typed array: Sample[] resultTyped = (Sample[]) result.toArray(new Sample[result.size()]); 

Tenga en cuenta que:

  • Hay un elenco de Object a Sample en cada iteración
  • Si necesita que sus resultados se tipeen como Sample[] , necesita código adicional (como se muestra en mi ejemplo)


Bonus: un buen artículo de blog que habla de cómo encontrar elementos en la lista.

Si siempre busca basado en value3 , puede almacenar los objetos en un Mapa:

 Map> map = new HashMap <>(); 

A continuación, puede llenar el mapa con key = value3 y value = list of Sample objects con esa misma propiedad value3 .

A continuación, puede consultar el mapa:

 List allSamplesWhereValue3IsDog = map.get("Dog"); 

Nota: si no hay 2 instancias de Sample puedan tener el mismo value3 , simplemente puede usar un Map .

Modifico esta lista y agrego una lista a las muestras intente esto

Pseudocódigo

 Sample { List values; List getList() { return values} } for(Sample s : list) { if(s.getString.getList.contains("three") { return s; } } 

Como su lista es una ArrayList , se puede suponer que no está ordenada. Por lo tanto, no hay forma de buscar su elemento que sea más rápido que O (n) .

Si puede, debe pensar en cambiar su lista en un Set (con HashSet como implementación) con un Comparator específico para su clase de muestra.

Otra posibilidad sería usar un HashMap . Puede agregar sus datos como Sample (comience nombres de clase con una letra mayúscula) y use la cadena que desea buscar como clave. Entonces podrías simplemente usar

 Sample samp = myMap.get(myKey); 

Si puede haber varias muestras por clave, use Map> , de lo contrario use Map . Si usa varias claves, tendrá que crear múltiples mapas que contengan el mismo conjunto de datos. Como todos apuntan a los mismos objetos, el espacio no debería ser tan problemático.