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

为何HashMap<Boolean,String>仅能存储2条数据?如何解决?

为什么你的HashMap<Boolean, String>最多只能存2条数据?解决方案看这里

嘿,这个问题其实很好理解,咱们拆解来看:

问题的核心原因

Boolean类型本质上只有两个可能的取值:true和false。而HashMap的核心规则是key必须唯一——当你用同一个key调用put()方法时,新的value会直接覆盖掉之前存在的value。

看你代码里的逻辑:

if (!metadatas.containsValue(indexable.indexName())) {
    metadatas.put(indexable.dictionary(), indexable.indexName());
}

这里的判断逻辑有漏洞:就算indexName不在map的value里,但只要dictionary(布尔值)这个key已经存在,新的indexName还是会把旧的value覆盖掉。而且containsValue()的效率特别低,因为它要遍历整个map的所有value才能判断,数据量越大越慢。

所以不管你循环多少次,最终map里最多只能有两条数据:一条key是true,一条是false。

两种可行的解决方案

根据你的业务需求,我给你两种常见的处理思路:

1. 更换唯一的Key类型

如果你的indexName是唯一标识,或者你需要用唯一值作为key,那可以把HashMap的key换成String(比如直接用indexName当key),或者自定义一个包含dictionary和indexName的对象作为key(记得重写equals()和hashCode()方法)。

比如改成以indexName为key的版本:

public Map<String, Boolean> findMetadata(String scanPackage) {
    Map<String, Boolean> metadatas = new HashMap<>();
    ClassPathScanningCandidateComponentProvider provider = createComponentScanner();
    for (BeanDefinition beanDef : provider.findCandidateComponents(scanPackage)) {
        try {
            Class<?> cl = Class.forName(beanDef.getBeanClassName());
            Indexable indexable = cl.getAnnotation(Indexable.class);
            logger.info("---------------------------- " + indexable.dictionary() + " " + indexable.indexName());
            // 直接存入,indexName作为唯一key,不会被覆盖(如果indexName可能重复,再加个判断即可)
            metadatas.put(indexable.indexName(), indexable.dictionary());
        } catch (ClassNotFoundException e) {
            logger.error(ERROR + e);
        }
    }
    return metadatas;
}

2. 用Map<Boolean, List>分组存储

如果你的需求是把同一个dictionary(布尔值)对应的所有indexName都保存下来,那应该用布尔值作为key,value用字符串列表。这样同一个布尔key下就能存储多个indexName了。

示例代码:

public Map<Boolean, List<String>> findMetadata(String scanPackage) {
    Map<Boolean, List<String>> metadatas = new HashMap<>();
    ClassPathScanningCandidateComponentProvider provider = createComponentScanner();
    for (BeanDefinition beanDef : provider.findCandidateComponents(scanPackage)) {
        try {
            Class<?> cl = Class.forName(beanDef.getBeanClassName());
            Indexable indexable = cl.getAnnotation(Indexable.class);
            boolean dictionary = indexable.dictionary();
            String indexName = indexable.indexName();
            logger.info("---------------------------- " + dictionary + " " + indexName);
            
            // 先获取对应布尔值的列表,不存在就新建一个
            List<String> indexNames = metadatas.getOrDefault(dictionary, new ArrayList<>());
            // 避免重复添加同一个indexName
            if (!indexNames.contains(indexName)) {
                indexNames.add(indexName);
                metadatas.put(dictionary, indexNames);
            }
        } catch (ClassNotFoundException e) {
            logger.error(ERROR + e);
        }
    }
    return metadatas;
}

如果用Java 8及以上版本,还可以用computeIfAbsent简化这段逻辑:

// 替换上面的列表处理代码
metadatas.computeIfAbsent(dictionary, k -> new ArrayList<>());
List<String> indexNames = metadatas.get(dictionary);
if (!indexNames.contains(indexName)) {
    indexNames.add(indexName);
}

小提示

  • 尽量别用containsValue(),HashMap的value没有索引,每次调用都要遍历整个map,数据量大的时候性能会很差。
  • 选哪种方案取决于你的业务:如果indexName是唯一的,第一种更高效;如果需要按布尔值分组存多个值,第二种更贴合需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:48:55