HashMap与HashTable来自那?
Map
HashMap是什么? 结构图什么样?
扩容操作
HashTable是什么?
HashTable已经不怎么使用,主要是比Hashmap线程安全
HashMap与HashTable的区别
HashMap与HashTable的key和Value是否可以为空
HashMap
public V put(K key, V value) {
return putVal(hash(key), key, value, false, true);
}
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
Hashtable
public synchronized V put(K key, V value) {
// Make sure the value is not null
if (value == null) {
throw new NullPointerException();
}
// Makes sure the key is not already in the hashtable.
Entry<?,?> tab[] = table;
int hash = key.hashCode();
HashMap与HashTable 是否是线性安全
HashMap
public V put(K key, V value) {
return putVal(hash(key), key, value, false, true);
}
Hashtable
public synchronized V put(K key, V value)
HashMap与HashTable 初始值大小,最大容量,负载因子
HashMap
默认长度16
/**
* The default initial capacity - MUST be a power of two.
*/
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16
最大值
* The maximum capacity, used if a higher value is implicitly specified
* by either of the constructors with arguments.
* MUST be a power of two <= 1<<30.
*/
static final int MAXIMUM_CAPACITY = 1 << 30;
负载因子
/**
* The load factor used when none specified in constructor.
*/
static final float DEFAULT_LOAD_FACTOR = 0.75f;
节点数大于8转换为红黑树
static final int TREEIFY_THRESHOLD = 8;
Hashtable
默认是11,负载因子默认0.75
/**
* Constructs a new, empty hashtable with a default initial capacity (11)
* and load factor (0.75).
*/
public Hashtable() {
this(11, 0.75f);
}
HashMap解决冲突问题
// 如果hash和key,equal都相等,则把新值赋给旧值
if (p.hash == hash && ((k = p.key) == key || (key != null && key.equals(k))))
e = p;
什么时候冲突
threshold 表示阈值
table.length长度
loadFactor 表示负载因子
当threshold 阀值 = table.length * loadFactor , 当键值对对个数size大于threshold则表示需要扩容
如何把HashMap变成线程安全的
Collections.synchronizedCollection(Arrays.asList("a"));
//互斥对象成员
final Object mutex; // Object on which to synchronize
ConcurrentHashMap
基于分段锁进行处理, 他的好处就是hashTable使用利用的sync,属于方法锁,效率不好,所以我们更改把数据进行分段,然后锁分段的数据所以效率就高了, 处理数据的分段,他也是采用跟HashMap一样的结构
JDK7
JDK8