您的位置:首页 > 编程语言 > Java开发

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

2017-01-10 23:48 323 查看
  需要重写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=zhangsan, package1.PhoneNumber@677327b6=wangwu, package1.PhoneNumber@1540e19d=lisi, package1.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=abc, package1.PhoneNumber@bca3e8=zhangsan, package1.PhoneNumber@1535828=lisi}

zhangsan

lisi

abc


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

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

计算对象的HashCode,看在表中是否存在

检查HashCode位置中的对象是否与当前对象相等

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

对于对象中每个关键域f,为该域计算int类型的散列码c,result = 31 * result + c
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: