Retrieve distinct element based on multiple attributes of java object using java 8 stream
You can create your own distinct method for example :
private static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
Map<Object, Boolean> seen = new ConcurrentHashMap<>();
return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
}
So you can use it with filter :
List<Person> persons = listPersons.stream()
//@Holger suggest
.filter(distinctByKey(pr -> Arrays.asList(pr.getId(), pr.getName())))
.collect(toList());
Take a look at this :
- Thank you Stuart Marks for the useful distinctByKey method
- https://www.concretepage.com/java/jdk-8/java-8-distinct-example
- https://howtodoinjava.com/java-8/java-stream-distinct-examples/
- demo ideone
If your list person is :
List<Person> listPersons = Arrays.asList(
new Person(1, "person1"),
new Person(1, "person5"),
new Person(2, "person2"),
new Person(1, "person1"),
new Person(1, "person2"),
new Person(1, "person1"),
new Person(3, "person3")
);
Outputs
Person{id=1, name=person1}
Person{id=1, name=person5}
Person{id=2, name=person2}
Person{id=1, name=person2}
Person{id=3, name=person3}
Override hashCode()
and equals()
methods for your class, then you can do something like this:
Set<Person> result = persons.stream().collect(Collectors.toSet());
Set is a data structure that does not allow duplicates so this way you'll only have unique elements.
Here is a solution: https://ideone.com/e.js/G7T2rH