1、背景 

 今天翻开IdentityHashMap的时候,就傻眼了,这个到底是个逻辑啊,我的程序代码如下:

  IdentityHashMap<String,String> identityHashMap=new IdentityHashMap<String, String>();

     private void initMap(){
identityHashMap.put("zhangsan","age:18");
identityHashMap.put("lisi","age:24");
} public String getAge(String name){
return identityHashMap.get(name);
} public static void main(String[] args) {
IdentityHashMapTest test=new IdentityHashMapTest();
test.initMap(); String zhangsan=new String("zhangsan");
String lisi=new String("lisi");
System.out.println("zhangsan age is ="+ test.getAge(zhangsan));
System.out.println("lisi age is ="+ test.getAge(lisi)); }

运行的结果如下:

zhangsan age is =null
lisi age is =null

为什么如此呢?

2、源码探索

This class implements the <tt>Map</tt> interface with a hash table, using
* reference-equality in place of object-equality when comparing keys (and
* values). In other words, in an <tt>IdentityHashMap</tt>, two keys
* <tt>k1</tt> and <tt>k2</tt> are considered equal if and only if
* <tt>(k1==k2)</tt>. (In normal <tt>Map</tt> implementations (like
* <tt>HashMap</tt>) two keys <tt>k1</tt> and <tt>k2</tt> are considered equal
* if and only if <tt>(k1==null ? k2==null : k1.equals(k2))</tt>.)
也就是说IdentityHashMap的用法是,如果两个key是引用相等的时候,才会返回存在map里面的数据,否则返回为null,并不是像HashMap中的只是比较key的值是否相等
(k = p.key) == key || (key != null && key.equals(k))

put方法:

 public V put(K key, V value) {
Object k = maskNull(key);
Object[] tab = table;
int len = tab.length;
int i = hash(k, len); Object item;
while ( (item = tab[i]) != null) {
if (item == k) {
V oldValue = (V) tab[i + 1];
tab[i + 1] = value;
return oldValue;
}
i = nextKeyIndex(i, len);
} modCount++;
tab[i] = k;
tab[i + 1] = value;
if (++size >= threshold)
resize(len); // len == 2 * current capacity.
return null;
}

  从这里可以看出,int i = hash(k, len);一定是一个偶数值,并且这里使用的while循环操作,可能会有性能问题。

  这里key是放在偶数的位置,而value是存放在key对应的下个一个位置中  

  当size>threshold的时候,就会去扩容。

get方法

 public V get(Object key) {
Object k = maskNull(key);
Object[] tab = table;
int len = tab.length;
int i = hash(k, len);
while (true) {
Object item = tab[i];
if (item == k)
return (V) tab[i + 1];
if (item == null)
return null;
i = nextKeyIndex(i, len);
}
}

  这里查找value的时候也是使用while循环查找,不断的去轮询找key,知道遇到空。

  也是使用强引用的比较,如果是key1==key2,才会返回对应的值。

3、使用场景

  现在想想这中map的设计,也挺有意思的。

  比如我想在户口登记处中找到一个叫张三的,他现在几岁了?全国叫张三的人这么多,户口注册的时候,又没有说不能重名,我怎么知道这个张三是否是你要找的那个张三呢?所以这个时候就可以使用IdentityHashMap来存储了,只有是保证强引用的时候,才可以找到,否则,我还是会告诉你,我不知道张三是谁

