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

HashMap过滤时输出不符合预期的问题排查

为什么传入多个参数时HashMap过滤结果会丢失部分条目?

我现在有个需求:用命令行传入多个源系统名称(比如SSN1、SSN2),从一个HashMap里过滤出包含这些名称的键值对,并且每个匹配的源系统都要单独输出对应的表项。

我的HashMap结构是键为源表名,值的格式是"目标表名:ssn1,ssn2,...",比如("Table1", "Table1:SSN1,SSN2,SSN3,SSN4,SSN5")。

我写了这段Java代码:

import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

public class FilterKeyValues { 
    public static void main(String[] args) { 
        String[] valArr; 
        String ky; 
        Map<String, String> hmap = new HashMap<String, String>(); 
        Map<String, String> filtered = new HashMap<String, String>(); 
        
        hmap.put("Table1", "Table1:SSN1,SSN2,SSN3,SSN4,SSN5"); 
        hmap.put("Table2", "Table2:SSN1,SSN4,SSN2,SSN5,SSN8,SSN9,SSN10"); 
        hmap.put("Table3", "Table3:SSN4,SSN1"); 
        hmap.put("Table4", "Table4:SSN5,SSN6,SSN7"); 
        hmap.put("Table5", "Table5:SSN8,SSN1,SSN5,SSN2"); 
        
        if(args.length > 0) { 
            for(String ssname: args) { 
                for (Entry<String, String> entry : hmap.entrySet()) { 
                    if (entry.getValue().contains(ssname)) { 
                        ky = entry.getKey(); 
                        valArr = entry.getValue().split(":"); 
                        filtered.put(ky, valArr[0]+":"+ssname); 
                    } 
                } 
            } 
        } 
        
        for (String iter: filtered.keySet()){ 
            String key = iter.toString(); 
            String value = filtered.get(key).toString(); 
            System.out.println(key + "->" + value); 
        } 
    } 
}

当我传入参数SSN1 SSN2时,预期输出是:

Table1->Table1:SSN1
Table2->Table2:SSN1
Table3->Table3:SSN1
Table5->Table5:SSN1
Table1->Table1:SSN2
Table2->Table2:SSN2
Table5->Table5:SSN2

但实际得到的输出却是:

Table2->Table2:SSN2
Table3->Table3:SSN1
Table5->Table5:SSN2
Table1->Table1:SSN2

我实在找不到问题出在哪,有人能帮我看看吗?


问题根源:HashMap的键唯一性导致覆盖

你的问题出在**filtered这个HashMap的特性上**——HashMap的键是唯一的,当你多次对同一个键调用put()方法时,新的值会直接覆盖旧的值。

举个具体的执行流程:

  1. 循环第一个参数SSN1时,你会把Table1->Table1:SSN1放入filtered;
  2. 接着循环第二个参数SSN2时,发现Table1也包含SSN2,于是再次执行filtered.put("Table1", "Table1:SSN2"),这就把之前存储的Table1:SSN1给覆盖掉了。

同理,Table2和Table5也会被最后一次匹配的SSN2覆盖,只有Table3因为只匹配SSN1,所以保留了下来。这就是为什么你看不到所有预期的条目。

解决方案:改用合适的数据结构存储结果

要实现你的预期输出,你需要一个能为同一个表名存储多个匹配结果的结构,这里提供两种常用方案:

方案1:用List存储所有匹配的条目(最简单直接)

把filtered从Map<String, String>改成List<String>,每次匹配成功就把key->value的字符串直接加入列表:

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

public class FilterKeyValues { 
    public static void main(String[] args) { 
        String[] valArr; 
        Map<String, String> hmap = new HashMap<String, String>(); 
        List<String> filtered = new ArrayList<>(); // 替换为List
        
        hmap.put("Table1", "Table1:SSN1,SSN2,SSN3,SSN4,SSN5"); 
        hmap.put("Table2", "Table2:SSN1,SSN4,SSN2,SSN5,SSN8,SSN9,SSN10"); 
        hmap.put("Table3", "Table3:SSN4,SSN1"); 
        hmap.put("Table4", "Table4:SSN5,SSN6,SSN7"); 
        hmap.put("Table5", "Table5:SSN8,SSN1,SSN5,SSN2"); 
        
        if(args.length > 0) { 
            for(String ssname: args) { 
                for (Entry<String, String> entry : hmap.entrySet()) { 
                    if (entry.getValue().contains(ssname)) { 
                        valArr = entry.getValue().split(":"); 
                        filtered.add(entry.getKey() + "->" + valArr[0] + ":" + ssname); 
                    } 
                } 
            } 
        } 
        
        // 直接遍历List输出所有结果
        for (String result : filtered) {
            System.out.println(result);
        } 
    } 
}

方案2:用Map<String, List>分组存储(更灵活)

如果你需要后续对每个表的匹配结果做进一步处理,可以用Map<String, List<String>>,键是表名,值是该表匹配的所有SSN列表:

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.ArrayList;

public class FilterKeyValues { 
    public static void main(String[] args) { 
        String[] valArr; 
        Map<String, String> hmap = new HashMap<String, String>(); 
        Map<String, List<String>> filtered = new HashMap<>(); // 分组存储结构
        
        hmap.put("Table1", "Table1:SSN1,SSN2,SSN3,SSN4,SSN5"); 
        hmap.put("Table2", "Table2:SSN1,SSN4,SSN2,SSN5,SSN8,SSN9,SSN10"); 
        hmap.put("Table3", "Table3:SSN4,SSN1"); 
        hmap.put("Table4", "Table4:SSN5,SSN6,SSN7"); 
        hmap.put("Table5", "Table5:SSN8,SSN1,SSN5,SSN2"); 
        
        if(args.length > 0) { 
            for(String ssname: args) { 
                for (Entry<String, String> entry : hmap.entrySet()) { 
                    if (entry.getValue().contains(ssname)) { 
                        String tableName = entry.getKey();
                        // 如果表名不在Map里,先初始化一个空列表
                        filtered.computeIfAbsent(tableName, k -> new ArrayList<>());
                        filtered.get(tableName).add(ssname);
                    } 
                } 
            } 
        } 
        
        // 遍历输出,每个表的每个SSN单独一行
        for (Entry<String, List<String>> entry : filtered.entrySet()) {
            String table = entry.getKey();
            for (String ssn : entry.getValue()) {
                System.out.println(table + "->" + table + ":" + ssn);
            }
        } 
    } 
}

这两种方案都能得到你预期的输出结果,你可以根据自己的后续需求选择合适的方式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:45:21