Java集合总结:

2016-09-14  本文已影响0人  cp_insist

概述:尽管已经将java核心编程中的集合看了好几遍了,但是还是感觉心里没有低;所以今天特别将集合这块常见的面试题进行总结,一边加深自己对java集合的理解;
<1>:谈谈你对HashMap具体实现的理解:
首先,hashMap是一个键值对类型的集合,他的键和值都可以为null;
使用hashMap存储数据时,首先我们键会先调用它的hashCode方法生成一个hashCode值,然后对这个的hashCode值再进一次移位的运算;

//java中的抖动函数
static  final int hash(Object Key){
    int h;
    if(key== null){
      return null  
    }else{
     return key==null ? 0:((h=h.hashCode) ^ h>>>16)
  }
} 

当然这样得到的hash值是不能直接作为数组的索引存储的;太大的;改进后的hashMap初始容量才是16;所以我们还需要对这个得到的值进行一次模运算:

 static int indexFor(int hash, int length) {
        return hash & (length-1);
   }

得到的结果便是我们想要存储的bucket的位置;此时如果篮子中没有值,我们直接将值放进这个bucket中键即可;如果有值即产生了我们所谓的hash冲突了;
散列表要解决的一个问题就是散列值的冲突问题,通常是两种方法:链表法和开放地址法。
链表法就是将相同hash值的对象组织成一个链表放在hash值对应的槽位;
开放地址法是通过一个探测算法,当某个槽位已经被占据的情况下继续查找下一个可以使用的槽位。java.util.HashMap采用的链表法的方式,链表是单向链表。形成单链表的核心代码如下:

void addEntry(int hash, K key, V value, int bucketIndex) {
        if ((size >= threshold) && (null != table[bucketIndex])) {
            resize(2 * table.length);
            hash = (null != key) ? hash(key) : 0;
            bucketIndex = indexFor(hash, table.length);
        }
        createEntry(hash, key, value, bucketIndex);
    }
 void createEntry(int hash, K key, V value, int bucketIndex) {
        Entry<K,V> e = table[bucketIndex];
        table[bucketIndex] = new Entry<>(hash, key, value, e);
        size++;
    }
上一篇 下一篇

猜你喜欢

热点阅读