散列表原理,HashMap源码解析

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/c_lutch/article/details/90239001

1.HashSet的实现原理
HashMap不会增加重复的元素(源码命中后做return),又HashSet底层是基于HashMap实现,故Set的add方法不允许增加重复的元素
总结:底层是基于HashMap实现,具体代码如下

    HashSet(int initialCapacity, float loadFactor, boolean dummy) {
        map = new LinkedHashMap<E,Object>(initialCapacity, loadFactor);
    }
    public boolean add(E e) {
        return map.put(e, PRESENT)==null;
    }    

HashSet的add方法是用Map的put方法实现。put查找命中更新值并返回旧值,旧值 != null,既添加已存在的元素add方法返回false;put未命中直接插入并返回null,因为null==null,故add返回true。存入的是默认值present;

2.HashMap的实现原理

  • HashMap put源码-简版
public V put(K key, V value) {
    for( Node x = first[ key.hashcode() % M ]; x!=null; x = x.next){
     if(x.key == key){
     	V oldValue = x.value;
     	x.value = value; 
     	return oldValue; //返回旧值
     }
    }
    first[ key.hashcode() % M ] = new Node(key, value,first); //未命中
    return null;

散列表使用链表数组实现,每个列表被称为桶。先计算hashCode(),再和桶的总数取余,所得的结果就是数组的索引(既桶的索引)。有时候桶被占满,就会出现散列冲突。解决哈希冲突可以是拉链法或线性探索法。桶其实拉链法。线性探索法又叫开放地址法,就是按地址在冲突的下一个空位插入。


3.List,Set和Map的不同
顺便回忆一下List,Set和Map的不同:

  • Collection是add,Map是put;
  • List是一个有序集合,元素会增加到容器的特定位置,使用迭代器添加元素有实际意义,Set和Map是无序的;

4.ConcurrentHashMap如何保证线程安全
java 7之前通过分段锁实现;java 8采用Node实现;

5.算法题里HashMap的使用

  • leetcode 实现两数之和target
HashMap<Integer, Integer> map = new HashMap();
int n = nums.length;
for(int i=0; i<n; i++){
   if(map.containsKey(target-nums[i])){
       int result[] = new int[2];
       result[0] = map.get(target-nums[i]);
       result[1] = i;
       return result;
   }
    else
        map.put(nums[i], i);
}
return null;
展开阅读全文

没有更多推荐了,返回首页