使用 Java Stream + LinkedHashMap 按日期排序 Map —— 实战与原理

在业务开发中,我们经常会拿到这样一类数据:

{
    "supplierId": 56,
    "supplierName": "雄安铁建集团",
    "dailyInAmount": {
        "2025-09-14": 170.00,
        "2025-09-13": 180.00,
        "2025-09-12": 190.00,
        "2025-09-11": 200.00,
        "2025-09-18": 130.00,
        ...
    }
}

这是一个 Map<String, BigDecimal>(key 是日期字符串,value 是金额)。由于 HashMap 的遍历顺序是无序的,前端拿到的 dailyInAmount 会是乱序的日期。

实际效果可能是这样的:

"2025-09-14": 170.00,
"2025-09-13": 180.00,
"2025-09-30": 10.00,
...

而我们的需求是:按日期升序输出,这样前端展示就是有序的时间轴:

"2025-09-01": 300.00,
"2025-09-02": 290.00,
"2025-09-03": 280.00,
...

Stream 解决方案

Java 8 之后有了 Stream API,可以很优雅地完成这种“对 Map 按键排序并收集”的需求:

// dailyAmount: Map<String, BigDecimal> 原始数据
Map<String, BigDecimal> sortedDailyAmount = dailyAmount.entrySet().stream()
        .sorted(Map.Entry.comparingByKey()) // 按 key 排序
        .collect(Collectors.toMap(
                Map.Entry::getKey,         // key 提取器
                Map.Entry::getValue,       // value 提取器
                (e1, e2) -> e1,            // 冲突时取第一个(一般不会冲突)
                LinkedHashMap::new         // 最终 Map 类型:按插入顺序
        ));

planVO.setDailyInAmount(sortedDailyAmount);

核心点:

  • entrySet().stream()Map 本身不是 Collection,没有 stream();要流式处理必须先取 entrySet()
  • .sorted(Map.Entry.comparingByKey()):对 entry 流按 key 自然顺序排序。这里 key 是 yyyy-MM-dd 格式的字符串,字典序 = 时间顺序。
  • Collectors.toMap(...) 的 4 个参数:
    1. key 映射器
    2. value 映射器
    3. 冲突合并策略
    4. 最终 Map 类型
  • 选择 LinkedHashMap 是为了保留插入顺序(我们已经按日期排序后再插入,所以迭代就是日期顺序)。

效果

经过这段代码处理后,前端返回的数据就是按日期顺序排列的:

"dailyInAmount": {
    "2025-09-01": 300.00,
    "2025-09-02": 290.00,
    "2025-09-03": 280.00,
    "2025-09-04": 270.00,
    ...
}

常见变体

  1. 按 value 排序.sorted(Map.Entry.<String,BigDecimal>comparingByValue().reversed())
  2. 按真实时间排序(字符串不规则时): DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy/MM/dd"); .sorted(Comparator.comparing(e -> LocalDate.parse(e.getKey(), dtf)))
  3. 用 TreeMap 简化Map<String,BigDecimal> sorted = new TreeMap<>(dailyAmount);

TreeMap 会自动按 key 排序,不过返回的是 SortedMap,不是按插入顺序的 LinkedHashMap;视需求选择。

总结

  • Map 本身没有 stream(),要处理键值对请用 entrySet().stream()
  • sorted + Collectors.toMap 是 Java 8 流处理 Map 排序的经典用法。
  • 指定 LinkedHashMap::new 可以让结果按我们排序后的顺序迭代。
  • 对日期、金额这类业务数据,前端展示通常要求有序,这就是这种用法的典型场景。

这段代码简洁优雅地完成了“无序 Map → 有序 Map”的转换,是 Stream 在日常业务里非常常见的一种用法。

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