Map用作什么场景,hashMap和hashTable有什么区别
详细请参考文章来源:http://blog.csdn.net/justloveyou_/article/details/62893086?locationNum=2&fps=1
1.map是key-value对映射的接口,通过hash算法来实现key-value的位置存储,从而快速高效的存取
2.hash算法:hash算法是一个集合到另一个集合的映射,key键的集合到value值集合的映射,这个映射要求考虑时间复杂度和空间复杂度,同时还有冲突碰撞
3 hash构造函数的方法有多种,如直接订址,数字分析,折叠,平方取中等等方法
4 HashMap的构造方法,hashMap的构造方法一般会默认有个容量为16,还有一个负载因子参数0.75;
对于hashMap我们应该知道哪些
看下面的5点之前我们先说说hashmap的数据结构
key-value键值对:key和value是如果存储的?hashMap的对象是Entry<k,V>
key通过hash算法(也就是hashcode)会得到一个int类型的值,一个int类型的值会对应数组的一个下标,
即找到这个桶,然后遍历这个桶(链表),找到value的值
1,hashMap效率高,线程不安全,hashTable实现了同步锁,线程安全,效率低,目前线程安全的一般用concurrenthashMap
2、如果两个对象equals,Java运行时环境会认为他们的hashcode一定相等。
3、如果两个对象不equals,他们的hashcode有可能相等。
4、如果两个对象hashcode相等,他们不一定equals(我理解是由于hash冲突造成的)。
5、如果两个对象hashcode不相等,他们一定不equals。
一 hashmap的构造函数
public HashMap(){
//负载因子,说明hashMap的空间使用情况,默认是0.75
this.loadFactor = DEFAULT_LOAD_FACTOR;
//进行扩容的阈值,默认负载因子*默认容量值,默认容量值为16
threshold=(int)(DEFAULT_INITIAL_CAPACITY * DEFAULT_LOAD_FACTOR);
//hashMap的底层仍然是数组,数组里存放的链表形式的数据
table = new Entry[DEFAULT_INITIAL_CAPACITY];
init();
}
二 hash的数据结构
1,hash()算法:hash就是把一个key值通过hash算法转换为一个int型整数,他是一种压缩映射,压缩后的hash值不一定和原来的key数量相等
2,hashmap是数组数据结构和链表数据结构的结合;hashMap的内部对象是一个Entry<K,V数组>;Entry数组的结构如下:
public static class Entry
implements Map.Entry
{
final K key;//key
V value;//value
Entry
next;//指向下一个节点
final int hash;//hash(Key.hashCode())返回值
public Entry(int h, K k, V v, Entry
n){
value = v;
next = n;
key = k;
hash = h;
}
}
首先,判断key是否为null,若为null,则直接调用putForNullKey方法;若不为空,则先计算key的hash值,然后根据hash值搜索在table数组中的索引位置,如果table数组在该位置处有元素,则查找是否存在相同的key,若存在则覆盖原来key的value,否则将该元素保存在链头(最先保存的元素放在链尾)。此外,若table在该处没有元素,则直接保存
public V put(K key, V value) {
//当key为null时,调用putForNullKey方法,并将该键值对保存到table的第一个位置
if (key == null)
return putForNullKey(value);
//根据key的hashCode计算hash值
int hash = hash(key.hashCode()); // ------- (1)
//计算该键值对在数组中的存储位置(哪个桶)
int i = indexFor(hash, table.length); // ------- (2)
//在table的第i个桶上进行迭代,寻找 key 保存的位置
for (Entry
e = table[i]; e != null; e = e.next) { // ------- (3)
Object k;
//判断该条链上是否存在hash值相同且key值相等的映射,若存在,则直接覆盖 value,并返回旧value
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue; // 返回旧值
}
}
modCount++; //修改次数增加1,快速失败机制
//原HashMap中无该映射,将该添加至该链的链头
addEntry(hash, key, value, i);
return null;
}
上述的hash()方法和indexFor()方法的作用只有一个:保证元素均匀分布到table的每个桶中以便充分利用空间
更多了解参考http://blog.csdn.net/justloveyou_/article/details/62893086?locationNum=2&fps=1
这里的解释更详细也更深入,我这里只是自己学习了解