Define yourself a key object that contains and compares the required properties. In this simple case, you can use a small list, while each index corresponds to one property. For more complex cases, you can use Map (using property names as keys) or a dedicated class:
Function<Person,List<Object>> toKey=p -> Arrays.asList(p.getName(), p.getAge());
Having such a display function. you can use a simple solution:
list1.stream().map(toKey) .flatMap(key -> list2.stream().map(toKey).filter(key::equals)) .forEach(key -> System.out.println("{name="+key.get(0)+", age="+key.get(1)+"}"));
which can lead to poor performance with fairly large lists. If you have large lists (or predict their sizes), you should use the intermediate Set to speed up the search (changing the complexity of the task time from O(n²) to O(n) ):
list2.stream().map(toKey) .filter(list1.stream().map(toKey).collect(Collectors.toSet())::contains) .forEach(key -> System.out.println("{name="+key.get(0)+", age="+key.get(1)+"}"));
In the above examples, each match is printed. If you are only interested in such a match, you can use either:
boolean exists=list1.stream().map(toKey) .anyMatch(key -> list2.stream().map(toKey).anyMatch(key::equals));
or
boolean exists=list2.stream().map(toKey) .anyMatch(list1.stream().map(toKey).collect(Collectors.toSet())::contains);
source share