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

使用Stream处理CSV生成双Map时第二个Map为空的问题求助

问题分析与解决方案:Stream被消费导致secondMap为空

嘿,你的问题根源其实很典型——同一个InputStream只能被读取一次!

你创建的streamSupplier每次调用get(),都是基于同一个somefile InputStream生成新的Stream。但当你第一次用它填充firstMap时,这个InputStream已经被完全读取,指针走到了文件末尾。第二次再调用streamSupplier.get()时,BufferedReader根本读不到任何内容,所以secondMap自然是空的。

下面给你两种可行的解决思路:


方案1:先把所有行加载到内存,再分两次处理

适合文件体积不大的场景,简单直观:

public static void main(String[] args) throws FileNotFoundException { 
    InputStream somefile = new FileInputStream("d:\\dummyfile.csv"); 
    // 先把所有行读取到List中,避免重复消费InputStream
    List<String> lines = new BufferedReader(new InputStreamReader(somefile, StandardCharsets.ISO_8859_1))
            .lines()
            .collect(Collectors.toList());

    // 构建firstMap:将所有g[2]的值用逗号拼接,对应newVal1
    Map<String, String> firstMap = lines.stream()
        .map(p -> p.split("\t"))
        // 注意:如果CSV中s[1]并非统一为"newVal1",请替换成固定key"newVal1"
        .collect(Collectors.groupingBy(s -> "newVal1", Collectors.mapping(g -> g[2], Collectors.joining(",")))); 

    // 构建secondMap:s[0]作为key,s[2]作为value
    Map<String, String> secondMap = lines.stream()
        .map(p -> p.split("\t"))
        .collect(Collectors.toMap(s -> s[0], s -> s[2])); 

    // 合并两个Map
    firstMap.putAll(secondMap);
}

方案2:一次遍历同时构建结果Map(更高效)

如果你的CSV文件很大,不想占用太多内存,可以只读取一次文件,直接构建最终需要的Map:

public static void main(String[] args) throws FileNotFoundException { 
    InputStream somefile = new FileInputStream("d:\\dummyfile.csv"); 
    Map<String, String> resultMap = new HashMap<>(); 
    StringBuilder aggregatedValues = new StringBuilder();

    new BufferedReader(new InputStreamReader(somefile, StandardCharsets.ISO_8859_1))
            .lines()
            .map(p -> p.split("\t"))
            // 加个过滤避免数组越界:行的列数不足3则跳过
            .filter(arr -> arr.length >= 3)
            .forEach(arr -> {
                // 填充oldVal系列的键值对
                resultMap.put(arr[0], arr[2]);
                // 收集所有s[2]的值,用于拼接newVal1的value
                if (aggregatedValues.length() > 0) {
                    aggregatedValues.append(",");
                }
                aggregatedValues.append(arr[2]);
            });

    // 添加newVal1的键值对
    resultMap.put("newVal1", aggregatedValues.toString());
}

额外注意点:

  • 你原代码中的groupingBy(s -> s[1]),如果CSV里s[1]不是统一的newVal1,需要调整成固定key,否则会生成多个分组,和你的期望输出不符。
  • 调用split("\t")时,如果某一行的列数不足3,会抛出ArrayIndexOutOfBoundsException,建议像方案2那样加个filter做判断。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 07:07:49