集合: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實現不可重複添加元素的原理
- 通過待添加元素的hashCode()確定該元素在Set中的位置
- 如果該位置上已有元素,則通過待加入元素的equals()判斷兩者是否是相同元素
- 如果判斷結果爲true,則放棄添加
- 如果判斷結果不一致,則添加到相同位置
- 在該位置形成一個鏈表,原來的元素向後推,新的元素排在前面
原理的核心步驟就是第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():返回棧中第一個元素(最後添加的元素),並將該元素從棧中刪除
隊列、雙端隊列、棧的區別
進出口 | 元素進出先後級 | |
---|---|---|
隊列 | 一個口進,一個口出 | 先進先出、後進後出 |
雙端隊列 | 兩個口都可以進出 | 無影響 |
棧 | 只有一個口能進出 | 先進後出,後進先出 |