複習11:List&Set&Queue

集合:List

List是什麼

List是Collection的一個子接口,被稱爲有序列表

List的特點

  • 有序:每一個元素的索引被確定
  • 重複:集合中的元素可重複
  • 線性:元素的內存地址是連續的

List的實現類

  • ArrayList
  • LinkedList
  • Vector:與ArrayList相同,但是目前已不再使用Vector

Vector與ArrayList之間的關係:StringBuffer與StringBuilder之間的關係

List的迭代方式

  • 迭代器
  • for-each
  • for()
    • 有索引

List的常用API

  • add(int index,element):將元素添加到索引的位置
  • remove(index):移除索引位置的元素
  • get(index):獲取索引位置的元素
  • set(int index,element):使用新的元素替換索引位置的元素
  • indexOf(…):返回元素在集合中第一次出現的位置的索引
  • lastIndexOf(…):返回元素在集合中最後一次出現的位置的索引
  • List subList(int fromIndex,int endIndex):截取[fromIndex]到[endIndex]之間的集合(左開右閉)
    • 修改子集合中的元素時,父集合中的元素也會有同樣的變化
    • 添加元素到子集合中時,父集合中會插入相同的元素(與子集合順序保持一致)
    • 刪除子集合中的元素時,父集合中的相同元素也會被刪除
    • 由此我們得出結論:子集合與父集合共用一個內存空間,所有對子集合的操作都會影響到父集合
    • 解除父、子集合綁定的方法:List list =new ArrayList(LIst sunList)
  • toArray(…):
    • toArray():默認將集合轉換成一個Object類型的數組
    • toArray(T[] a):將集合轉換爲一個指定類型的數組(a是數組對象,不需要有元素)
      • 傳遞的數組參數的長度大於集合的長度,則多出來的位置用null填充
      • 傳遞的數組參數的長度小於集合的長度,則默認將數組長度擴容到與集合長度相同

數組轉換成集合:List list = Arrays.asList(Array a)

  • 泛型類型與傳遞的數組類型相同
  • 轉換後的list並非尋常的集合,而是數組的一個內部類,不能進行增、刪(改變長度),可以進行改、查;如果想操作該集合,只需創建一個新的集合對象,將list作爲參數構造新集合

ArrayList

ArrayList的實現

數組(Array)

ArrayList的特點
  • 內存空間連續
  • 查找效率高:元素的索引是確定的
  • 插入效率低
    • 頭部插入最慢:所有元素需要後移一位
    • 中部插入其次:插入位置之後的元素需要後移一位
    • 尾部插入最快:元素不需要後移
ArrayList的常用API
  • int size():返回列表中的元素
  • boolean isEmpty():判斷列表是否爲空
  • boolean contains(Object element):判斷列表是否包含元素
  • boolean add(Object element):將元素添加到列表末尾
  • void clear():情況列表中的所有元素
  • void add(int index,Object element):將元素插入到指定索引的位置
  • Object remove(int index):刪除指定索引位置的元素,並將該元素返回
  • boolean remove(Object element):刪除列表中第一次出現的匹配元素
  • Object set(Object oldE,ObjectnewE):使用新元素替換列表中的舊元素,並將舊元素返回
  • Object get(int index):獲取指定索引位置的元素
ArrayList的長度與擴容方式
  • 初始長度:10
  • 擴容方式:擴容後的大小=原始大小+原始大小/2(/2的結果向下取整),例如:原始大小是15,擴容後的大小爲:15+15/2=22

Vector的初始長度與ArrayList相同,但是Vector是成倍擴容(初始長度爲10,擴容之後長度爲20)

LinkedList

LinkedList的實現

LinkedList的實現原理是鏈表,它的鏈表結構是雙向的,可以從頭部或者尾部開始訪問,也可以同時訪問頭尾

  • LinkedList既可以作爲List,也可以作爲雙端隊列(擁有雙端隊列和棧的所有方法)
LinkedList的元素特點

鏈表的基本單元是節點,LinkedList的元素就存放在節點中

  • 節點的結構:三層結構
    • 頭部(Previous):存放上一個節點的地址信息
    • 中部:存放元素信息
    • 尾部(Next):存放下一個節點的地址信息
  • 元素的索引不確定
