温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Map的key、value值的数据类型不能为基本类型的原因有哪些

发布时间:2020-11-02 16:31:31 来源:亿速云 阅读:246 作者:Leah 栏目:开发技术

这篇文章将为大家详细讲解有关Map的key、value值的数据类型不能为基本类型的原因有哪些,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。

interface Map<K,V>

Map源码

  /**
     * Returns the hash code value for this map entry. The hash code
     * of a map entry <tt>e</tt> is defined to be: <pre>
     *   (e.getKey()==null  &#63; 0 : e.getKey().hashCode()) ^
     *   (e.getValue()==null &#63; 0 : e.getValue().hashCode())
     * </pre>
     * This ensures that <tt>e1.equals(e2)</tt> implies that
     * <tt>e1.hashCode()==e2.hashCode()</tt> for any two Entries
     * <tt>e1</tt> and <tt>e2</tt>, as required by the general
     * contract of <tt>Object.hashCode</tt>.
     *
     * @return the hash code value for this map entry
     * @see Object#hashCode()
     * @see Object#equals(Object)
     * @see #equals(Object)
  */
    int hashCode();

hashCode返回 (e.getKey()==null &#63; 0 : e.getKey().hashCode()) ^(e.getValue()==null &#63; 0 : e.getValue().hashCode())

class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable

HashMap源码中:

public final int hashCode() {
 return Objects.hashCode(key) ^ Objects.hashCode(value);
}
static final int hash(Object key) {
 int h;
 return (key == null) &#63; 0 : (h = key.hashCode()) ^ (h >>> 16);
}
public final boolean equals(Object o) {
 if (o == this)
    return true;
  if (o instanceof Map.Entry) {
    Map.Entry<&#63;,&#63;> e = (Map.Entry<&#63;,&#63;>)o;
  if (Objects.equals(key, e.getKey()) &&
    Objects.equals(value, e.getValue()))
    return true;
  }
  return false;
}

补充知识:java hashmap key long 和int 区别

最近同事问起,map里面存的key 是int 类型的,存了一个 Integera =123,为什么使用long 123 作为key get,取出来的是空,这个问题粗想了一下,感觉long和int 本身 类型不同,肯定不能是同一个key,后来细研究了一下,跟了一下源码,发现逻辑不是那么简单。

简单测试了一下,如下代码

Map<Object,String> map = new HashMap<>();
Integer b = 123;
Long c =123L;
map.put(b, b+"int");
System.out.println(b.hashCode() == c.hashCode()); //true
System.out.println(map.get(c));  //null
map.put(c, c+"long"); // size =2

简单的总结了一下问题:

1、HashMap 是把key做hash 然后作为数组下标,但是 b 和c 的hashcode 竟然是相同的,为什么 get(c) 为空

2、HashMap 存入c 发现 size=2 ,hashcode相同 为什么 size=2,get(c) =123long

带着上面两个问题跟了一遍源码,问题豁然开朗

1、hashmap在存入的时候,先对key 做一遍 hash,以hash值作为数组下标,如果发现 下标已有值,判断 存的key 跟传入的key是不是相同,使用 (k = p.key) == key || (key != null && key.equals(k)) ,如果相同覆盖,而Interger的equals 方法如下:

if (obj instanceof Integer) {
      return value == ((Integer)obj).intValue();
    }

return false;

Integer 和 Long 肯定不是一个类型,返回 false,这时候 hashmap 以 hashkey 冲突来处理,存入链表,所以 Long 123 和 Integer 123 hashmap会认为是 hash冲突

2、hashmap 在 get的时候,也是先做 hash处理,根据hash值查找对应的数组下标,如果找到,使用存入时候的判断条件

(k = first.key) == key || (key != null && key.equals(k)) 如果相等就返回,不相等,查找当前值的next有没有值,有继续根据逻辑判断,所以 存入Integer 123 根据 Long 123 来获取返回的 是 NULL

至此,解析完毕。

关于Map的key、value值的数据类型不能为基本类型的原因有哪些就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI