【Java】の基礎——LinkedList和ArrayList

Java集合主要可以劃分爲4個部分:List列表、Set集合、Map映射、工具類(Iterator迭代器、Enumeration枚舉類、Arrays和Collections)。

Collection

Collection的爸爸

Collection接口繼承Iterrable接口,
Iterrable:提供迭代的功能

public interface Iterable<T> {
    Iterator<T> iterator();
}

Iterator:迭代器,用於遍歷一個序列類似一個遊標。
public Interface Iterator{
boolean hasNext();
   Object next();
   void remove();
}

Collection的寶寶

看完了Collection的來歷,我們再看看的延伸:
Collection

public interface Collection<E> extends Iterable<E> {}

它是一個接口,是高度抽象出來的集合,它包含了集合的基本操作:添加、刪除、清空、遍歷(讀取)、是否爲空、獲取大小、是否保護某元素等等。
Collection接口包含了List和Set兩大分支。

  1. List是一個有序的隊列,每一個元素都有它的索引。第一個元素的索引值是0。
    List的實現類有LinkedList, ArrayList, Vector, Stack。
  2. Set是一個不允許有重複元素的集合。
    Set的實現類有HastSet和TreeSet。HashSet依賴於HashMap,它實際上是通過HashMap實現的;TreeSet依賴於TreeMap,它實際上是通過TreeMap實現的。

List是有序的隊列,List中可以有重複的元素;
Set是數學概念中的集合,Set中沒有重複元素。

List

public interface List<E> extends Collection<E> {}

List是有序的隊列,List中的每一個元素都有一個索引;第一個元素的索引值是0,往後的元素的索引值依次+1。List中允許有重複的元素。

Set

public interface Set<E> extends Collection<E> {}

Set是數學概念中的集合,Set中沒有重複元素。

ArrayList

ArrayList 實現了動態數組,它繼承於AbstractList,實現了List, RandomAccess, Cloneable, java.io.Serializable這些接口。
遍歷ArrayList時,使用隨機訪問(即,通過索引序號訪問)效率最高,而使用迭代器的效率最低。

ArrayList的Add擴容

在add時,先確認數組長度是否足夠(這個過程首先檢查內部數組是否爲空,如果爲空就設定默認的初始容量(10) ),接着判斷當前需要的容量是否大於內部數組,大於的話就進行擴容。
擴容的過程是,將內部數組拷貝到一個新的大小爲原數組1.5倍的數組中(這裏也要先計算,來判斷擴容後是否會過大,出現溢出等情況),然後將內部數組的引用改爲新數組。

LinkedList

雙向鏈表,定義了Node(Entry — 1.8之前)

LinkedList的Add擴容:

JDK1.8之前:

不得不說它的addBefore方法 addBefore(E e, Entry entry)
就是在entry結點之前插入一個新的結點存放e。

public boolean add(E e) {
    addBefore(e, header);
    return true;
}
public void add(int index, E element) {
     addBefore(element, (index==size ? header : entry(index)));
}
public void addFirst(E e) {
    addBefore(e, header.next);
}
public void addLast(E e) {
    addBefore(e, header);
}

JDK1.8:

public boolean add(E e) {
        // 添加到末尾
        linkLast(e);
        return true;
   }
void linkLast(E e) {
        // 保存尾結點,l爲final類型,不可更改
        final Node<E> l = last;
        // 新生成結點的前驅爲l,後繼爲null
        final Node<E> newNode = new Node<>(l, e, null);
        // 重新賦值尾結點
        last = newNode;    
        if (l == null) // 尾結點爲空
            first = newNode; // 賦值頭結點
        else // 尾結點不爲空
            l.next = newNode; // 尾結點的後繼爲新生成的結點
        // 大小加1    
        size++;
        // 結構性修改加1
        modCount++;
    }

當然,它也提供了LinkFirst()插入第一個元素,LinkBefore()來插入元素等方法。

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