這篇文章記錄了Collection集合,List集合,Set集合
在文章第七點總結了兩大系列集合的五種實作類的區別,有需要的小伙伴可以直接去查看
一、什么是集合
集合是Java中存盤物件資料的一種容器
二、集合有什么特點
- 大小不固定,型別也可以不固定(通常需要泛型約束)
- 集合只能存盤參考資料型別
- 集合適合對容器中的元素進行增刪操作
三、體系結構

Collection單列集合,每個元素(資料)只包含一個值,
Map雙列集合,每個元素包含兩個值(鍵值對),
四、Collection
1. 什么是Collection
官方的解釋:
- Collection是集合層次結構中的根介面, 集合表示一組物件,稱為其元素 , 有些集合允許重復元素而其他集合則不允許, 有些是有序的,有些是無序的,
- JDK不提供此介面(Collection)的任何直接實作:它提供了更具體的子介面的實作,如 Set 和 List
- 此介面通常用于傳遞集合并在需要最大通用性的情況下對其進行操作,
說的通俗一點就是:
- Collection是根介面,所有集合都來自Collection
- jdk不提供該介面實作類物件,但提供了更具體的實作類
- 就好比父類和子類,你可以用父類物件接收一個子類的實體化物件
???例如:Father f = new Sun(); // Sun類繼承了Father類
2. Collection的體系結構

