hashmap 允许key重复吗_关于Java IdentityHashMap的问题 为什么相同的key 第二次插入进去了?...

首先,说答案:被覆盖了。

为什么被覆盖呢?不废话,直接上IdentityHashMap中的put方法源码:

/**

* Associates the specified value with the specified key in this identity

* hash map. If the map previously contained a mapping for the key, the

* old value is replaced.

*

* @paramkey the key with which the specified value is to be associated

* @paramvalue the value to be associated with the specified key

* @returnthe previous value associated with key, or

* null if there was no mapping for key.

* (A null return can also indicate that the map

* previously associated null with key.)

* @seeObject#equals(Object)

* @see#get(Object)

* @see#containsKey(Object)

*/public V put(K key, V value) {

final Object k = maskNull(key);

retryAfterResize: for (;;) {

final Object[] tab = table;

final int len = tab.length;

int i = hash(k, len);

for (Object item; (item = tab[i]) != null;

i = nextKeyIndex(i, len)) {

if (item == k) {

@SuppressWarnings("unchecked")

V oldValue = (V) tab[i + 1];

tab[i + 1] = value;

return oldValue;

}

}

final int s = size + 1;

// Use optimized form of 3 * s.

// Next capacity is len, 2 * current capacity.

if (s + (s << 1) > len && resize(len))

continue retryAfterResize;

modCount++;

tab[i] = k;

tab[i + 1] = value;

size = s;

return null;

}

}

可以看到,IdentityHashMap其实是一个object数组,他的键和值相邻的放在数组中。在调用put方法时,首先会遍历数组,找到有没有与即将插入的key==的key值,没有,则在i位存入key在i+1位存入value(其中还涉及到扩容的问题,这里不做讨论),并且modCount++(键值对计数)。如果有,则替换当前位置的value。

接下来先来看这样一段有趣的程序

public static void main(String[] args){

String key="144-25-5464";

String key1= new String("144-25-5464");

String key2= "144-25-5464";

String key3 = key1;

System.out.println("key与key1 equals相等?"+key.equals(key1));

System.out.println("key==key1?"+(key==key1));

System.out.println("key==key2?"+(key==key2));

Map stringMap = new IdentityHashMap();

stringMap.put(key,"123"); //添加第一个k,v

stringMap.put(key1,"456"); //添加第二个k,v,此时指向内存地址不一样,key!=key1

System.out.println("put key2前打印");

display(stringMap); //输出stringMap

stringMap.put(key2,"789"); //添加第三个k,v,此时指向内存地址一样,key==key2

System.out.println("put key2后打印");

display(stringMap);

stringMap.put(key3,"101112");

System.out.println("put key3后打印");

display(stringMap);

}

private static void display(Map stringMap){

for (Map.Entry entry:stringMap.entrySet()){

System.out.println(entry.getValue());

}

}

他的输出结果是什么呢?

key与key1 equals相等?true

key==key1?false

key==key2?true

put key2前打印

456

123

put key2后打印

456

789

put key3后打印

101112

789

(mmp,本来想截图的,结果图片上传不清晰)

key,key1,key2的值都是"144-25-5464",为什么key2覆盖了key的值,而key1没有呢?根据上面的输出我们可以知道,key,key1,key2都是equals相等的,而在IdentityHashMap的put方法我们看到

if (item == k) {

@SuppressWarnings("unchecked")

V oldValue = (V) tab[i + 1];

tab[i + 1] = value;

return oldValue;

}

只有key==相等才去替换。为什么key,key1,key2 equals相等但是==不等呢?这又涉及到String构造的问题。后面又是什么String常量池等一大堆的概念。

略略略,不想写了,题主自己百度吧

开个玩笑,我们还是要多读源码的,看看技术大佬们是怎么敲代码还是很有好处的。

(知乎处女答,睡觉觉咯)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值