You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java8中拆分字符串并构建年份分组的月份Map问题

正确实现Java 8中按年份分组月份并排序的方案

问题场景

现有格式为20232,20221,20222,20223,20224,20225,20226,20227,20228,20229,202210,202211,202212,20231的字符串,其中前4位为年份,后续字符为月份。需要构建一个Map,以年份为Key,对应所有存在的升序排列且无重复的月份为Value。

原实现输出存在数据重复问题,错误输出如下:

[Key] : 2023 [Value] : 2,1,2,3,4,5,6,7,8,9,10,11,12,1
[Key] : 2022 [Value] : 2,1,2,3,4,5,6,7,8,9,10,11,12,1

原代码问题分析

  • 所有年份共享同一个StringBuilder实例,每次追加都会把所有月份累加,导致每个Key对应的Value都是所有月份的拼接
  • 没有去重逻辑,重复月份会被多次添加
  • 缺乏排序处理,月份无法保证升序
  • 使用未指定泛型的HashMap,存在类型安全隐患

正确实现方案

方案一:Java 8 Stream API(简洁高效)

利用Stream的分组、收集功能,结合TreeSet自动去重并排序:

import java.util.Map;
import java.util.TreeSet;
import java.util.stream.Collectors;

public class TestJava {
    public static void main(String[] args) {
        String str = "20232,20221,20222,20223,20224,20225,20226,20227,20228,20229,202210,202211,202212,20231";
        
        // 分割字符串并分组处理
        Map<String, String> yearMonthMap = str.split(",")
                .map(item -> {
                    String year = item.substring(0, 4);
                    Integer month = Integer.parseInt(item.substring(4));
                    return Map.entry(year, month);
                })
                .collect(Collectors.groupingBy(
                        Map.Entry::getKey,
                        Collectors.collectingAndThen(
                                Collectors.toCollection(TreeSet::new),
                                set -> String.join(",", set.stream().map(String::valueOf).toArray(String[]::new))
                        )
                });
        
        // 输出结果
        yearMonthMap.forEach((key, value) -> System.out.println("[Key] : " + key + " [Value] : " + value));
    }
}

方案二:传统循环方式(兼容性好)

使用泛型Map结合TreeSet实现去重和排序:

import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

public class TestJava {
    public static void main(String[] args) {
        String str = "20232,20221,20222,20223,20224,20225,20226,20227,20228,20229,202210,202211,202212,20231";
        String[] lst = str.split(",");
        
        // 用TreeSet存储月份,自动去重并升序
        Map<String, Set<Integer>> yearMonthMap = new HashMap<>();
        
        for (String item : lst) {
            String year = item.substring(0, 4);
            Integer month = Integer.parseInt(item.substring(4));
            
            // 若年份不存在则创建新的TreeSet,否则直接添加月份
            yearMonthMap.computeIfAbsent(year, k -> new TreeSet<>()).add(month);
        }
        
        // 转换为逗号分隔的字符串并输出
        yearMonthMap.forEach((key, value) -> {
            String monthStr = String.join(",", value.stream().map(String::valueOf).toArray(String[]::new));
            System.out.println("[Key] : " + key + " [Value] : " + monthStr);
        });
    }
}

正确输出结果

[Key] : 2022 [Value] : 1,2,3,4,5,6,7,8,9,10,11,12
[Key] : 2023 [Value] : 1,2

内容的提问来源于stack exchange,提问作者user1015388

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 19:09:57