Java 8 Streams сокращает удаление дубликатов, сохраняя самую последнюю запись - PullRequest
0 голосов
/ 27 ноября 2018

У меня есть Java-бин, например

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

Если у них длинный список, в котором у нас есть дубликаты по идентификатору, но с другой датой, например:

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

Как можно сократить такой список, сохранив только записи с самой последней датой, например:

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

?Предпочтительно с использованием Java 8 ...

Я начал с чего-то вроде:

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

Это дает мне отображение в отдельных группах, но я застрял в том, как собрать этов список результатов - мои потоки не слишком сильны, я боюсь ...

Ответы [ 3 ]

0 голосов
/ 27 ноября 2018

Ну, я просто собираюсь поместить свой комментарий здесь в форме ответа:

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

Это даст вам Collection вместо List, если вы действительно заботитесь оэтот.

0 голосов
/ 27 ноября 2018

С vavr.io вы можете сделать это так:

var finalContract = Stream.ofAll(contract) //create io.vavr.collection.Stream
            .groupBy(EmployeeContract::getId)
            .map(tuple -> tuple._2.maxBy(EmployeeContract::getDate))
            .collect(Collectors.toList()); //result is list from java.util package
0 голосов
/ 27 ноября 2018

Вы можете сделать это в два этапа следующим образом:

List<EmployeeContract> finalContract = contract.stream() // Stream<EmployeeContract>
        .collect(Collectors.toMap(EmployeeContract::getId, 
                EmployeeContract::getDate, (a, b) -> a.after(b) ? a : b)) // Map<Long, Date> (Step 1)
        .entrySet().stream() // Stream<Entry<Long, Date>>
        .map(a -> new EmployeeContract(a.getKey(), a.getValue())) // Stream<EmployeeContract>
        .collect(Collectors.toList()); // Step 2

Первый шаг : обеспечивает сравнение date с с самым последним, сопоставленным с id.

Второй шаг : сопоставляет эти пары ключ-значение в результате как конечный List<EmployeeContract>.

...