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());