美团面试题:Hashmap的结构,1.7和1.8有哪些区别,史上最深入的分析
https://blog.youkuaiyun.com/qq_36520235/article/details/82417949
HashMap , Hashtable, HashSet区别
HashMap和Hashtable两个类都实现了Map接口,二者保存K-V对(key-value对);HashSet则实现了Set接口,性质类似于集合。
HashTable和HashMap区别
一、继承的父类不同
Hashtable继承自Dictionary类,而HashMap继承自AbstractMap类。但二者都实现了Map接口。
二、线程安全性不同
Hashtable 中的方法是Synchronize的,而HashMap中的方法在缺省情况下是非Synchronize的。在多线程并发的环境下,可以直接使用Hashtable,不需要自己为它的方法实现同步,但使用HashMap时就必须要自己增加同步处理。
三、是否提供contains方法
HashMap把Hashtable的contains方法去掉了,改成containsValue和containsKey,因为contains方法容易让人引起误解。
Hashtable则保留了contains,containsValue和containsKey三个方法,其中contains和containsValue功能相同。
四、key和value是否允许null值
其中key和value都是对象,并且不能包含重复key,但可以包含重复的value。
Hashtable中,key和value都不允许出现null值。
HashMap中,null可以作为键,这样的键只有一个;可以有一个或多个键所对应的值为null。当get()方法返回null值时,可能是 HashMap中没有该键,也可能使该键所对应的值为null。因此,在HashMap中不能由get()方法来判断HashMap中是否存在某个键, 而应该用containsKey()方法来判断。
五、两个遍历方式的内部实现上不同
Hashtable、HashMap都使用了 Iterator。而由于历史原因,Hashtable还使用了Enumeration的方式 。
六、hash值不同
哈希值的使用不同,HashTable直接使用对象的hashCode。而HashMap重新计算hash值。
七、内部实现使用的数组初始化和扩容方式不同
Hashtable和HashMap它们两个内部实现方式的数组的初始大小和扩容的方式。HashTable中hash数组默认大小是11,增加的方式是 old*2+1。
HashMap中hash数组的默认大小是16,而且一定是2的指数。
HashSet
-
1实现了set接口,add()使用hashmap存储数据 ,并且把添加对象作为hashmap的key(必须唯一),所以set不容许存重复元素
-
2因此,使用hashSet存自定义对象前,必须重写自定义对象的hashcode()与equals()方法
public boolean add(E e) {
//
return map.put(e, PRESENT)==null;
}
HashSet实现了Set接口,它不允许集合中有重复的值,当我们提到HashSet时,第一件事情就是在将对象存储在HashSet之前,要先确保对象重写equals()和hashCode()方法,这样才能比较对象的值是否相等,以确保set中没有储存相等的对象。如果我们没有重写这两个方法,将会使用这个方法的默认实现。
public boolean add(Object o)方法用来在Set中添加元素,当元素值重复时则会立即返回false,如果成功添加的话会返回true。
##针对多线程情况
synchronizedMap
- 1 使用 synchronizedMap() 包装hanshmap
Map<String, Integer> hashMap = Collections.synchronizedMap(new HashMap<>());
ps: synchronizedMap 使用synchronize 低效
- 2 使用ConcurrentHashMap
ConcurrentHashMap的核心要点:
https://zhuanlan.zhihu.com/p/35668936
http://www.jasongj.com/java/concurrenthashmap/
原理
https://www.jianshu.com/p/865c813f2726
底层结构是散列表(数组+链表)+红黑树,这一点和HashMap是一样的。
Hashtable是将所有的方法进行同步,效率低下。而ConcurrentHashMap作为一个高并发的容器,它是通过部分锁定+CAS算法来进行实现线程安全的。CAS算法也可以认为是乐观锁的一种~
在高并发环境下,统计数据(计算size…等等)其实是无意义的,因为在下一时刻size值就变化了。
get方法是非阻塞,无锁的。重写Node类,通过volatile修饰next,取共享变量,保证可见性,即来实现每次获取都是最新设置的值
ConcurrentHashMap的key和Value都不能为null
–
linkedHashMap
深入研究–》https://www.cnblogs.com/xrq730/p/5052323.html
LinkedHashMap: HashMap子类
a、LinkedHashMap作为HashMap的子类,同样也可以存空的key和空的value。
b、LinkedHashMap会按存入顺序存放元素(迭代器顺序)。
现实中很多情况下都可以使用LinkedHashMap,例如购物车的实现:按用户添加的时间顺序显示购物车中的元素。