【问题标题】:Why does this hashmap have the same key twice?为什么这个 hashmap 有两次相同的键?
【发布时间】:2012-09-11 07:54:52
【问题描述】:
// same X, Y value text.
    TextInfo currXY = new TextInfo( text );

    ArrayList<TextPosition> currTextArray = textComposition.get( currXY );
    if( currTextArray != null ){
        currTextArray.add( text ); 
    } else {
        ArrayList<TextPosition> newTextArray = new ArrayList<TextPosition>();
        newTextArray.add( text );
        if( textComposition.containsKey( currXY )){
            System.out.println( "processTextPosition : containsKEy ");
        }
        textComposition.put( currXY , newTextArray );
    }   

HashMap 不能有重复或相同的密钥,对吧?

我从 hashmap 中获取所有条目并将这些条目放入一个新的 hashmap 中。

它像同一个键一样进行。

lineSortingMap = new HashMap< TextInfo, ArrayList<TextPosition> > ();     
    for ( Map.Entry< TextInfo, ArrayList<TextPosition> > entry : textComposition.entrySet() ) {
        TextInfo key = (TextInfo)entry.getKey();
        ArrayList<TextPosition> arrayTextPositions = entry.getValue();
        if( lineSortingMap.containsKey( key ) ){
            System.out.println("WTFcontainsKey : " + " " + key + " " + key.getX() + " " + key.getY() );
        }
        else{
            lineSortingMap.put( key , arrayTextPositions );
        }
    }

结果:

WTFcontainsKey :  analyzeSrc.TextInfo@4c5 75.307 603.85535

WTFcontainsKey :  analyzeSrc.TextInfo@4c5 71.74238 603.85535

WTFcontainsKey :  analyzeSrc.TextInfo@4c4 66.36187 612.82837

...

你能解释一下这里发生了什么吗?

为什么不打印“processTextPosition : containsKey”?

【问题讨论】:

    标签: java hashmap key duplicates


    【解决方案1】:

    可能是因为您的 Key Object 没有正确覆盖 equals() 和 hashCode()。

    查看Object.hashCode() 的文档和Java Tutorial 中的Object as a Superclass 部分

    甚至更好:阅读Effective Java (2nd Ed) by Joshua Bloch

    【讨论】:

    • @JoachimSauer 令人惊奇的是,Sun / Oracle 官方文档中很少强调这一点。 Java 教程的 Maps 部分和 HashMap JavaDocs 都几乎没有提到一致的 equals() / hashCode() 实现的重要性。
    • 我的印象是大部分 API 文档都是从受正式系统影响的视图编写的(“你是什么意思?equals()/hashCode() 的要求是 清楚 记录,如果您不遵循它们,系统就是 FUBAR,这不是很明显吗? >必须确保...")。
    • 感谢您的回答 :) 我确实覆盖了 equals() 和 hashCode()。但我不明白,当第一次调用 containsKey 方法时,它返回 false...接下来我移动该哈希图的条目,但这次 containsKey 方法返回 true
    • @HanbumBak 正如其他人所建议的那样,发布您的 equals() 和 hashCode() 方法的代码,我们可以看到它们有什么问题。
    • 我解决了这个问题。 :) 当我将条目从原始 HashMap 移动到 lineSortingMap 时,我使用条目对象。像这样: TextInfo key = entry.getKey(); containsKey 使用getEntry 方法,该方法使用对象的equals 方法。 TextInfo 是我的自定义类,但调用 String 类的 equals 方法。那是问题。我不明白为什么,但我会解决它。谢谢你:D
    【解决方案2】:

    没有看到完整的代码很难知道,但我有理由确定您的TextInfo 类没有正确实现equals()hashCode()。实现这两种方法是作为HashMap 中的键有用的先决条件。

    【讨论】:

    • 感谢您的回答 :) 我确实覆盖了 equals() 和 hashCode()。但我不明白,当第一次调用 containsKey 方法时,它返回 false...接下来我移动该哈希图的条目,但这次 containsKey 方法返回 true...
    • @HanbumBak:你是如何实现它的?向我们展示代码,因为这很可能是这个问题的根源。
    【解决方案3】:

    要使用您创建的对象作为 Map 中的键,您应该覆盖 hashCode()equals() 方法。我很确定您的班级TextInfo 没有提供相同的实现。

    【讨论】:

      猜你喜欢
      • 2011-05-26
      • 2012-07-21
      • 1970-01-01
      • 1970-01-01
      • 2023-01-10
      • 1970-01-01
      • 2018-01-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多