java 集合--Collection子介面LINK (總結於尚矽谷java)
阿新 • • 發佈:2021-02-07
Collection子接
1.Collection中子介面的整體描述
|----Collection介面:單列集合,用來儲存一個一個的物件 |----List介面:儲存有序的、可重複的資料。 -->“動態”陣列,替換原有的陣列 |----ArrayList:作為List介面的主要實現類;執行緒不安全的,效率高;底層使用Object[] elementData儲存 |----LinkedList:對於頻繁的插入、刪除操作,使用此類效率比ArrayList高;底層使用雙向連結串列儲存 |----Vector:作為List介面的古老實現類;執行緒安全的,效率低;底層使用Object[] elementData儲存
2.List介面方法
List除了從Collection集合繼承的方法外,List 集合裡添加了一些根據索引來操作集合元素的方法
- void add(int index, Object ele):在index位置插入ele元素
- boolean addAll(int index, Collection eles):從index位置開始將eles中的所有元素新增進來
- Object get(int index):獲取指定index位置的元素
- int indexOf(Object obj):返回obj在集合中首次出現的位置
- int lastIndexOf(Object obj):返回obj在當前集合中末次出現的位置
- Object remove(int index):移除指定index位置的元素,並返回此元素
- Object set(int index, Object ele):設定指定index位置的元素為ele
- List subList(int fromIndex, int toIndex):返回從fromIndex到toIndex
位置的子集合
ArrayList list = new ArrayList();
list.add(123);
list.add(456);
list.add("AA");
list. add(new Person("Tom",12));
list.add(456);
System.out.println(list);
//[123, 456, AA, Person{name='Tom', age=12}, 456]
//void add(int index, Object ele):在index位置插入ele元素
list.add(1,"BB");
System.out.println(list);
//[123, BB, 456, AA, Person{name='Tom', age=12}, 456]
//boolean addAll(int index, Collection eles):從index位置開始將eles中的所有元素新增進來
System.out.println(list.size());//6
List list1 = Arrays.asList(1, 2, 3);//往裡添加了3個元素
list.addAll(list1);
// list.add(list1); 這裡表示只添加了一個元素 123為一個
System.out.println(list.size());//9
//Object get(int index):獲取指定index位置的元素
System.out.println(list.get(0));
//int indexOf(Object obj):返回obj在集合中首次出現的位置。如果不存在,返回-1.
int index = list.indexOf(4567);
System.out.println(index);
//int lastIndexOf(Object obj):返回obj在當前集合中末次出現的位置。如果不存在,返回-1.
System.out.println(list.lastIndexOf(456));
//Object remove(int index):移除指定index位置的元素,並返回此元素
Object obj = list.remove(0);
System.out.println(obj); //返回123
System.out.println(list);//輸出刪除123的所有的元素
@Test
public void testListRemove() {
List list = new ArrayList();
list.add(1);
list.add(2);
list.add(3);
updateList(list);
System.out.println(list);
}
private static void updateList(List list) {
list.remove(2); //remove是指定刪除index 所以真實得是刪除3 而不是2
}
//Object set(int index, Object ele):設定指定index位置的元素為ele
list.set(1,"CC");
System.out.println(list);
//List subList(int fromIndex, int toIndex):返回從fromIndex到toIndex位置的左閉右開區間的子集合
List subList = list.subList(2, 4);
System.out.println(subList);
System.out.println(list);
迴圈ArryList的方式:
//方式一:Iterator迭代器方式
Iterator iterator = list.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
System.out.println("***************");
//方式二:foreach迴圈
for(Object obj : list){
System.out.println(obj);
}
System.out.println("***************");
//方式三:普通for迴圈
for(int i = 0;i < list.size();i++){
System.out.println(list.get(i));
}
3.List實現類子介面ArrayList
本質上,ArrayList是物件引用的一個”變長”陣列
ArrayList的原始碼分析
//1.在jdk7的時候:
//底層建立了長度是10的Object[]陣列elementData
ArrayList list = new ArrayList();
list.add(123); //elementData[0] = new Integer(123);
...
list.add(123);
//果此次的新增導致底層elementData陣列10個容量不夠,則擴容。預設情況下,擴容為原來的容量的1.5倍,同時需要將原有陣列中的資料複製到新的陣列中。
//2.在jdk8後
//底層Object[] elementData初始化為{}.並沒有建立長度為10的陣列
ArrayList list = new ArrayList();
list.add(123); //第一次呼叫add()時,底層才建立了長度10的陣列,並將資料123新增到elementData[0]
...
list.add(123);
//若容量不夠 則和7一樣
總結:
- 開發中建議使用帶參的構造器:ArrayList list = new ArrayList(int capacity)
- jdk7中的ArrayList的物件的建立類似於單例的餓漢式,而jdk8中的ArrayList的物件的建立類似於單例的懶漢式,延遲了陣列的建立,節省記憶體。
4.List實現類子介面LinkedList
雙向連結串列,內部沒有宣告陣列,而是定義了Node型別的first和last,用於記錄首末元素。同時,定義內部類Node,作為LinkedList中儲存資料的基本結構。Node除了儲存資料,還定義了兩個變數:
prev變數記錄前一個元素的位置
next變數記錄下一個元素的位置
新增的方法:
- void addFirst(Object obj)
- void addLast(Object obj)
- Object getFirst()
- Object getLast()
- Object removeFirst()
- Object removeLast()
雙向連結串列,內部沒有宣告陣列,而是定義了Node型別的first和last,用於記錄首末元素。同時,定義內部類Node,作為LinkedList中儲存資料的基本結構。Node除了儲存資料,還定義了兩個變數:
prev變數記錄前一個元素的位置
next變數記錄下一個元素的位置
LinkedList的原始碼分析
//內部聲明瞭Node型別的first和last屬性,預設值為null
LinkedList list = new LinkedList();
//將123封裝到Node中,建立了Node物件。
list.add(123);
// 其中,Node定義為:體現了LinkedList的雙向連結串列的說法
// private static class Node<E> {
// E item;
// Node<E> next;
// Node<E> prev;
//
// Node(Node<E> prev, E element, Node<E> next) {
// this.item = element;
// this.next = next;
// this.prev = prev;
// }
5.List實現類子介面Vector
- Vector 是一個古老的集合,JDK1.0就有了。大多數操作與ArrayList相同,區別之處在於Vector是執行緒安全的。(過時的不使用)
Vector的原始碼分析:jdk7和jdk8中通過Vector()構造器建立物件時,底層都建立了長度為10的陣列。
在擴容方面,預設擴容為原來的陣列長度的2倍。
注意點:
ArrayList、LinkedList、vector的異同?理解?底層實現原理和擴容機制
1.ArrayList、LinkedList 2個都是不安全的,但是執行效率要比vector高
2.ArrayList是實現了基於動態陣列的資料結構,LinkedList基於連結串列的資料結構。對於隨機訪問get和set,ArrayList覺得優於LinkedList,因為LinkedList要移動指標。對於新增和刪除操作add(特指插入)和remove,LinkedList比較佔優勢,因為ArrayList要移動資料。
3.ArrayList類似於單例模式的餓漢式 先在底層建立element陣列 10個,而LinkedList類似單例模式的懶漢式,在執行add的時候才去建立element陣列(用的時候才去做)
4.vector和ArrayList底層原理一樣 擴容倍數不同
5.Arraylist和LinkedList擴容都是原理的1.5倍 vector為原來的2倍