使用HashMap意外输出

时间:2011-03-16 09:52:28

标签: java collections

CODE:

public class Puzzle23{
    void Puzzle23(){
        map1.put(String1, "1");
        map1.put(String2, "2");
    }

    private final NewMap map1 = new NewMap();
    private static final String String1 = new String("J2eeSig");
    private static final String String2 = new String("J2eeSig");

    public static void main(final String args[]){
        final Puzzle23 p22 = new Puzzle23();
        final Map<String, String> map2 = new HashMap();

        map2.put(String1, "1");
        map2.put(String2, "2");
        System.out.println(p22.map1.size() == map2.size() ? true : false);
        p22.map1.remove(new String(String1));
        map2.remove(new String(String2));
        System.out.println(p22.map1.size() == map2.size() ? true : false);
    }

    class NewMap extends IdentityHashMap<String, String>{
        public void put(final String... values){
            super.put(values[0], values[1]);
        }

        public int size(){
            return super.size() + 1 - 1 / 1 * 1;
        }
    }
}

实际结果: -

false
true

预期结果: -

true
true

为什么???

3 个答案:

答案 0 :(得分:6)

这是因为使用NewMapIdentityHashMap。检查文档在哪里

  

这个类不是通用的Map实现!虽然这个类实现了Map接口,但它故意违反了Map的一般契约,它要求在比较对象时使用equals方法。此类仅用于需要引用相等语义的罕见情况。

修改 无论如何,我在你的代码中发现了一个错误。 void Puzzle23()不是构造函数,它是一种方法。必须定义构造函数而不返回值(例如Puzzle23())。所以你永远不会填map1。解决此问题后,由于false,您会发现输出为false IdentityHashMap。当您将map1切换为HashMap时,输出将为true true,如您所料。无论如何检查IdentityHashMap的文档。

答案 1 :(得分:2)

p22.map1.remove(new String(String1));不会删除任何内容,因为NewMapIdentityHashMap的子类。

更新

我错了

1)这里的第一个错误是伪装成构造函数的void方法。这就是为什么p22.map1总是空的。

2)第二个是NewMapIdentityHashMap。在向其添加2个字符串后,其大小变为2,因为虽然此字符串相等但它们不相同(==)。

3)p22.map1.remove(new String(String1));不会像我先前所说的那样做任何事情。

答案 2 :(得分:2)

IdentityHashMap使用==,其中普通HashMap使用.equals()。请参阅documentation