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. 夏梦竹谈Hive vs. HBase的区别

    对于刚接触大数据的用户来说,要想区分Hive与HBase是有一定难度的.本文将尝试从其各自的定义.特点.限制.应用场景等角度来进行分析,以作抛砖引玉之用.  Hive是什么? Apache Hive是 ...

  2. 自定义AuthorizeAttribute

    原文地址:http://www.cnblogs.com/shanyou/archive/2010/03/29/1699511.html 网站的权限判断是一个非常普遍的需求,从文章ASP.NET MVC ...

  3. .net 安装remoting服务

    程序->vs2008->vs tools->vs2008 命令提示 D:\QidianWorkShop\Develop\Source\Services\Snda.Qidian.Hon ...

  4. 1036 : Trie图 (AC自动机)

    题目大意: 输入 n 个目标单词和一个文本串,判断文本串中是否存在某些目标单词. 思路 赤裸裸的 AC自动机. 代码: #include<iostream> #include<cst ...

  5. Spring 4.0 StandaloneMockMvcBuilder java.lang.NoClassDefFoundError: javax/servlet/SessionCookieConfig 问题解决

    standaloneSetup(clrr). build(); 执行第二行 build() 时,出现下面的错误提示. java.lang.NoClassDefFoundError: javax/ser ...

  6. C++ 匿名名字空间及静态非成员函数

    在C++中,static有一个感觉被较少提及的用法:修饰非成员函数,这个用法实际是从C语言继承来的.其作用是表明这个函数只在当前编译单元中有效.这就使这个函数的所有引用在编译时就可以全部确定,无需进入 ...

  7. 转: LRU缓存介绍与实现 (Java)

    引子: 我们平时总会有一个电话本记录所有朋友的电话,但是,如果有朋友经常联系,那些朋友的电话号码不用翻电话本我们也能记住,但是,如果长时间没有联系了,要再次联系那位朋友的时候,我们又不得不求助电话本, ...

  8. TestNG 与 Junit的比较(转)

    转自 http://www.blogjava.net/fanscial/archive/2005/12/14/23780.html 1.         JDK 5 Annotations (JDK ...

  9. homebrew介绍

    对于一个习惯了在 Ubuntu 的终端上通过 apt-get 来安装工具软件的我来说,也希望在Mac上找到类似的工具,能很方便的一条命令就能安装所需的软件,而不用手工的去查找下载编译,或者是折腾安装所 ...

  10. Object-C变量作用域 -- 笔记

    @interface Dog: NSObject { @public int age; @protected int ID; @Private float price; } @end 字段作用域解析: ...