zoukankan      html  css  js  c++  java
  • Java用自定义的类型作为HashMap的key

      需要重写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的比较顺序为:

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

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

    • 对于对象中每个关键域f,为该域计算int类型的散列码c,result = 31 * result + c
  • 相关阅读:
    多级导航Menu的CSS
    Centos7在线安装PostgreSQL和PostGIS
    PostGis 根据经纬度查询两点之间距离
    在PowerDesigner中表显示中添加Code的显示
    Tomcat部署Geoserver
    PostGIS之路AddGeometryColumn函数添加一个几何类型字段
    怎样把多个excel文件合并成一个
    Error:java: 无效的目标发行版: 11
    PowerDesigner导出Excel
    GeoServer发布高清电子地图
  • 原文地址:https://www.cnblogs.com/liuyang0/p/6271343.html
Copyright © 2011-2022 走看看