1. 程式人生 > 其它 >java 集合--Collection子介面LINK (總結於尚矽谷java)

java 集合--Collection子介面LINK (總結於尚矽谷java)

技術標籤:Java連結串列java

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一樣

總結:

  1. 開發中建議使用帶參的構造器:ArrayList list = new ArrayList(int capacity)
  2. 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

  1. 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倍