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
  • 相关阅读:
    在android 5.0以上,如何判断当前应用是在前台还是后台
    Android实现手机摄像头的自动对焦
    抓包获取百度音乐API
    andriod 自定义来电界面功能
    Android 自定义相机
    解决Android拍照保存在系统相册不显示的问题
    有关Color和Drawable你所不知道的那些内容
    Android主题切换方案总结
    设置background属性使用selector的时候内置?attr报错的解决方案
    一步一步解析google camera2 demo(三)
  • 原文地址:https://www.cnblogs.com/liuyang0/p/6271343.html
Copyright © 2011-2022 走看看