集合01

Java集合

ArrayList:List 接口的大小可变数组的实现,并允许包括 null 在内的所有元素,此类不同步

1、API描述:

a) Constructor:
    1.       ArrayList(int ini):构造一个ini为容量大小的对象。
b) Methods:
    1. add(E e):直接将元素添加在数组末尾
    2. add(int index,E)               
        c) 将元素添加到index位置,注意(@1)index最多超过此ArrayList实际大小1;
    3. addAll(Collection c):按照c的迭代器的顺序添加
    4. addAll(int index,Collection)
        d) 从指定的位置开始按照c的迭代器的顺序添加,index(@1)
    5. ensureCapacity(int
        e):手动增加此ArrayList的容量,当加入大量数据时,避免重复的扩增空间,影响效率。
    6.  get(int index):直接返回index位置上的元素,高效。

2、特性:

a)由于底层由数组实现,所以索引查找,索引删除都非常快,但是插入、删除等操作时间复杂度就高。
b)(@2)此方法不同步,如果要同不则要用到Collections.synchronizedList(new ArrayList(…))方法实现。
c)(@3)返回List特有的ListIterator遍历器,
d)(@4)在获得遍历器后,在对其结构进行更改是非法的

3、简单源码了解:

a) 拥有属性:int size、object [] elementData、另外拥有
    三个内部类Itr、ListItr、SubList来实现iterator  listIterator   subList方法
b) 重要方法:
1.  grow(int minCapacity):
    1.   privatevoidgrow(intminCapacity) {
    2.           // overflow-conscious code
    3.           intoldCapacity =elementData.length;
    4.           intnewCapacity =oldCapacity+ (oldCapacity>> 1);
    5.           if (newCapacity -minCapacity< 0)
    6.               newCapacity =minCapacity;
    7.           if (newCapacity -MAX_ARRAY_SIZE > 0)
    8.               newCapacity =hugeCapacity(minCapacity);
    9.           // minCapacity is usually close to size, so this is a win:
    10.          elementData = Arrays.copyOf(elementData,newCapacity);
    11.     }

minCapacity为size+1,newCapacity=length的3/2倍,当minCapacity仍然大于newCapacity时,则此当前容量等于实际容量。
当其最大值超过Max_ARRAY_SIZE时,会被限制在Integer.MAX_VALUE;

2. 内部类SubList中的set方法:
    1.   public E set(intindex, Ee) {
    2.               rangeCheck(index);
    3.               checkForComodification();
    4.               E oldValue = ArrayList.this.elementData(offset +index);
    5.               ArrayList.this.elementData[offset+index]=e;
    6.               returnoldValue;
    7.          }
在这里面,可以看到当改变这个subList时,原ArrayList也会发生改变

LinkedList:双向链表实现的List,允许多个null

1、 API描述:

a)  Method:
    1.  peek() element()  getFist():获取不移除表头
    2.  poll() pollFirst()   pop()  remove() removeFirst()  :获取表头并删除表头
    3.      descendingIterator:返回反向迭代器

2、 特性:

    a)  底层由双向链表实现,所有拥有链表易于更改,而难于查找的功能,
    b)  可以将LinkedList改造为栈、队列、双端队列数据结构,并且还提供了大量的获得头元素及尾元素等方法
    c)   @2 、@4、@3

3、 简单源码了解:

1.  拥有一个内部类Node作为链表的节点,first、last指针
2.  重要的方法:
    1.      publicboolean addAll(intindex, Collection<?extends E>c) {
    2.           checkPositionIndex(index);
    3.    
    4.           Object[] a = c.toArray();
    5.           intnumNew =a.length;
    6.           if (numNew == 0)
    7.               returnfalse;
    8.    
    9.           Node<E> pred, succ;
    10.          if (index ==size){@1:位于末尾
    11.              succ =null;
    12.              pred =last;
    13.          } else {@2:位于中间@3:位于开头
    14.              succ = node(index);
    15.              pred =succ.prev;
    16.          }
    17.   
    18.          for (Objecto :a) {
    19.              @SuppressWarnings("unchecked")Ee = (E)o;
    20.              Node<E> newNode =new Node<>(pred,e,null);
    21.              if (pred ==null)@3
    22.                  first =newNode;
    23.              else
    24.                  pred.next =newNode;@1@2@3
    25.              pred =newNode;
    26.          }
    27.   
    28.          if (succ ==null){
    29.              last =pred;@1
    30.          } else {
    31.              pred.next =succ;@2
    32.              succ.prev =pred;@2
    33.          }
    34.   
    35.          size +=numNew;
    36.          modCount++;
    37.          returntrue;
    38.      }