3. 常用方法
|
方法名稱 |
說明 |
|
|
把給定的物件添加到當前集合中 |
|
|
清空集合中所有的元素 |
|
|
把給定的物件在當前集合中出現的第一個位置洗掉,如果洗掉失敗回傳false |
|
|
判斷當前集合中是否包含給定的物件 |
|
|
判斷當前集合是否為空 |
|
|
回傳集合中元素的個數, |
|
|
把集合中的元素,存盤到陣列中 |
4. 集合的遍歷方式
4.1 迭代器
Iterator是集合專用的迭代方法,只能集合呼叫
Iterator中常用方法
- next():回傳迭代中的下一個元素
- hasNext():如果迭代具有更多元素,則回傳true
Collection<Integer> list = new ArrayList<>();
Iterator<Integer> iterator = list.iterator();
while(iterator.hasNext()){
Integer next = iterator.next();
System.out.println(next);
}
注意事項:
- 迭代器只能使用一次
- next()移動指標到下一個元素,如果沒有拋例外
- hasNext()檢查下一個元素是否為空,但不移動指標
- 迭代器迭代元素越界出現:NoSuchElementException
4.2 普通for
只適用于List系列集合,因為他有序
通過呼叫集合的get方法,根據索引取值
4.3 增強for
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(3);
list.add(2);
//增強for
for (int i : list) {
if (i == 3) {
i = 5;//增強for中如果對取出的這個元素修改,將不會對集合產生影響
}
System.out.println(i);
}
4.4 Lambda迭代
// 使用lambda運算式集合的迭代
colStr.forEach(new Consumer() {
@Override public void accept(String s) {
System.out.println(s);
}
});
// 簡化寫法
System.out.println("-------------------------");
colStr.forEach(s-> System.out.println(s));
System.out.println("-------------------------");
// 再次簡化
colStr.forEach(System.out::println);
五、List
Collection的子介面
1. 特點
有序,有索引(是獨有的),可重復,可存盤null值,此實作不同步,執行緒不安全
存盤和取出順序一致
2. 特有方法
|
方法名稱 |
說明 |
注意 |
|
|
將給定的元素插入到指定位置 |
索引不能越界,否則報錯
|
|
|
回傳該索引位置的元素,沒找到回傳-1 |
|
|
|
對給定位置的元素進行替換 |
|
|
|
洗掉指定位置的元素 |
|
|
|
回傳特定元素在集合中最后一次出現的位置 |
沒找到回傳-1 |
|
|
回傳特定元素在集合中第一次出現的位置 |
|
|
|
List集合特有的迭代器 |
|
|
|
根據開始索引和結束索引(左閉右開)回傳一個新的集合,該集合是原集合的子集 |
|
ListIterator叫做串列迭代器,將在第3.2解釋
3. 迭代方式
和Collection一樣的:迭代器、增強for、Lambda運算式
List獨有的:listIterator、普通for(因為有索引)
3.1 并發修改例外
迭代器在迭代集合,但是集合本身被修改,換而言之:就是在同一時刻只能有一個物件來操作集合,否則就會出現并發修改例外
下面兩種情況會出現并發修改例外
??1. 迭代器和集合方法都會對集合進行操作
List<String> list = new ArrayList<>();
list.add("java");
list.add("css");
list.add("python");
while(stringListIterator.hasNext()){
String ele = stringListIterator.next();
if("css".equals(ele)){
stringListIterator.remove();//允許
//list.remove("css");// 不允許 出現 ConcurrentModificationException
}
System.out.println(ele);
}
??2. 增強for本身也是一個Iterator迭代器,同樣不能使用
List<String> list = new ArrayList<>();
list.add("java");
list.add("css");
list.add("python");
for (String s : list) {
if("css".equals(s)){
list.remove("css");//不允許,并發修改例外
}
System.out.println(s);
}
不會出現并發修改例外
List<String> list = new ArrayList<>();
list.add("java");
list.add("css");
list.add("python");
for (int i= 0; i < list.size();i++){
String ele = list.get(i);
if("css".equals(ele)){
list.remove("css");// 允許
}
}
System.out.println(list);
并發修改例外總結
- 同一時間只能有一個物件操作集合
- 使用迭代器要保證集合不在改變
- 出現例外的原因:
- 迭代器在進行遍歷程序中,如果對陣列進行操作,會導致迭代器的實際修改值和集合的預期修改值不對應,就會出例外
- 迭代器是一次性的,如果對集合進行操作,沒有及時更新迭代器就會引發例外
- 如何解決并發修改例外
- 使用普通for:用索引取值,同一時間只有一個物件對集合操作
- 使用串列迭代器ListIterator
3.2 ListIterator
- ListIterator的兩個遍歷方法
|
|
從前往后遍歷 |
|
|
從后往前遍歷,前提是先得從前往后遍歷一遍,讓迭代器指標走到末尾 |
List<String> list = new ArrayList<>();
ListIterator<String> listIterator = list.listIterator();
- ListIterator和Iterator的區別
- ListIterator每進行一次迭代都會把實際修改值重新賦值給預期修改值,但是Iterator不行
- ListIterator是List集合特有的,Iterator是所有集合都有的
4. 兩個主要的介面實作類
4.1 特點
List的介面實作類,List的特點就是ArrayList、LinkedList的特點
4.2 ArrayList
- 使用的是陣列,默認容量為10
- 一旦陣列滿了,則創建一個新的陣列,新陣列的容量是原陣列的容量的1.5倍,并且會將原陣列內容復制到新陣列
- 因為底層是陣列,具有陣列的特點:查詢快,增刪慢

- 可存盤null值
- 此實作不同步,執行緒不安全
4.3 LinkedList
- 底層是雙向鏈表
- 具有鏈表的特點:查詢慢,增刪快
- 此實作不同步,執行緒不安全
- 常用方法



六、Set
1. 特點
元素唯一,無序,沒有索引,最多只能一個null
三個主要的介面實作類
HashSet、TreeSet、LinkedHashSet
2. HashSet
2.1 特點:無序(HashSet只是不保證有序,并不是保證無序),不重復,無索引,此實作不同步
2.2 底層實作:哈希表,是一種對增刪改查性能都較好的結構
-
哈希表組成
??jdk8之前:陣列+鏈表
??jdk8之后:陣列+鏈表+紅黑樹
-
哈希值
- 哈希值是jdk根據物件計算得出的記憶體地址,根據某個規則算出來的int型別數值
- 物件可以通過呼叫hashCode()回傳物件的哈希值
- 同一個物件的哈希值是相同的
- 在默認情況下,不同物件的哈希值是相同的(除非重寫了hashCode方法)
2.3 HashSet底層存盤結構