LinkedList的結構特點:
  • 內存空間不連續
  • 查找效率低
    • 訪問頭、尾元素最快
    • 訪問中部元素最慢
  • 插入效率高:新元素的頭部指向上一個元素的尾部,新元素的尾部指向下一個元素的頭部
LinkedList的常用API

LinkedList與ArrayList的方法類似,下面介紹一些LinkedList的特有方法

  • addFirst(E e):將指定元素添加到此列表的開頭
  • addList(E e):將指定元素添加到此列表的尾部
  • getFirst():返回此列表的第一個元素
  • getLast():返回此列表的最後一個元素
LinkedList的長度與擴容方式
  • 由於LinkedList是雙向鏈表,因此LinkedList沒有初始化大小,也沒有擴容機制

集合:Set

Set是什麼

Collection接口下的一個子接口,被稱爲散列表

Set的特點

  • 無序
    • 元素在Set中的順序與添加順序不同
    • 元素在Set中的順序由hashCode()決定
  • 不可重複
    • Set中的元素不可重複

Set的實現類/子接口

  • HashSet(實現類)
  • SortedSet(子接口)
    • TreeSet:SortedSet的實現類

Set的迭代方式

  • 迭代器
  • for-each

因爲set沒有索引,所以無法使用for()迭代

Set的API

Set的方法都是從Collection中繼承的,沒有特有方法

HashSet可以添加null值

HashSet實現不可重複添加元素的原理

  1. 通過待添加元素的hashCode()確定該元素在Set中的位置
  2. 如果該位置上已有元素,則通過待加入元素的equals()判斷兩者是否是相同元素
  3. 如果判斷結果爲true,則放棄添加
  4. 如果判斷結果不一致,則添加到相同位置
    • 在該位置形成一個鏈表,原來的元素向後推,新的元素排在前面

原理的核心步驟就是第1、2步,要求待添加的元素重寫hashCode()和equals(),且必須兩個方法都要重寫,否則會發生:

  • hashCode()重寫,equals()未重寫:相同位置存在相同元素
  • hashCode()未重寫,equals()重寫:不同位置存在相同元素

注意:若將一個元素添加到Set之後,修改了有關hashCode()計算的屬性值,會發生的事情有:

  • 可以再次添加:hashCode()發生了變化,計算的位置與之前不同
  • 無法刪除之前添加的元素:hashCode()發生了變化,計算的位置與之前不同

TreeSet

TreeSet是什麼

可以排序的散列表

  • 添加到TreeSet中的元素自動按照自然順序排序,被添加的元素需要實現Comparable接口
TreeSet的底層實現:二叉樹

雖然TreeSet實現了自然排序,但它本身仍然是無序的(本質是散列表)

TreeSet實現不可重複添加與排序的原理

不再使用hashCode()和equals(),而是實現Comparable或者Comparator接口

  • 待添加的元素已實現Comparable接口:通過compareTo()的返回值判斷兩個元素是否相同
  • 待添加的元素未實現Comparable接口:通過聲明Set對象時傳入一個Comparator比較器,添加元素時根據比較器的返回值判斷兩個元素是否相同

集合:Queue

Queue是什麼

Collection下的一個子接口,稱爲隊列

Queue的特點

一頭進,一頭出(先進先出,後進後出)

Queue的實現類/子接口

Deque:子接口

  • LinkedList:實現類

Queue的API

Queue是Collection的子接口,繼承了Collection的方法,下面介紹一些Queue有其特有的方法:

  • offer():添加元素
  • peek():返回隊列中的第一個元素,該元素不會從隊列中刪除
  • poll():返回隊列中的第一個元素,該元素會從隊列中刪除

Deque

Deque是什麼

雙端隊列

Deque的特點
  • 兩頭都可以進出
  • 可以作爲棧來使用,擁有棧的方法
Deque的API
  • Deque繼承了Queue的方法
  • Deque有其特有的方法:
    • offerFirst()
    • offerLast()
    • peekFirst()
    • peekLast()
    • pollFirst()
    • pollLast()
    • getFirst()
    • getLast()
  • 棧的方法:
    • push():將元素加入棧中(舊元素在後面,新元素在前面)
    • pop():返回棧中第一個元素(最後添加的元素),並將該元素從棧中刪除

隊列、雙端隊列、棧的區別

進出口 元素進出先後級
隊列 一個口進,一個口出 先進先出、後進後出
雙端隊列 兩個口都可以進出 無影響
只有一個口能進出 先進後出,後進先出

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