3. toArray(T[] a):当T的length不够时,重新构造一个数组赋值返回
    1.   public <T> T[] toArray(T[]a) {
    2.           if (a.length <size)
    3.      a=(T[])java.lang.reflect.Array.newInstance(
    4.                                   a.getClass().getComponentType(),size);
    5.           inti = 0;
    6.           Object[] result =a;
    7.           for (Node<E>x =first;x !=null;x = x.next)
    8.               result[i++] =x.item;
    9.    
    10.          if (a.length >size)
    11.              a[size] =null;
    12.   
    13.          returna;
    14.      }

HashTable:实现一个哈希表,将键映射到相应的值(非null),键值必须实现equals和hashCode方法,其容量大小由桶的个数和加载因子决定,此类每个方法实现同步。

1. API描述:

    1.  contains(Objectkey)、contains(Object value):检测 或者键
    2.  elements()、keys():返回值和键的枚举
    3.  rehash():增加Hash表达容量
    4.  常用的put(Object key,Object value)、get(Object key)

2. 特点:

    a)  其拥有一个内部类的数组,而内部类为一个链表,即为一个个桶。通过一个对对象的hash码的算法作为key。
    b)  很重要的是,如果一个类想要存放进HashTable的key,必须要严格的重写equeals()方法和hashCode方法。
    c)  在通过其他途径获得迭代器后,也是快速失败的,即不能通过非迭代器的方法改变此类的结构

3. 简单源码了解

1.  put(Kkey,T value):
1.   publicsynchronized Vput(Kkey, Vvalue) {
2.           // Make sure the value is not null
3.           if (value ==null){
4.               thrownew NullPointerException();
5.           }
6.    
7.           // Makes sure the key is not already in the hashtable.
8.           Entry tab[] = table;
9.           inthash =key.hashCode();
10.          intindex = (hash& 0x7FFFFFFF) %tab.length;
11.          for (Entry<K,V>e =tab[index];e !=null ;e =e.next) {
12.              if ((e.hash ==hash) &&e.key.equals(key)) {
13.                  V old = e.value;
14.                  e.value =value;
15.                  returnold;
16.              }
17.          }
18.   
19.          modCount++;
20.          if (count >=threshold){
21.              // Rehash the table if the threshold is exceeded
22.              rehash();
23.   
24.              tab =table;
25.              index = (hash & 0x7FFFFFFF) %tab.length;
26.          }
27.   
28.          // Creates the new entry.
29.          Entry<K,V> e = tab[index];
30.          tab[index] =newEntry<>(hash,key,value,e);
31.          count++;
32.          returnnull;
33.       }

可以看出,得到对象的Hash码之后,便进行(hash&0x7FFFFFFF) %tab.length运算,得到桶的位置,遍历桶,插入对象

2.  rehash()
    1.   protectedvoidrehash() {
    2.           intoldCapacity =table.length;
    3.           Entry[] oldMap = table;
    4.    
    5.           // overflow-conscious code
    6.           intnewCapacity = (oldCapacity<< 1) + 1;
    7.           if (newCapacity -MAX_ARRAY_SIZE > 0) {
    8.               if (oldCapacity ==MAX_ARRAY_SIZE)
    9.                   // Keep running with MAX_ARRAY_SIZE buckets
    10.                  return;
    11.              newCapacity =MAX_ARRAY_SIZE;
    12.          }
    13.          Entry[] newMap = new Entry[newCapacity];
    14.   
    15.          modCount++;
    16.          threshold = (int)(newCapacity *loadFactor);
    17.          table =newMap;
    18.   
    19.          for (inti =oldCapacity;i-- > 0 ;) {
    20.              for (Entry<K,V>old =oldMap[i] ;old !=null ; ) {
    21.                  Entry<K,V>e =old;
    22.                  old =old.next;
    23.   
    24.                  intindex = (e.hash & 0x7FFFFFFF) %newCapacity;
    25.                  e.next =newMap[index];
    26.                  newMap[index] =e;
    27.              }
    28.          }
    29.       }

可以看出,当接近HashTable的容量时,会新申请一个Entity数组来扩增,扩增容量大致为原来的两倍
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值