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
相关产品推荐
相关产品推荐

