【问题标题】:Java 8 Map group by orderid and sort by itemLeastDateJava 8 Map按orderid分组并按itemLeastDate排序
【发布时间】:2021-10-11 03:28:57
【问题描述】:

我希望数据库记录列表按 orderId 分组并按 itemDate 排序。

我正在以任何顺序从数据库中获取这样的记录。相同的 OrderId 的记录会以不同的顺序出现。

OrderId Item Number Item Date
1       12345       3/10/21
2       67890       4/10/21
1       12345       3/11/21  -> duplicate. so take least date of Item 12345
1       23456       3/11/21  -> don't remove this one as itemnumb is unique
3       33441       5/10/21
2       67890       4/11/21  -> duplicate. so take least date 4/10/21 record
2       12333       4/11/21
3       33441       5/11/21  -> duplicate. so take least date 5/10/21 record
3       45321       5/11/21

我只需要首先返回按最少项目日期排序的最高记录。不需要相同订单 ID 的第二条记录。

POJO

public class ItemDetail {

    private String orderId;
    private String itemNumber;
    private Date itemDate;

    //setter/getters
}

DAO层会返回itemDetails列表,即List itemDetails;

从 itemDetails 列表中,我必须像下面的代码一样在地图中设置键、值,

我需要将键存储为字符串中的 OrderId-ItemNumber 组合,值存储为 ItemDetail 对象

public List<ItemDetail> getItemDetails(List<ItemDetail> itemDetails) {
 Map<String, ItemDetail> itemMap = itemDetails.stream()
        .collect(Collectors.groupingBy(itemDetail -> itemDetail.getOrderId()))
        .values()
        .stream()
        .collect(Collectors.toMap(itemDetail -> itemDetail.getOrderId() +"-"+ itemDetail.getItemNumber(), 
                 itemDetail -> itemDetail));
return mapValueAsItemDetailList;
}

最后地图应该只返回这样的记录

OrderId Item Number Item Date
1       12345       3/10/21
1       23456       3/11/21
2       67890       4/10/21
2       12333       4/11/21
3       33441       5/10/21
3       45321       5/11/21

简单来说,我需要按 orderId-itemNumber 分组并按项目日期排序并仅返回最少日期记录。不要删除相同订单编号的唯一商品编号记录。如何在 Java 8 中做到这一点?

记录一张。 12345 不是唯一的。所以删除最高日期的第二条记录。需要保留唯一记录并按 itemdate 删除重复项。

1       12345       3/10/21
1       12345       3/11/21
1       23456       3/11/21

所以只有我想将密钥保留为 orderId-itemNumber

【问题讨论】:

  • 你当前的代码怎么不工作?
  • 我收到此错误,类型不匹配:无法从 Map 转换为 Map
  • 不要将日期作为字符串放入 POJO。保留LocalDate 对象。
  • 那只是 Date 对象。我会更新POJO
  • 清道夫的回答是正确的。你的代码中的问题是第一次分组后的结果类型是 Map 所以 values() 得到 List>.

标签: java sorting java-8 groupingby


【解决方案1】:

首先,考虑使用LocalDateDate 已经过时了。

private LocalDate itemDate;

要删除除最旧的具有相同订单 ID 的商品详情之外的所有商品,您可以先使用toMap 收集器制作地图:1. 使用订单 ID + 商品编号作为键,2. 商品详情本身为价值。 3.指定当有重复键时,选择日期较早的项目明细作为值。

之后,获取地图的值,并从中创建一个列表。然后按日期对列表进行排序。

public List<ItemDetail> getItemDetails(List<ItemDetail> itemDetails) {
    ArrayList<ItemDetail> list = new ArrayList<>(itemDetails.stream().collect(
        Collectors.toMap(
            x -> x.getOrderId() + x.getItemNumber(), // 1
            Function.identity(), // 2
            BinaryOperator.minBy( // 3
                Comparator.comparing(ItemDetail::getItemDate)
            )
        )
    ).values());
    list.sort(Comparator.comparing(ItemDetail::getItemDate));
    return list;
}

【讨论】:

  • 我想保留唯一记录,但此代码将仅返回一个日期最少的订单 ID。我还需要按项目编号分组。所以只有我将密钥保留为 orderid-itemnumber。如果有三个orderid,两个项目号是重复的,一个是唯一的。它也会删除唯一的项目编号。如果原始问题不清楚,请原谅。我已经编辑了原始问题。在您的代码中将密钥保留为 itemDetail -> itemDetail.getOrderId() +"-"+ itemDetail.getItemNumber() 会起作用吗?我正在检查
  • @Abhikhya 是的,我认为这行得通。我认为您还需要对列表进行排序。查看编辑。
猜你喜欢
  • 2021-08-19
  • 1970-01-01
  • 1970-01-01
  • 2012-11-30
  • 1970-01-01
  • 2018-09-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多