zoukankan      html  css  js  c++  java
  • java Map使用Object 做为Key的问题

    近期在看dnsjava 源码的时候,不经意间发现一个自己没有想过的问题:

    HashMap 如何使用key去查找对应的value的,这个问题很难用语言描述的清楚,那就使用代码来进行说明吧!

    public class test {
        public static void main(String[] args) {
            a aa = new a();
            b bb = new b();
            Map<Object,Object> c = new HashMap<Object,Object>();
            c.put(aa, bb);
            a cc = new a();
            c.get(cc);
    System.out.println(bb); System.out.println(c.get(aa)); System.out.println(c.get(cc)); } }
    class a { } class b { }

    运行结果为:

    test.java.hashmap.b@10b30a7

    test.java.hashmap.b@10b30a7
    null

    为什么使用aa能获取到value 而 cc就不行呢?aa 和 cc是同一个类的实例啊,如果这样的话HashMap还怎么根据对象来查找value呢?为什么以前使用String就可以查找value呢?带着一连串的疑问我们继续来寻找答案

    首先我们来测试下使用String做为Key 看是否真的可以取出对应的value

    public class test {
    
        public static void main(String[] args) {
            Map<Object,Object> c = new HashMap<Object,Object>();
            String aa = new String("abc");
            b bb = new b();
            c.put(aa, bb);
            String cc = new String("abc");
            System.out.println(bb);
            System.out.println(c.get(aa));
            System.out.println(c.get(cc));
        }
    
    }
    class b {
    
    }

    运行结果为:

    test.java.hashmap.b@61de33
    test.java.hashmap.b@61de33
    test.java.hashmap.b@61de33

    使用String的时候运行正常,下面咱们就去看看HashMap的源码来一探究竟,下面是HashMap get方法的源码

        public V get(Object key) {
            if (key == null)
                return getForNullKey();
            int hash = hash(key.hashCode());
            for (Entry<K,V> e = table[indexFor(hash, table.length)];
                 e != null;
                 e = e.next) {
                Object k;
                if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
                    return e.value;
            }
            return null;
        }

    从源码中可以看出,主要根据两个方法来判断Key是否相同:hashCode 和 equals ,这两个方法都是在Object中定义的,具体的作用请看http://blog.csdn.net/fenglibing/article/details/8905007

    根据上面的分析,要想使用自定义的对象作为key 必须要重写从Object中继承过来的hashCode 和 equals。String 中已经对两个方法进行了重新实现,各位可查看String相关源码。

    public class test {
        public static void main(String[] args) {
            a aa = new a();
            b bb = new b();
            Map<Object,Object> c = new HashMap<Object,Object>();
            c.put(aa, bb);
            a cc = new a();
            c.get(cc);
            System.out.println(bb);
            System.out.println(c.get(aa));
            System.out.println(c.get(cc));
        }
    }
    class a {
        public int hashCode() {
            return 1;
        }
        public boolean equals(Object obj) {
            return true;
        }
    }
    class b {
    }

    运行结果为:

    test.java.hashmap.b@14318bb
    test.java.hashmap.b@14318bb
    test.java.hashmap.b@14318bb

  • 相关阅读:
    leetcode笔记--7 Find the Difference
    数据挖掘:概念与技术--笔记1--度量数据的相似性与相异性
    leetcode笔记--6 Add Digits
    leetcode 笔记5 single number
    数据挖掘导论笔记2 数据集的类型
    **leetcode笔记--4 Sum of Two Integers
    vs2015-Cordova开发安卓应用环境搭建
    c#一些常用的方法集合
    c#根据ip获取城市地址
    asp.net mvc 无刷新加载
  • 原文地址:https://www.cnblogs.com/cruze/p/3700126.html
Copyright © 2011-2022 走看看