如何处理HashMap中的重复键?CSV重复键值求和实现方案
解决HashMap处理CSV重复键并求和的问题
嘿,这个需求很典型,我来帮你调整代码实现!
你当前的代码直接将字符串值存入HashMap,遇到重复键时旧值会被新值覆盖,根本没法完成求和。核心的解决思路是把HashMap的Value类型换成数值类型(比如Double),每次处理行时判断键是否已存在,存在则累加数值,不存在则初始化存入。
具体修改步骤:
- 调整HashMap类型:将存储字符串的Map改为存储键为String、值为Double的Map,这样才能进行数值计算。
- 处理数值解析:你的CSV里用逗号作为小数点分隔符,需要先替换为点号,否则
Double.parseDouble会抛出异常。 - 判断并累加数值:每次读取行后,检查键是否在Map中:
- 存在则取出当前总和,加上新解析的数值,再存回Map
- 不存在则直接将新数值存入Map
- 格式化输出结果:遍历Map,按照你需要的格式输出键和对应的总和。
修改后的完整代码:
import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.util.HashMap; import java.util.Map; public class CsvSumProcessor { public static void main(String[] args) { String filepath = "你的CSV文件路径"; String cvsSplitBy = ";"; // 调整HashMap类型为<String, Double>,用于存储键和对应的总和 Map<String, Double> alldataMap = new HashMap<>(); BufferedReader br = null; String line; try { br = new BufferedReader(new FileReader(filepath)); while ((line = br.readLine()) != null) { String[] splitter = line.split(cvsSplitBy); // 跳过表头(假设"Voertuig"是表头行的第一个字段) if (!"Voertuig".equals(splitter[0])) { String key = splitter[0].trim(); // 去除键的多余空格 // 处理数值:替换逗号为点号,去除空格后解析为Double String valueStr = splitter[8].trim().replace(",", "."); try { double value = Double.parseDouble(valueStr); // 判断键是否存在,存在则累加,不存在则初始化 if (alldataMap.containsKey(key)) { alldataMap.put(key, alldataMap.get(key) + value); } else { alldataMap.put(key, value); } } catch (NumberFormatException e) { // 处理数值解析失败的情况,比如跳过无效行或打印日志 System.out.println("无效的数值格式:" + valueStr + ",跳过该行"); } } } // 按照期望格式输出结果 System.out.println("处理后的结果:"); for (Map.Entry<String, Double> entry : alldataMap.entrySet()) { System.out.println(entry.getKey() + "; " + entry.getValue()); } // 调用你的TextOutput方法(如果需要) // TextOutput(); } catch (FileNotFoundException fnfex) { System.out.println(fnfex.getMessage() + " Bestand niet gevonden!"); System.exit(0); } catch (IOException ioex) { System.out.println(ioex.getMessage() + " Error 1"); } finally { // 别忘了关闭BufferedReader,避免资源泄漏 try { if (br != null) br.close(); } catch (IOException e) { e.printStackTrace(); } System.exit(0); } } }
针对你给出的CSV示例:
输入CSV:
Apples; 299,9 Bananas; 300,23 Apples; 3912,1 Bananas;342 Bananas;343
处理后输出:
Apples; 4212.0 Bananas; 985.23
额外提示:
- 我在代码里加了
trim()处理键和值,避免CSV里的空格导致键不匹配(比如"Apples"和" Apples"会被当成不同的键) - 增加了
NumberFormatException的捕获,防止遇到无效数值时程序崩溃 - 最后在finally块里关闭了BufferedReader,避免资源泄漏
内容的提问来源于stack exchange,提问作者wutBruh
相关产品推荐
相关产品推荐