java-map-IdentityHashMap的更多相关文章

  1. java:Map借口及其子类HashMap五,identityHashMap子类

    java:Map借口及其子类HashMap五,identityHashMap子类 了解:identityHashMap子类 一般情况下,标准的Map,是不会有重复的key值得value的,相同的key ...

  2. 入门:Java Map<String,String>遍历及修改

    重点:在使用Map时注意key-value,key用于检索value的内容. 在正常情况下,可以不允许重复:在java中分为2中情况,一是内存地址重复,另一个是不同的地址但内容相等. 在使用Map是一 ...

  3. Java Map操作

    Map:键必须是唯一 同步方法:Map m = Collections.synchronizedMap(new TreeMap(...)); Hashtable:基于散列表的实现 允许空键空值 线程安 ...

  4. Java map 详解 - 用法、遍历、排序、常用API等

    尊重原创: http://www.cnblogs.com/lzq198754/p/5780165.html 概要: java.util 中的集合类包含 Java 中某些最常用的类.最常用的集合类是 L ...

  5. java Map实现的cache manager

    一个模仿memcached的JAVA虚拟缓存工具,可以缓存java对象 import java.io.ByteArrayInputStream; import java.io.ByteArrayOut ...

  6. java map遍历、排序,根据value获取key

    Map 四种遍历: Map<String,String> map = new HashMap<String, String>(); map.put("one" ...

  7. java Map常用方法封装

      java Map常用方法封装 CreationTime--2018年7月16日15点59分 Author:Marydon 1.准备工作 import java.util.HashMap; impo ...

  8. Java Map获取key和value 以及String字符串转List方法

    一.问题描述 这里描述两个问题: 1.Java Map获取key和value的方法: 2.String字符串转List的方法: 二.解决方法 1.Java Map获取key和value的方法   2. ...

  9. java map添加另一个map时候 键值对的类型要一致

    java map添加另一个map时候 键值对的类型要一致

  10. java:Map借口及其子类HashMap四

    java:Map借口及其子类HashMap四 使用非系统对象作为key,使用匿名对象获取数据 在Map中可以使用匿名对象找到一个key对应的value. person: public class Ha ...

随机推荐

  1. Silverlight 模板(Template)使用

    模板(Template)是控件另一种样式 它和样式(style)不同的是它允许已有的控件进行组合新的一个控件样式 那么先看一下最简单Template代码 xaml代码 <Button Conte ...

  2. Delphi 线程resume 不能调用Execute

    如果Resume不能唤起线程,请试试如下的函数,试试. GetExitCodeThread(ThreadHandle,ExitCode)来取得ExitCode,如果ExitCode=STILL_ACT ...

  3. 辛巴达:帮电商打造ZARA式开放供应链体系 - 行业网站 - 亿邦动力网

    辛巴达:帮电商打造ZARA式开放供应链体系 - 行业网站 - 亿邦动力网 辛巴达:帮电商打造ZARA式开放供应链体系

  4. 利用"NOTIFYICONDATA"实现MFC的托盘程序

    本文章为转发百度空间内容,,保存一下,以防以后用到.. 一.自定义信息 在头文件中加入下面这句话: #define WM_SHOWTASK (WM_USER+1) 二.MYDLG.CPP文件中添加_m ...

  5. Context中嵌套<Environment>元素

    环境条目  可以在Context中嵌套<Environment>元素,配置命名的值,这些值作为环境条目资源(Environment Entry Resource),对整个web应用可见.比 ...

  6. Spring MVC之LocaleResolver(解析用户区域)

    为了让web应用程序支持国际化,必须识别每个用户的首选区域,并根据这个区域显示内容. 在Spring MVC应用程序中,用户的区域是通过区域解析器来识别的,它必须实现LocaleResolver接口. ...

  7. 【科研论文】W5100在远程电力质量监测设备中的应用

    摘要: 针对传统电力质量监测方法实时性.多参数测试性能较差的缺点,提出了将以太网接入技术与电能采集相结合进行电力质量现场和远程在线监测的设计方案.硬件设计采用微控制器STM32FI03和以太网控制芯片 ...

  8. 适配ios7

    if ([self respondsToSelector:@selector(edgesForExtendedLayout)]) { self.edgesForExtendedLayout = UIR ...

  9. 新版福昕阅读器(Foxit Reader)启动速度慢解决办法

    新版福昕阅读器(FoxitReader)启动速度慢解决办法之前喜欢使用福昕阅读器的原因就是看中了其小巧,可是最近版本的阅读器打开速度变得慢了很多(不是电脑配置问题),比AdobeReader还要慢,这 ...

  10. hdu3724Encoded Barcodes(Trie tree)

    题目请戳这里 题目大意:给n个字符串,给m个询问,每个询问给k个条形码.每个条形码由8个小码组成,每个小码有相应的宽度,已知一个条形码的宽度只有2种,宽的表示1,窄的表示0.并且宽的宽度是窄的宽度的2 ...