du-it
du-it

Reputation: 3009

How to compare two lists of custom objects for some properties using streams in Java?

What is the best way to compares the items of two lists by (only) some of their properties?

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(...);

I tried

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

...but this doesn't work.

It would be sufficient to find any/the first match and return true then or false if no match can be found.

Update / Example


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);

Using these lists in (with compVal = listA and expVal = listB):

public static boolean isValid(final List<A> compAs, final List<A> expAs) {
    
    return compAs.stream().anyMatch(a -> expAs.stream().anyMatch(e -> {
    return c.getType().equals(e.getType()) &&
                c.getValue().equals(e.getValue())
    }
} 

an assertFalse(isValid()) test fails (returns true while false is expected).

I tried with

return e.equals(c)

as well.

Using allMatch() ends up in a failure if the list are really equal.

Upvotes: 1

Views: 8036

Answers (1)

Eran
Eran

Reputation: 393801

If you want both properties to match, it should be:

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

This will compare all pairs of elements of the two lists until a match is found.

EDIT:

If you require that each element of the first List have a matching element of the second List, use allMatch in the outer Stream:

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

Upvotes: 1

Related Questions