Java 8 Streams 删除重复条目,保留最小日期和 return 更新的对象列表
Java 8 Streams remove duplicates entry, keep which have min date and return updated List of object
我有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
如何,我可以删除基于 userId 的重复条目并保留最小日期的数据,如下所示:
orderId. userId. OrderInfo[orderCreatedDate].
1001. 123. 2015/07/07
1002. 124. 2015/08/07
1003. 125. 2015/09/07
应该 return 整个 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>
作为输出。
我不会为您编写代码,但步骤如下:
- 您需要一个可以在第三个参数中进行“合并”的
Collectors::toMap
。类似于:
...collect(Collectors.toMap(
OrderDeatils::getUserId,
Function.identity(),
(left, right) ->
left.getInfo.getOrderCreatedDate().isBefore(right.getInfo.getOrderCreatedDate()) ? left : right
))
- 这将为您提供一个
Map<Long, OrderDeatils>
,您只需要其中的值。
您可以使用一个简单的集合来进行过滤。
添加到集合后 - .add() 方法将 return 如果它是新值则为真,如果该值已存在于集合中则为假。
对于排序,您可以使用 .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());
我有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
如何,我可以删除基于 userId 的重复条目并保留最小日期的数据,如下所示:
orderId. userId. OrderInfo[orderCreatedDate].
1001. 123. 2015/07/07
1002. 124. 2015/08/07
1003. 125. 2015/09/07
应该 return 整个 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>
作为输出。
我不会为您编写代码,但步骤如下:
- 您需要一个可以在第三个参数中进行“合并”的
Collectors::toMap
。类似于:
...collect(Collectors.toMap(
OrderDeatils::getUserId,
Function.identity(),
(left, right) ->
left.getInfo.getOrderCreatedDate().isBefore(right.getInfo.getOrderCreatedDate()) ? left : right
))
- 这将为您提供一个
Map<Long, OrderDeatils>
,您只需要其中的值。
您可以使用一个简单的集合来进行过滤。 添加到集合后 - .add() 方法将 return 如果它是新值则为真,如果该值已存在于集合中则为假。
对于排序,您可以使用 .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());