学习ArrayList和LinkedList的一些心得笔记,以及他们的区别

ArrayList:

			结构:数组
			创建时:1.无参数初始化
				   2.指定大小初始化
				   3.指定初始数据初始化
				   
			扩容:  1.第一次add时,如果是空数组,将capacity初始化为10
				   2.add时超过当前容量,则扩容至当前容量的1.5倍
				   3.如果扩容1.5倍后不够,则直接扩容到指定的容量(原始容量+新增的元素数量)
				   4.如果所需容量大于Integer.MAX_VALUE - 8,则直接扩容到Integer.MAX_VALUE				
				   
			扩容的本质 是调用System.arraycopy,是复制原数组到一个新的数组,因此非常消耗性能
				   
			删除:
					1.删掉指定位置的元素:先拿到指定位置的元素的值,然后将后面所有元素整体前移一位,最后一位置null(方便gc),size--
					
					2.删除指定元素时分两种情况,是null则找null,非null则找equeals的
					
			新增:	允许add  null
			
			迭代器: 在用for进行循环时,是不能进行使用原list进行remove的,因为索引的值一直在变,每remove一个,后面的元素向前移一位.
					因此如果要循环删除list中的元素,要使用Iterator

核心扩容代码

private void grow(int minCapacity) {
  int oldCapacity = elementData.length;
  int newCapacity = oldCapacity + (oldCapacity >> 1);

  // 如果扩容后的值 < 我们的期望值,扩容后的值就等于我们的期望值
  if (newCapacity - minCapacity < 0)
    newCapacity = minCapacity;

  // 如果扩容后的值 > jvm 所能分配的数组的最大值,那么就用 Integer 的最大值
  if (newCapacity - MAX_ARRAY_SIZE > 0)
    newCapacity = hugeCapacity(minCapacity);
 
  // 通过复制进行扩容,因此非常消耗性能
  elementData = Arrays.copyOf(elementData, newCapacity);
}

LinkedList:

			结构:双向链表结构
			新增:只能从头部或尾部新增
			
			删除:只能从头部或尾部删除
			
			查询:根据索引来查询节点,查找时采用二分法
			
			迭代器:  迭代器不同于其他迭代器,因为它是双向的,因此有它自身的ListIterator,可向前或向后迭代
						
					迭代器的删除:,删除之前迭代器迭代到的值,无论之前是向前还是向后迭代,都在同一个方法中进行删除操作
					
					迭代器初始化时,索引是0,也就是next指向第一个元素
					最开始的时候只能next,不能previous
					
					用previous的时候,返回的是上一次next指向的元素
					如果使用next之前有previous的操作,那么这次next指向的是上一次previous返回的元素
					
					核心代码{
					迭代previous:  lastReturn=next=(next==null?last:next.prev)//如果next为null,那么就是最后一个了,直接等于last
						next	:  lastReturn=next;
								   next=next.next;

我觉得的linkedlist的重点

public void remove() {
    checkForComodification();
    // lastReturned 是本次迭代需要删除的值,分以下空和非空两种情况:
    // lastReturned 为空,说明调用者没有主动执行过 next() 或者 previos(),直接报错
    // lastReturned 不为空,是在上次执行 next() 或者 previos()方法时赋的值
    if (lastReturned == null)
        throw new IllegalStateException();
    Node<E> lastNext = lastReturned.next;
    //删除当前节点
    unlink(lastReturned);
    //因为在previous方法中,最后是将next=lastReturned的
    if (next == lastReturned)
        //如果之前执行的是previous,那么将删掉的next记录起来,下次直接取它的previous
        next = lastNext;
    else
        nextIndex--;
    lastReturned = null;
    expectedModCount++;
}

ArrayList和LinkedList的主要区别有两点:
1.ArrayList的大小是受限制的,最大容量是Integer.MAX_VALUE,而LinkedList因为是双向联表结构,因此它在理论上是可以无限大的
2.迭代器不一样,linkedlist有它特殊的双向迭代器

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章