• 集合源码(一)之hashMap、ArrayList


    HashMap

    一、HashMap基本概念:

    HashMap是基于哈希表的Map接口的实现。此实现提供所有可选的映射操作,并允许使用null值和null键。此类不保证映射的顺序,特别是它不保证该顺序恒久不变。

    HashMap不是线程安全的,如果想要线程安全的HashMap,可以通过Collections类的静态方法synchronizedMap获得线程安全的HashMap。

    Map map = Connections.synchronized(new HashMap());

    二、HashMap的数据结构

    HashMap的底层主要是基于数组和链表来实现的,它之所以又相当快的查询速度是因为它是通过计算散列码来决定存储的位置。

    在构造HashMap的时候如果我们指定了加载因子和初始容量的话就调用第一个构造方法,否则的话就是用默认的。默认初始容量为16,默认加载因子为0.75。

    注:HashMap中则通过h&(length-1)的方法来代替取模(hash值对length取模),这也是HashMap对Hashtable的一个改进

    部分源码如下:

    public V put(K key, V value) {
         // 若“key为null”,则将该键值对添加到table[0]中。
             if (key == null)
                return putForNullKey(value);
         // 若“key不为null”,则计算该key的哈希值,然后将其添加到该哈希值对应的链表中。
             int hash = hash(key.hashCode());
         //搜索指定hash值在对应table中的索引
             int i = indexFor(hash, table.length);
         // 循环遍历Entry数组,若“该key”对应的键值对已经存在,则用新的value取代旧的value。然后退出!
             for (Entry<K,V> e = table[i]; e != null; e = e.next) {
                 Object k;
                  if (e.hash == hash && ((k = e.key) == key || key.equals(k))) { //如果key相同则覆盖并返回旧值
                      V oldValue = e.value;
                      e.value = value;
                      e.recordAccess(this);
                      return oldValue;
                  }
             }
         //修改次数+1
             modCount++;
         //将key-value添加到table[i]处
         addEntry(hash, key, value, i);
         return null;
    }




    ArrayList

    一、ArrayList的继承体系:

    public class ArrayList<E> extends AbstractList<E> implements List<E>,RandomAccess,Cloneable,java.io.Serializable

    public class ArrayList<E> extends AbstractList<E> implements List<E>,RandomAccess,Cloneable,java.io.Serializable

    部分源码如下:

    二、删除方法源码:删除一个元素且不说最好一个元素则需要移动底层数组,这个会导致效率低下,故ArrayList不适合删除操作过多的场景

    public E remove(int index){
             RangeCheck(index);   //检查索引边界
             modCount++;
             E oldValue = (E)elemetData[index]; //得到index上的元素
             Int numMoved = size – index -1; //得到需要移动的元素数列,注意这里要减1,因为不包括要删除的元素
    
        If(numMoved > 0) //需要移动的元素数量大于0,则开始移动ArrayList底层数组   System.arraycopy(elementData,index+1,elementData,index,numMoved);
          elementData[--size] = null;
       return oldValue;
    
    }
    三、contains方法用来判断ArrayList中对象o是否在,调用了indexOf来实现
          public int indexOf(Object o){
                  if(null == 0){ //如果o为null
                         for(int I = 0;i < size;i++){  //循环遍历ArrayList底层的数组
                                if(elementData[i] == null){
                                       return i;
                                }else {
                                       for(int i = 0;I < size;i++){
                                         if(o.equals(elementData[i])){ //若发现其中某个元素等于o,则返回该元素的索引
                                             return i;
             }
            }
    
    
    复制代码
    
    
  • 相关阅读:
    2020 牛客 NOIP 赛前集训营 提高级(第四场) B-色球 平衡树模板
    P4084 [USACO17DEC]Barn Painting G
    CSP-S 2020
    CQOI 2020省选
    我回来了
    hdu3605(二分图多重匹配伪模板)
    舞动的夜晚(二分图的必须边和可行边)
    poj3436(最大流+拆点)
    P2954([USACO09OPEN]移动牛棚Grazing2,dp)
    CSP-S 2020 游记
  • 原文地址:https://www.cnblogs.com/cczequn/p/6485575.html
Copyright © 2020-2023  润新知