- 當呼叫無參hashSet構造器,會默認創建一個長度為16的陣列
- 添加元素,元素哈希值和陣列長度根據哈希演算法計算元素存盤位置
- 判斷該位置是否為空,如果為空直接存陣列
- 如果位置不為空,判斷哈希值,如果不同直接存鏈表
- 如果哈希值相同,判斷equals是否相同,如果不同直接存鏈表
- 如果都相同就不存
-
版本差異
??jdk8之前:新元素占據舊元素位置,指向舊元素,當元素鏈表掛載元素過多會造成查詢性能下降,
??jdk8之后:新元素掛在舊元素下面,當鏈表長度超過8時,自動將鏈表轉換為紅黑樹,進一步提高性能
-
元素去重原理(面試會問)
- 判斷hashcode值是否相同,如果不同,則不重復
- 如果hashcode相同,呼叫equals比較,如果為true,則重復,否則掛在元素下邊
- 在類中可以重寫equals和hashCode方法,進行自定義特征比較
//假設這是一個學生類,有name和age兩個屬性
//重寫equals和hashCode方法
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
Student student = (Student) o;
return Objects.equals(name, student.name); //例如這里
//可以自定義比較物件中的哪一個特征,比如就比較名字是否一樣,不在乎年齡是否一樣
}
@Override
public int hashCode() {
return Objects.hash(name); //例如這里
//可以自定義要進行計算哈希的物件,比如只想判斷名字哈希是否一樣,
//名字哈希一樣就認為這倆物件哈希一樣,不在乎年齡哈希是否一樣
}
3. TreeSet
3.1 特點:默認自然升序排序,不重復,無索引,可排序
3.2 排序方式
-
自然排序
- 必須實作Comparable介面,重寫compareTo,定義排序規則
- Integer、String這些類默認已經實作了Comparable介面,可以直接去呼叫
- 英文按照字母順序,中文按照Unicode碼大小升序
-
比較器排序(定制排序):
??創建集合時候就實作Comparator介面
??如何理解排序呢
??首先要知道這倆的區別
- Comparable是比較介面,Comparator是比較器
- 實作比較介面(Comparable)就意味著該類支持排序
- 實作比較器(Comparator)就意味著該集合要使用自定義的比較方法
- Comparable相當于“內部比較器”,而Comparator相當于“外部比較器”,
??通俗一點,用人話說就是:
- 使用Comparable就是支持排序,意思是我這個類支持排序
- 使用了Comparator就是比較器,不管類支不支持,想要排序就得按照我比較器的規矩排序
LinkedHashSet
- 特點:有序(存入和取出順序一樣),不重復,無索引
- 底層存盤結構:哈希表和雙向鏈表,雙向鏈表用來記錄存盤的順序
七、所有集合最全面總結
| List | Set | ||||
| 實作類 | ArrayList | LinkedList | HashSet | TreeSet | LinkedHashSet |
| 順序 | 有序 | 有序 | 無序 | 有序 | 有序 |
| 重復 | 可重復 | 可重復 | 不可重復 | 不可重復 | 不可重復 |
| 空值 | 允許多個null | 允許多個null | 最多一個null | 最多一個null | 最多一個null |
| 索引 | 有索引 | 有索引 | 無索引 | 無索引 | 無索引 |
| 排序 | 存入順序就是取出順序 | 存入順序就是取出順序 | 不能排序 | 自然排序和比較器排序 | 存入順序就是取出順序 |
| 特點 | 查詢快 | 增刪首尾操作快 | 增刪改查都快的五邊形戰士 | 唯一可以自定義排序 | 增刪改查都快的五邊形戰士 |
| 底層 | 陣列 | 鏈表 | 哈希表 | 紅黑樹 | 哈希表和雙鏈表 |
| 凡是帶list都可重復、有索引 | 凡是帶set都不可重復、無索引 | ||||
| 凡是帶hash都是五邊形戰士,增刪改查都快 | 只有HashSet無序、不能排序 | ||||
八、集合工具類Collections
Collections 不屬于集合,是用來操作集合的工具類

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/547376.html
標籤:其他
上一篇:JAVA -01(簡單知識介紹)
