当前位置:  开发笔记 > 编程语言 > 正文

Java HashMap包含奇怪的行为

如何解决《JavaHashMap包含奇怪的行为》经验,为你挑选了1个好方法。

试图实现简单的任务陷入奇怪的问题:

class User{
    String login;
    String pwrd;
    User(String lg,String pw){
        this.login=lg;
        this.pwrd=pw;
    }
    public String toString(){
        return this.login;
    }
    public boolean equals(String a){
        return this.login.equals(a);
    }
    public boolean equals(User t){
        return this.login.equals(t.toString());
    }
}

public class Foo{
    public static void main (String[] args)
    {
        HashMap a=new HashMap<>();
        User a1=new User("asd","123"),a2=new User("asd","134");
        a.put(a1,false);
        a.put(a2,false);
        System.out.println(a.containsKey(a2));
        System.out.println(a.containsKey("asd"));
    }
}

结果我希望两个containsKey检查都是真的.进一步在代码中它将被越来越多地使用.所以首先要理解为什么它表现如此,如果可能的话修复它.任何帮助赞赏.



1> Eran..:

Map的键是User实例,所以a.containsKey("asd")永远不会返回true,因为"asd"是一个String.

顺便说一下,你没有覆盖Object's equals,它需要一个Object参数.这意味着a.containsKey(a2)也返回false,因为a1==a2是假的.

正确的实施equals将是:

@Override
public boolean equals(Object other){
    if (!(other instanceof User))
        return false;
    User u = (User) other;
    return this.login.equals(u.login);
}

正如Andy所提到的,你也必须覆盖hashCode,所以如果a.equals(b)是真的那么a.hashCode()==b.hashCode().

编辑:

我认为a.containsKey("asd")如果你equals以一种将String实例视为与你的User实例相等的方式覆盖(如果它们与login属性匹配),则可以返回true :

@Override
public boolean equals(Object other){
    if (other instanceof User) {
        User u = (User) other;
        return this.login.equals(u.login);
    } else if (other instanceof String) {
        String u = (String) other;
        return this.login.equals(u);
    }
    return false;
}

@Override
public int hashCode()
{
    return login.hashCode();
}

我从未尝试过这样的实现equals,但根据我的理解HashMap,它可能会起作用.

但是,这样的实现equals会违反equalsJavadoc中定义的合同Object,因为"asd".equals(a1)即使a1.equals("asd")是真的也会返回false .

编辑:

检查执行后HashMap,我发现这个实现equals不起作用,因为代码containsKey(key)将密钥与现有条目的密钥进行比较而不是相反的方式,String.equals(obj)如果obj不是a ,则总是返回false String.我想有一个很好的理由不打破合同equals.


我还要补充说,只要覆盖`equals`,就应该覆盖`hashCode`.
推荐阅读
LEEstarmmmmm
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有