首页 > 编程语言 > 详细

Java用自定义的类型作为HashMap的key

时间:2017-05-30 20:28:21      阅读:271      评论:0      收藏:0      [点我收藏+]

??需要重写hashCode()和equals()方法才可以实现自定义键在HashMap中的查找。

public class PhoneNumber
{
    private int prefix; //区号
    private int phoneNumber; //电话号

    public PhoneNumber(int prefix, int phoneNumber)
    {
        this.prefix = prefix;
        this.phoneNumber = phoneNumber;
    }
}
import java.util.HashMap;

public class Test1
{
    public static void main(String[] args)
    {
        HashMap<PhoneNumber, String> map = new HashMap<>();

        map.put(new PhoneNumber(027, 12345678), "zhangsan");
        map.put(new PhoneNumber(027, 22222222), "lisi");
        map.put(new PhoneNumber(027, 33333333), "wangwu");
        map.put(new PhoneNumber(027, 33333333), "abc");

        System.out.println(map.toString());

        System.out.println(map.get(new PhoneNumber(027, 12345678)));
        System.out.println(map.get(new PhoneNumber(027, 22222222)));
        System.out.println(map.get(new PhoneNumber(027, 33333333)));
    }
}

运行结果为:

{package1.PhoneNumber@74a14482=zhangsanpackage1.PhoneNumber@677327b6=wangwupackage1.PhoneNumber@1540e19d=lisipackage1.PhoneNumber@14ae5a5=abc}
null
null
null

从中我们可以看到出现了两个问题:

  • new PhoneNumber(027, 33333333)这个键被添加了两次,但是在HashMap中wangwu和abc同时存在了
  • 使用get方法取得的值均为null

正确的方法就是直接对PhoneNumber类进行修改,覆盖equals和hashCode方法,修改后的PhoneNumber类如下:

public class PhoneNumber
{
    private int prefix; //区号
    private int phoneNumber; //电话号

    public PhoneNumber(int prefix, int phoneNumber)
    {
        this.prefix = prefix;
        this.phoneNumber = phoneNumber;
    }

    @Override
    public boolean equals(Object o)
    {
        if(this == o)
        {
            return true;
        }
        if(!(o instanceof PhoneNumber))
        {
            return false;
        }
        PhoneNumber pn = (PhoneNumber)o;
        return pn.prefix == prefix && pn.phoneNumber == phoneNumber;
    }

    @Override
    public int hashCode()
    {
        int result = 17;
        result = 31 * result + prefix;
        result = 31 * result + phoneNumber;
        return result;
    }
}

重新执行上述函数,结果为:

{package1.PhoneNumber@1fce2ef=abcpackage1.PhoneNumber@bca3e8=zhangsanpackage1.PhoneNumber@1535828=lisi}
zhangsan
lisi
abc

可以看到,之前出的错误都被改正了

在HashMap中,查找key的比较顺序为:

  1. 计算对象的HashCode,看在表中是否存在
  2. 检查HashCode位置中的对象是否与当前对象相等

以上使用计算HashCode的方法在effective java第九点中提到:

    • 对于对象中每个关键域f,为该域计算int类型的散列码c,result = 31 * result + c

Java用自定义的类型作为HashMap的key

原文:http://www.cnblogs.com/yangmingyu/p/6921246.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!