Java 8 Streams 删除重复条目,保留元素的最短日期

问题描述 投票:0回答:3

我有 Java bean,例如:

class OrderDeatils {
    Long orderId;
    Long userId;
    OrderInfo info;

    // Required getters/setters
}

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 

应该返回整个

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>
作为输出。

java list java-stream grouping
3个回答
3
投票

我不会为你编写代码,但步骤如下:

  • 你需要一个
    Collectors::toMap
    可以在第三个参数中进行“合并”。比如:
...collect(Collectors.toMap(
     OrderDeatils::getUserId,
     Function.identity(),
     (left, right) ->
        left.getInfo.getOrderCreatedDate().isBefore(right.getInfo.getOrderCreatedDate()) ? left : right        
))
  • 这将为您提供一个
    Map<Long, OrderDeatils>
    ,您只需要从中获取值。

0
投票
List<OrderDeatils> result = input.stream().collect(Collectors.groupingBy(
        OrderDeatils::getUserId,
        Collectors.minBy(Comparator.comparing(o ->
                o.getInfo().getOrderCreatedDate()))))
        .values().stream()
        .flatMap(Optional::stream)
        .toList();

这使用

Collectors.groupingBy
将结果分组到
Map<Long, Optional<OrderDeatils>>
中,其中键是用户 ID,值是具有最早订单创建日期的
OrderDeatils
。 然后使用地图值上的流将这些值转换为
List<OrderDeatils>


-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());
© www.soinside.com 2019 - 2024. All rights reserved.