es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Cómo comparar dos listas de objetos personalizados para algunas propiedades utilizando streams en Java?

¿Cuál es la mejor manera de comparar los elementos de dos listas solo por algunas de sus propiedades?

public class A {
    private String type;
    private String value;
    private String foo;
    private String bar;
}

List<a> listA = List.of(...);
List<a> listB = List.of(...);

Lo intenté de la siguiente manera:

return listA.stream().anyMatch(a -> listB.stream().anyMatch(b -> {
    a.getType().equals(b.getType());
    a.getValue().equals(b.getValue());
}));

…pero esto no funciona.

Sería suficiente encontrar cualquier/la primera coincidencia y devolver verdadero en ese caso, o falso si no se puede encontrar ninguna coincidencia.

Actualización / Ejemplo

A a1 = new A();
a1.setType("AB");
a1.setValue("xx");

A a2 = new A();
a2.setType("XY");
a2.setValue("00");

List<a> listA = List.of(a1, a2);

A b1 = new A();
b1.setType("AB");
b1.setValue("xx");

A b2 = new A();
b2.setType("XY");
b2.setValue("");

List<a> listB = List.of(b1, b2);

Utilizando estas listas en (con compAs = listA y expAs = listB):

public static boolean isValid(final List<a> compAs, final List<a> expAs) {

    return compAs.stream().anyMatch(c -> expAs.stream().anyMatch(e -> {
        return c.getType().equals(e.getType()) &&
                c.getValue().equals(e.getValue());
    }));
}

una prueba assertFalse(isValid()) falla (devuelve verdadero mientras se espera falso).

También lo intenté con return e.equals(c).

Usar allMatch() termina en un fallo si las listas son realmente iguales.

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Para comparar dos listas de objetos según algunas de sus propiedades, puedes utilizar el método anyMatch() de la clase Stream. Necesitas crear un stream sobre una de las listas y, para cada elemento, crear otro stream sobre la segunda lista para buscar coincidencias. Luego, puedes utilizar una función lambda para definir las condiciones de la coincidencia, comparando las propiedades relevantes de los dos objetos. Finalmente, puedes regresar un valor booleano que indique si se encontró una coincidencia o no.

    Aquí tienes un ejemplo de código que demuestra este enfoque, basado en la clase A proporcionada en la pregunta:

    public static boolean compareListsByProperties(List<a> lista1, List<a> lista2) {
        return lista1.stream().anyMatch(a -> 
                lista2.stream().anyMatch(b -> 
                    a.getTipo().equals(b.getTipo()) && a.getValor().equals(b.getValor())
                )
            );
    }
    

    En este ejemplo, queremos comparar las dos listas (lista1 y lista2) según las propiedades tipo y valor de los objetos en la lista. El método anyMatch() se utiliza para regresar un valor booleano que indique si algún elemento en lista1 coincide con algún elemento en lista2 basado en estas propiedades. La función lambda dentro de anyMatch() define las condiciones de comparación para los dos objetos (a y b) que se están comparando.

    Ten en cuenta que, para comparar las propiedades de los objetos, puedes elegir usar equals() o ==, dependiendo de si las propiedades son tipos primitivos u objetos. Además, para mejorar el rendimiento, puedes considerar seleccionar la lista más pequeña para crear el stream y así potencialmente reducir el número de comparaciones requeridas.

Comments are closed.