【问题标题】:HashMap<Object, Boolean> toString problemHashMap<Object, Boolean> toString 问题
【发布时间】:2025-12-30 23:20:37
【问题描述】:

我有一个 HashMap 类型的地图。

我正在尝试遍历地图,并且对于布尔标志设置为 true 的每个条目,我正在尝试打印相应的键值。

我能够做到这一点。但是,它不是打印字符串“键”值,而是打印字符串对象。我尝试使用 .toString() 函数进行转换。什么都没有解决它。

任何帮助将不胜感激。

谢谢,S。

【问题讨论】:

  • “打印字符串对象而不是字符串键值”的问题描述没有任何意义。请详细说明。

标签: java hashmap tostring


【解决方案1】:

你想遍历 Map 的 entrySet:

Set< Map.Entry<String, Boolean> > es = map.entrySet();

这是一个集合,因此您可以对其进行迭代:

for( Map.Entry<String, Boolean> v : es ) {
   if( v.getValue() ) { // auto-unboxing
       System.out.println(v.getKey());
   }
}

简化:

for( Map.Entry<String, Boolean> v : map.entrySet() ) {
   if( v.getValue() ) {
       System.out.println(v.getKey());
   }
}

【讨论】:

  • 是的,这是比使用 get() 和键集更有效的方法。这是我在 IE 崩溃时输入的答案。
  • 你应该停止使用 IE @ArtB
  • 我确实尝试了类似于您建议的方法。但我仍然打印字符串对象而不是字符串。您可以向下滚动并查看我的评论以了解我所说的 String 对象的含义。
【解决方案2】:

您的跟进表明您的 Map 中的值不是 String 类型,也不是已覆盖 toString 的类型,这就是为什么当您调用 toString 时,您会得到类似“com.f5.lunaui.emproto”的值.reports.Device_Sri@334003"。

在 Device_Sri 中,你应该重写 toString 方法以返回你想要的字符串:

@Override
public String toString() {
    return "em_device90-36";
}

当然,您可能希望从 Device_Sri 类的字段中计算值“em_device90-36”。

【讨论】:

    【解决方案3】:

    你可能想要这样的东西:

    for(String key : map.keySet()){
      if(map.get(key)){
        System.out.println(key);
      }
    }
    

    【讨论】:

    • 这没用。你是说:“对于地图中的每个键 k,如果 map.get(that key k),打印那个 key k”。因此,您将打印每个键,无论其(在本例中为布尔值)值如何。此外,`if(map.get(key)){` 在 Java 中是非法的;与 C/C++ 不同,您与 null 的比较必须明确:if(map.get(key) != null ){。但更进一步,如果键不存在或键的值为空(对于允许空键的映射),map.get 将返回 null。
    • @tpdi 我没有与 null 进行比较......地图中的值是布尔类型。 Java 会为我自动拆箱,因此唯一会打印的值是与键关联的值为 True 时。我不必担心密钥不存在,因为我明确地只迭代密钥(好吧,除非发生了一些奇怪的并发事情)。当 Java 尝试拆箱时,出现空点异常的风险很小,但只有当存在从键到空的显式映射时才会发生这种情况。
    • @tpdi 您从自己的回答中清楚地了解到 Java 会自动拆箱,那么您为什么认为它在这里行不通呢?我没有显示 map 的声明,但显然它是 HashMap&lt;String, Boolean&gt; 类型,因为 OP 在问题中明确提到了这一点。显然,如果值不是Boolean 类型,我的解决方案将不起作用,但很明显它们是......
    【解决方案4】:

    这应该可行:

    Map<String, Boolean> myMap = new HashMap<String, Boolean>();
    myMap.put("one", true);
    myMap.put("second", false);
    
    for (String key : myMap.keySet()) {
      if (myMap.get(key)) {
        System.out.println(key + " --> " + myMap.get(key));
      }
    }
    

    【讨论】:

    • OP 说他只有在值为真时才对打印感兴趣。
    • 由于同时使用key和value,最好使用EntrySet for( Entry&lt;String, Boolean&gt; entry : myMap.entrySet() )
    • @wolf '更好' 值得商榷。您将获得边际性能提升(避免重新散列,但根据定义,这应该是一个快速操作)但代码在@CarlosZ 的版本中更具可读性,我认为可读性的提高优于边际速度的提高。 :-)
    【解决方案5】:

    要添加到其他答案,如果值为空,您将获得空指针异常。

    if (e.getValue()) { ... }
    

    这是因为该值为Boolean,将被拆箱为boolean。相当于e.getValue().booleanValue()

    如果你想防止值为空,那么使用

    if (Boolean.TRUE.equals(e.getValue()) { ... }
    

    【讨论】:

      【解决方案6】:
      private Map<String, Boolean> deviceChecked = new HashMap<String, Boolean>();
      deviceChecked = checkMap;
      
      Set entry = deviceChecked.entrySet();
          Iterator i = entry.iterator();
      while(i.hasNext()){
          Map.Entry ent = (Map.Entry)i.next();
          if(ent.getValue()){
              result = result + (String)ent.getKey() + ", ";
          }
      }
      System.out.println("result is " +result);
      return result;
      

      我只在对应的布尔值为真时才尝试打印密钥。类似于上面的代码。在这种情况下,结果值不包含字符串,它会打印对象。 我应该将值打印为“em-device90-36”。但是,相反,我得到了这个打印

      com.f5.lunaui.emproto.reports.Device_Sri@334003

      【讨论】:

      • 嗨,欢迎来到 *。您可以(并且应该)在需要时编辑您的原始问题,而不是在答案中发布您的代码。 :-)
      • @Azure,感谢您指出这一点。以后我会尽量遵循这个提示。
      • 您的演员 (String)ent.getKey() 应该会失败,如果 Map 的键不是字符串,则抛出 ClasscastException。但是,这一行(没有强制转换)不会抛出:result = result + ent.getKey() + ", "; 那是因为 String operator+ 被重载,并在其第二个操作数上调用 toString,就好像你写了这个 `result = result + ent.getKey().toString + ", ";这是安全的,因为所有对象都有一个 toString,并且因为 String operator+ 也有所有原始类型的重载,它们将它们转换为字符串。你得到的结果看起来像 Object.toString 被调用(更多)
      • (续)这表明了两件事:您的实际代码没有显式转换,并且您的地图键不是真正的字符串。简单的解决方法是找到实际键的类型,并覆盖其 toString() 方法以返回您认为该类应该返回的任何字符串表示形式。此外,您的行 private Map deviceChecked = new HashMap(); deviceChecked = checkMap; 创建并 thgen 丢弃新的 HashMap;你只需要这里的参考(deviceChecked)。