https://blog.csdn.net/u010297957/article/details/51974340
Java的HashMap
FAQ:
为什么要有HashMap?
答:我非常期待能在Java 中使用Hash表 这种数据结构 ,因为它的快速存取特性。
Hash表 和HashMap的关系?
答:Hash表 是一种逻辑数据结构,HashMap是Java中的一种数据类型,它通过代码实现了Hash表 这种数据结构,并利用此结构实现了Map的功能。去除value部分只看key部分就是一个Hash表 了。
这一章节我们要干嘛?
答:首先要明白我们是在干嘛?我们是在分析一个叫做哈希表的数据结构吗?
不是的!我们是在讨论Java 这个高级程序设计语言中一个数据类型Map的实现HashMap,它利用了哈希表这个数据结构但它不是哈希表本身,它就是它自己 - HashMap类型。所以,我们再看一次HashMap父接口Map的JavaDoc描述: “An object that maps keys to values. ”,即“Map是一个键值对对象”。
Java中的数据类型
答:有些话不明白的说出来,其实容易让人想不明白。所以我想说:
实际上,编程语言中数据类型都是层层封装的结果。
实际上,Java 中只有3类数据类型:原生类型(primitive8个)、数组、Object。
实际上,无论官方的集合框架也好,你自己创建的类也好,都只能是源自于Object并依赖于原有的这3类数据类型;
最终,到现在你可能才会发现,“数组”这种类型竟是如此的重要,在Java 中,如果没有数组作为基础结构,你是不可能构造出任何想实现某种数据结构的Object类型的。
hashMap底层的数据结构就是数组和链表的结合
数组是固定的,每个数组元素对应一个链表,
当put一个key-value,先计算用哪个数组元素,
确定了数组元素的索引就在在链表中添加数据,
一个数组元素对应一个链表,一个链表对应多个key-value的封装类entry
hashMap不是线程安全的
http://wiki.jikexueyuan.com/project/java-collection/hashmap.html
并发修改异常
hashSet底层用的hashMap
http://wiki.jikexueyuan.com/project/java-collection/hashset.html
怎么保证元素唯一行呢?
/**
* @param e 将添加到此set中的元素。
* @return 如果此set尚未包含指定元素,则返回true。
*/
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
把set添加的值作为map的key
值的hash不能相同。
hashTable
http://wiki.jikexueyuan.com/project/java-collection/hashtable.html
hashtable也是用的数组和链表的结构;
但是hashtable是线程安全的,因此每个public方法都加了synchronized
在单线程环境里会影响执行效率;
Hashtable 与 HashMap 的简单比较
HashTable 基于 Dictionary 类,而 HashMap 是基于 AbstractMap。Dictionary 是任何可将键映射到相应值的类的抽象父类,而 AbstractMap 是基于 Map 接口的实现,它以最大限度地减少实现此接口所需的工作。
HashMap 的 key 和 value 都允许为 null,而 Hashtable 的 key 和 value 都不允许为 null。HashMap 遇到 key 为 null 的时候,调用 putForNullKey 方法进行处理,而对 value 没有处理;Hashtable遇到 null,直接返回 NullPointerException。
Hashtable 方法是同步,而HashMap则不是。我们可以看一下源码,Hashtable 中的几乎所有的 public 的方法都是 synchronized 的,而有些方法也是在内部通过 synchronized 代码块来实现。所以有人一般都建议如果是涉及到多线程同步时采用 HashTable,没有涉及就采用 HashMap,但是在 Collections 类中存在一个静态方法:synchronizedMap(),该方法创建了一个线程安全的 Map 对象,并把它作为一个封装的对象来返回。