【问题标题】:How is it possible to get duplicate keys in map如何在地图中获取重复的键
【发布时间】:2019-08-07 14:13:08
【问题描述】:

有时我的 java/groovy 应用程序的行为很奇怪:有一个不为空且其中包含值的映射,但是当我尝试通过我在记录该映射时看到的完全相同的键获取值时为空。最奇怪的是log中的map有重复的key。

重新启动应用程序可以解决问题,但我感兴趣的是这怎么可能。

我有这个代码:

def mainField = typeSettings?.mainField != null 
    ? typeSettings?.mainField 
    : classSettings.mainField
logger.info("${typeSettings}\n ${classSettings}\n ${classSettings.mainField}")

我确定classSettings 不是null

这是我在日志中看到的:

null
[
    iconsField:[], 
    mainField:[
        [
            code:portalCard, showTitle:false, pages:[card]
        ], 
        [
            code:portalAddForm, showTitle:false, pages:[addForm]
        ]
    ], 
    footer:[showNegotDate:true, showPlanDate:true], 
    footer:[showNegotDate:true, showPlanDate:true]
]
null

但很明显,mainField 存在于映射中,更重要的是,该映射中有两个重复的键 footer

【问题讨论】:

    标签: java groovy jvm


    【解决方案1】:

    例如GStrings 可以做到这一点(它们打印相同,但散列不同):

    groovy:000> [footer: 1, ("${"footer"}"): 2]
    ===> [footer:1, footer:2]
    

    如果你想调试类似的东西,通常最好使用.inspect() 而不是.toString()(在任何情况下都可能没有帮助,但它实际上提供了一个线索):

    groovy:000> [footer: 1, ("${"footer"}"): 2].inspect()
    ===> ['footer':1, footer:2]
    

    最后,你必须看类型或哈希码:

    groovy:000> [footer: 1, ("${"footer"}"): 2].keySet()*.getClass()
    ===> [class java.lang.String, class org.codehaus.groovy.runtime.GStringImpl]
    groovy:000> [footer: 1, ("${"footer"}"): 2].keySet()*.hashCode()
    ===> [-1268861541, -1268861504]
    

    【讨论】:

    • 感谢您的回答,但不幸的是,事实并非如此。我很确定这两个键都是简单的字符串。
    • “相当确定”不是“确定”;)。也许某些东西在打印时修改了地图?是共享的吗?
    • 我什至打电话给classSettings.keySet()*.hashCode(),我看到了相同的哈希码
    • 似乎问题在于此处提到的该地图的并发修改:stackoverflow.com/questions/46902323/…
    【解决方案2】:

    似乎问题在于此处提到的该地图的并发修改:What happens when two threads try to modify/access the same key in HashMap?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-04-18
      • 2013-05-20
      • 1970-01-01
      • 2014-07-29
      • 1970-01-01
      • 2016-04-04
      • 2014-03-13
      • 1970-01-01
      相关资源
      最近更新 更多