#java #list #stream #java-stream #grouping
Вопрос:
у меня есть java-боб, такой как
class OrderDeatils {
Long orderId;
Long userId;
OrderInfo info;
\Required getter/setter
}
class OrderInfo {
OffsetDateTime orderCreatedDate;
\Required getter/setter
}
У меня есть данные в виде List<OrderDeatils>
списка
orderId. userId. OrderInfo[orderCreatedDate].
1001. 123. 2015/07/07
1002. 124. 2015/08/07
1003. 125. 2015/09/07
1004. 123. 2015/08/07
Как я могу удалить дублирующуюся запись на основе идентификатора пользователя и сохранить данные с минимальной датой, как показано ниже:
orderId. userId. OrderInfo[orderCreatedDate].
1001. 123. 2015/07/07
1002. 124. 2015/08/07
1003. 125. 2015/09/07
Должен возвращать список всего объекта OrderDeatils.
Я пытался, как:
list.stream().collect(
Collectors.groupingBy(OrderDeatils::getUserId,
Collectors.collectingAndThen(
Collectors.reducing((OrderDeatils d1, OrderDeatils d2)
-> d1.getInfo.getOrderCreatedDate().isBefore(d2.getInfo.getOrderCreatedDate()) ? d1 : d2), Optional::get)));
Но ответ не такой, как ожидалось, я не обновляюсь List<OrderDeatils>
по мере вывода.
Ответ №1:
Я не буду писать код для вас, но вот шаги:
- вам нужен
Collectors::toMap
тот, который может выполнить «слияние» в третьем аргументе. Что-то вроде:
...collect(Collectors.toMap(
OrderDeatils::getUserId,
Function.identity(),
(left, right) ->
left.getInfo.getOrderCreatedDate().isBefore(right.getInfo.getOrderCreatedDate()) ? left : right
))
- Это даст вам
Map<Long, OrderDeatils>
то, от чего вам нужны только ценности.
Комментарии:
1. Спасибо, что сработало …небольшой вопрос по этому поводу, если OrderInfo является родительским классом для OrderDeatils …. как OrderDeatils расширяет OrderInfo.. мы получим тот же результат … извините за то, что задал вопрос, должен создать новую тему. Но если вы можете внести свой вклад.
2. @utpalsharma где твой вопрос?
3. Спасибо, я создам новый
Ответ №2:
Вы можете использовать простой набор для фильтрации. При добавлении в набор — метод .add() вернет true, если это новое значение, и false, если значение уже существует в наборе.
Для сортировки вы можете использовать .sorted() и передать компаратор для сортировки по нужному полю.
Set<String> userIdsSet = new HashSet<>();
List<OrderDetails> filteredOrderDetails = list.stream()
.filter(e -> userIdsSet.add(e.getUserId()))
.sorted(Comparator.comparing(OrderDetails::getOrderCreatedDate()))
.collect(Collectors.toList());
Комментарии:
1. Это нарушает рекомендацию о безгражданстве в поведенческих параметрах.