Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java 8 Streams reduce remove duplicates keeping the most recent entry

I have a Java bean, like

class EmployeeContract {
    Long id;
    Date date;
    getter/setter
}

If a have a long list of these, in which we have duplicates by id but with different date, such as:

1, 2015/07/07
1, 2018/07/08
2, 2015/07/08
2, 2018/07/09

How can I reduce such a list keeping only the entries with the most recent date, such as:

1, 2018/07/08
2, 2018/07/09

? Preferably using Java 8...

I've started with something like:

contract.stream()
         .collect(Collectors.groupingBy(EmployeeContract::getId, Collectors.mapping(EmployeeContract::getId, Collectors.toList())))
                    .entrySet().stream().findFirst();

That gives me the mapping within individual groups, but I'm stuck as to how to collect that into a result list - my streams are not too strong I'm afraid...

like image 208
Nestor Milyaev Avatar asked Nov 27 '18 17:11

Nestor Milyaev


People also ask

Does Java Stream distinct preserve order?

Java Stream distinct() MethodIf the stream is ordered, the encounter order is preserved. It means that the element occurring first will be present in the distinct elements stream. If the stream is unordered, then the resulting stream elements can be in any order.

How do you prevent duplicates in Java 8?

Using Java 8 Stream. You can use the distinct() method from the Stream API. The distinct() method return a new Stream without duplicates elements based on the result returned by equals() method, which can be used for further processing.

How do I delete duplicates in Stream API?

To remove the duplicates from the arraylist, we can use the java 8 stream api as well. Use steam's distinct() method which returns a stream consisting of the distinct elements comparing by object's equals() method. Collect all district elements as List using Collectors.


1 Answers

Well, I am just going to put my comment here in the shape of an answer:

 yourList.stream()
         .collect(Collectors.toMap(
                  EmployeeContract::getId,
                  Function.identity(),
                  BinaryOperator.maxBy(Comparator.comparing(EmployeeContract::getDate)))
            )
         .values();

This will give you a Collection instead of a List, if you really care about this.

like image 55
Eugene Avatar answered Sep 22 '22 13:09

Eugene