Java集合學習筆記(1)
java集合
1. 集合關係圖
-
集合介面
terface.png)
-
實現類
2. LinkedList與ArrayList
2.1常用api,迷惑看https://docs.oracle.com/javase/7/docs/api/
-
構造
-
ArrayList() 構造一個初始容量為0的空列表,官方文件上說是10, 我認為不正確。原始碼中建構函式中陣列指標指向一了空陣列,儘管size欄位在申明時初始化為10, 但是不代表構造完成後陣列大小為10。當插入元素時才開始擴容為10。
int[] array = {}; // 等價與int[] array = new int[0] // array長度為0,但是不為null // null表示這個變數指向的物件為不存在,還沒有給物件分配記憶體空間 // 此處的array指向了一個物件,只不過這個物件陣列長度為零罷了。
- ArrayList(Collection<? extends E>) 構造一個包含集合的元素,按照他們由集合迭代器返回的順序構建ArrayList。如果集合內的元素Class一樣,也就是說型別一樣,直接指向Collection。如果是子類,利用Arrays.copy()複製,進行型別強轉。
- ArrayList(int initailCapacity) 構造具有初始容量的ArrayList,一般而言,如果事先知道有多少個元素,最好指定容量,避免不必要的resize()。儘管陣列容量不為0, 但是有效元素個數size為0!!!
-
-
增
-
boolean add(E e) 增加元素到列表末尾
-
boolean add(int index, E element) 在索引index前面插入element。
List<Integer> array = ArrayList(10); array.add(2, 5); // 上面的程式碼出現數組越界異常 // 我以為聲明瞭10個空間大小,每個初始化為0,所以我可以這麼幹啊。 // 儘管聲明瞭大小為10的陣列,但是size = 0, size為有效元素的個數。 // add()是針對下標在0-size-1之間的陣列。
- boolean addAll(Collection<? extends E>) Collectin加到arraylist尾部
-
-
刪
-
boolean remove(int index) 刪除index下標,當然了,index也必須時在0-size-1之間
-
boolean remove(Object 0) 刪除第一個元素0,內部使用equals()比較
// 貼一段我覺得寫得很棒的程式碼 // 如果我實現下面的邏輯,肯定是return到處扔,肯定要把break換成fastRemove(es, i)和return true // 要是需求變了,要求remove失敗返回true, 那就拉胯了。 public boolean remove(Object o) { final Object[] es = elementData; final int size = this.size; int i = 0; found: { if (o == null) { for (; i < size; i++) if (es[i] == null) break found;//跳出found } else { for (; i < size; i++) if (o.equals(es[i])) break found;//跳出found } return false; } fastRemove(es, i); return true; }
-
-
改
- E set(int index, E element) 返回原來的值
-
查
- E get(int index)
-
其他
- int size() 有效元素個數
- int indexOf(Object o) 返回元素下標, 內部使用equals比較大小
- Iterator
iterator() 返回迭代器 - Object clone()返回淺拷貝arrayList()
- contains(Object o) 內部使用equeals()
- Object[] toArray() 返回對應的陣列
LinkedList, 除了ArrayList的一些操作,還可以當棧,佇列,雙端佇列,所以api要多一點
-
建構函式
- LinkList()
- LinkList(Collection<? extend E> c)
-
增
-
boolean addFirst(E e) boolean addLast(E e) 雙端佇列常用操作
-
add(E e) 隊尾部加
-
-
刪
-
E remove() 刪除第一個節點
-
E removeFirst()
-
E removeLast()
-
E poll() 刪除第一個節點
-
E pollFirst()
-
E pollLast()
-
-
改
- set(in index)
-
檢視
-
E peek() 獲得第一個元素
-
E peekFirst() 獲得第一個元素
-
E peekLast() 獲得最後一個元素
-
E getFirst()
-
E getLast()
-
2.2 內部實現分
-
ArrayList : 可擴容的動態陣列
- 執行緒不同步。
- 預設初始容量為 10,當陣列大小不足時容量擴大為 1.5 倍。
- 為追求效率,ArrayList 沒有實現同步(synchronized),如果需要多個執行緒併發訪問,使用者可以手動同步,也可使用 Vector 替代。
-
LinkedList: 雙向連結串列
-
執行緒不同步。
-
雙向連結實現。LinkedList 同時實現了 List 介面和 Deque 介面,也就是說它既可以看作一個順序容器,又可以看作一個佇列(Queue),同時又可以看作一個棧(Stack)。
-
當你需要使用棧或者佇列時,可以考慮使用 LinkedList,一方面是因為 Java 官方已經宣告不建議使用 Stack 類,更遺憾的是,Java 里根本沒有一個叫做 Queue 的類(它是個介面名字)。關於棧或佇列,現在的首選是 ArrayDeque,它有著比 LinkedList(當作棧或佇列使用時)有著更好的效能
-
Vector
:實現同步的可擴容動態陣列-
執行緒同步。它的同步是通過
Iterator
方法加synchronized
實現的。 -
預設初始容量為 10,當陣列大小不足時容量擴大為 2 倍。
-
2.3 區別與聯絡
- ArrayList底層是陣列,可以通過下標直接定位到某個元素,時間複雜度為O(1),所以ArrayList更擅長read。當write的時候,如果是陣列中間插入或者刪除某個元素,那麼則需要移動大量的元素。當我們只是read資料,或者是在末尾插入或者刪除資料時,建議用ArrayList
- LinkedList底層是雙向連結串列,當我們需要read某個元素時,可以從頭或者從尾部開始遍歷,具體取決於離頭部近還是離尾部近。當需要wirte資料時,只用移動指標。所以,LinkedList更適合儲存那些常常被修改的資料。