一 java集合框架图
二 map
2.1 hashMap
通过阅读map接口的源码可以发现,map的key是由set组织起来的,所以key是不能重复的。而value是Collection,value值是可以重复的。
HashMap结构
当表中key的值经过上述运算,总是得出相同的值,也就是说所有的都存放于同一个element中,即同一个bucket桶中,这样会使得桶的链表会变得很长,导致查询的性能恶化从O(1) 变为 O(n)
所以在java8及以后使用如下结构
构造函数
构造函数中并没有初始化,推断使用的是延迟加载,在使用到的时候初始化,如put()
put()方法
put执行过程:
hash()方法。
结合put中的方法可以指导新存入的数据应该放到哪个桶,也就是数组下标的计算过程
同时也发现为什么数组的大小一定要是2的幂次方。因为数组下标的算法是通过位运算来实现%求模的。将hash与(n-1)进行&运算可以看成是要保留几位。假设hash值为15,即0000 1111,数组长度为8,即(n-1)为7,0000 0111,那么取模后,得到的是0000 0111,会发现结果是保留3位。也只有n满足为2的幂次方时才能使用该运算。
如何有效减少碰撞
1、扰动函数算法,促使元素位置分布均匀,减少碰撞几率;
2、使用final对象,并采用合适的equals方法和hashCode方法;
扩容问题
线程安全问题
hashMap本身不是线程安全的但是可以将其转为安全的
与HashTable都是串行的效率低
2.2 Hashtable
目前已被废弃。
与hashMap最大区别就是,hashtable是线程安全的,key和value都不能为null。
hashMap 的key和value都能为空,但是这样的key只能有个一个,value可以多个。这样就不能使用get来判断是否存在,应该使用containsKey()
2.3 ConcurrentHashMap
提升hashtable性能
分段锁: