集合
目錄- 集合
- 1.集合的作用
- 2.集合類的分類
- Collection
- Collection方法分類
- 首先看一下添加操作與批量添加操作
- 集合洗掉資料
- ArrayList
- LinkedList
- ArrayList與LinkedList的區別
- HashMap
- LinkedHashMap
- TreeMap(二叉樹映射)
- HashSet(哈希集合)
- LInkedHashSet(鏈式哈希集合)
- TreeSet(二叉樹集合)
- 快速失敗(fail-fast)機制
- ConcurrentHashMap
- Collection方法分類
1.集合的作用
在java中我們可以使用陣列來保存多個物件,但是陣列的長度不可變,如果需要保存數量變化的資料,資料就不太合適了,為了保存數量不確定的資料,以及保存具有映射關系的資料(也被稱為關聯陣列),Java 提供了集合類,**集合類主要負責保存、盛裝其他資料,因此集合類也被稱為容器類**
2.集合類的分類
? java集合型別分為Collection和Map,它們是 Java 集合的根介面,這兩個介面又包含了一些子介面或實作類.
下圖為collection介面基本結構

下圖為Map介面基本結構

Collection
Collection方法分類
1.修改操作
| 方法名 | 作用 |
|---|---|
| add() | 添加單個資料,結果回傳布林值 |
| remove() | 洗掉單個資料,結果回傳布林值 |
2.查詢操作
| 方法名 | 作用 |
|---|---|
| size() | 回傳此集合中的元素數, |
| isEmpty() | 如果集合中不包含元素,則回傳 true , |
| contains() | 如果此集合包含指定的元素,則回傳true, |
| iterator() | 以正確的順序回傳該串列中的元素的迭代器, |
| toArray() | 正確的順序(從第一個到最后一個元素)回傳一個包含此串列中所有元素的陣列, |
| toArray(T[]) | 正確的順序回傳一個包含此串列中所有元素的陣列(從第一個到最后一個元素); 回傳的陣列的運行時型別是指定陣列的運行時型別, 如果串列適合指定的陣列,則回傳其中, 否則,將為指定陣列的運行時型別和此串列的大小分配一個新陣列, |
3.批量操作
| 方法名 | 作用 |
|---|---|
| containsAll(Collection<?>) | 如果此集合包含指定 集合中的所有元素,則回傳true, |
| addALl(Collection<? extends E>) | 批量添加 |
| removeALL(Collection<?>) | 批量洗掉 |
| removeIF(Predicate<? super E>) | 條件洗掉 |
| retainAll(Collection<?>) | 保留洗掉 |
| clear() | 清空集合 |
| stream() | 回傳一個順序Stream與此集合作為其來源, |
| parallelStream() | 回傳可能并行的Stream與此集合作為其來源, 該方法允許回傳順序流, |
首先看一下添加操作與批量添加操作
定義一個Fruit類,一個Apple類,以及一個Banana類
public class Fruit {
private String name;
public Fruit(String name) {
this.name = name;
}
@Override
public String toString() {
return name;
}
}
public class Apple extends Fruit{
public Apple(String name) {
super(name);
}
}
public class Banana extends Fruit{
public Banana(String name) {
super(name);
}
}
然后在主方法中寫一個集合,并向這個集合中國添加資料
public class Demo01 {
//首先看一下添加操作boolean add(),添加成功回傳True,失敗回傳False
public static void main(String[] args) {
List<Fruit> fruits = new ArrayList<>();
System.out.println(fruits.add(new Apple("紅富士蘋果")));
System.out.println(fruits.add(new Apple("青蘋果")));
System.out.println(fruits.add(new Fruit("蛇果")));
for (Fruit fruit : fruits) {
System.out.println(fruit);
}
}
}
輸出:
true
true
true
紅富士蘋果
青蘋果
蛇果
List
因為集合中定義的是Fruit,說明該集合只能存盤Fruit物件或者Fruit的子類物件
再看一下addall()方法,添加成功回傳true,否則回傳false
首先定義兩個集合,分別為蘋果集合和香蕉集合,并向集合中添加資料
public class Demo01 {
//首先看一下添加操作boolean add(),添加成功回傳True,失敗回傳False
public static void main(String[] args) {
List<Apple> apples = new ArrayList<>();
apples.add(new Apple("紅富士"));
apples.add(new Apple("青蘋果"));
apples.add(new Apple("蛇果"));
List<Banana> bananas = new ArrayList<>();
bananas.add(new Banana("帝皇蕉"));
apples.add(new Apple("海南香蕉"));
List<Fruit> fruits = new ArrayList<>();
System.out.println(fruits.addAll(apples));
System.out.println(fruits.addAll(bananas));
for (Fruit fruit : fruits) {
System.out.println(fruit);
}
}
}
集合洗掉資料
remove()洗掉單個資料,洗掉批量資料removeAll,洗掉符合添加條件的資料,removeIF,洗掉所有資料clear,即清空資料!
首先先看單個洗掉操作如何操作的
public class Demo02 {
public static void main(String[] args) {
//定義一個數字集合
List<Integer> numbers = new ArrayList<>();
numbers.add(1);
numbers.add(2);
numbers.add(3);
numbers.add(4);
numbers.add(5);
for (Integer number : numbers) {
System.out.print(number+" ");
}
System.out.println();
System.out.println("====分===割===線=====");
numbers.remove(2);
numbers.remove(3);
for (Integer number : numbers) {
System.out.print(number+" ");
}
}
}
輸出:
1 2 3 4 5
====分===割===線=====
1 2 4
可以看到,洗掉我們列印輸出的是1,2,4,可以看到他是先洗掉的下標為2的數字,然后,后面的數字往前進一個,集合中現在的長度為4,我們再取下標3的數,也就是最后一個數5,列印剩下的數就是1.2.4.
1.removeAll()方法
洗掉要洗掉資料中的集合,只要有符合的就執行洗掉操作
代碼示例:
public class Demo03 {
public static void main(String[] args) {
List<Integer> numbers = new ArrayList<>();
numbers.add(1);
numbers.add(2);
numbers.add(3);
numbers.add(4);
numbers.add(5);
List<Integer> num=new ArrayList<>();
num.add(2);
num.add(3);
num.add(5);
num.add(6);
numbers.removeAll(num);
for (Integer number : numbers) {
System.out.print(number+" ");
}
}
}
輸出:
1 4
2.retainAll()方法,指定要保留的資料集合
public class Demo04 {
public static void main(String[] args) {
List<Integer> numbers = new ArrayList<>();
numbers.add(1);
numbers.add(2);
numbers.add(3);
numbers.add(4);
numbers.add(5);
List<Integer> nums = new ArrayList<>();
nums.add(2);
nums.add(4);
nums.add(6);
numbers.retainAll(nums);
System.out.println(numbers);
}
}
輸出:
[2, 4]
可以看到,我們把要保留的數放在第二個集合中,當在需要操作的集合中能找到相應的資料,就將其保留!
3.removeIf()方法
public class Demo05 {
public static void main(String[] args) {
List<Integer> numbers = new ArrayList<>();
numbers.add(1);
numbers.add(2);
numbers.add(3);
numbers.add(4);
numbers.add(5);
//指定規則洗掉集合中的資料
//Predicate介面主要用來判斷一個引數是否符合要求
boolean result=numbers.removeIf(new Predicate<Integer>() {
@Override
public boolean test(Integer integer) {
//洗掉所有偶數
return integer%2==0;
}
});
//看是否洗掉成功
System.out.println(result);
//遍歷集合
for (Integer number : numbers) {
System.out.print(number+" ");
}
}
}
輸出:
true
1 3 5
4.clear()方法,清空集合
public class Demo06 {
public static void main(String[] args) {
List<Integer> numbers = new ArrayList<>();
numbers.add(1);
numbers.add(2);
numbers.add(3);
numbers.add(4);
numbers.add(5);
System.out.println(numbers);
numbers.clear();
System.out.println(numbers);
}
}
輸出:
[1, 2, 3, 4, 5]
[]
一些常見的其他方法
public class Demo07 {
public static void main(String[] args) {
List<Integer> numbers = new ArrayList<>();
numbers.add(1);
numbers.add(2);
numbers.add(3);
numbers.add(4);
numbers.add(5);
//集合的元素數
System.out.println(numbers.size());
//集合是否為空
System.out.println(numbers.isEmpty());
//集合中是否有元素2
System.out.println(numbers.contains(2));
}
}
輸出:
5
false
true
更多方法,具體的可以查看一下jdk的幫助檔案
ArrayList
? ArrayLisy不但擁有Collection中的方法,還擁有List中的所有方法
特點:
- 有序
- 可重復
- 資料可為null
優點:查詢快
缺點:增刪慢
1.ArrayList中的構造方法
? ArrayList中有三種構造方法
-
public ArrayList() 構造一個初始容量為十的空串列,
-
public ArrayList(Collection<? extends E> c) 構造一個包含指定集合的元素的串列,按照它們由集合的迭代器回傳的順序,
-
public ArrayList(int initialCapacity) 構造具有指定初始容量的空串列,
2.ArrayList中的常用方法
| 方法 | 作用 |
|---|---|
| add(E) | 添加元素 |
| set(int index,E element) | 覆寫指定位置的元素 |
| remove(int index) | 洗掉指定位置的元素 |
| get(int index) | 獲取指定位置的元素 |
| indexOf(Object o) | 獲取指定位置的索引 |
| iterator() | 獲取迭代器 |
| size() | 獲取集合大小 |
| isEmpty() | 判斷集合是否為空 |
| clear() | 清空集合 |
| stream() | 為集合創建流 |
LinkedList
? 擁有Collection里面的所有方法,List中的所有方法,Queue中的所有方法,Deque中的所有方法
1.LinkedList中的構造方法
-
LinkedList() 構造一個空串列,
-
LinkedList(Collection<? extends E> c) 構造一個包含指定集合的元素的串列,按照它們由集合的迭代器回傳的順序,
特點:
- 有序
- 可重復
- 可為null
優點:增刪塊
缺點:查詢慢
2.LinkedList的常用方法:
| 方法 | 作用 |
|---|---|
| getFirst | 回傳此串列中的第一個元素, |
| getLast | 回傳此串列中的最后一個元素, |
| removeFirst | 從此串列中洗掉并回傳第一個元素, |
| removeLast | 從此串列中洗掉并回傳最后一個元素, |
| add | 將指定的元素追加到此串列的末尾, |
| addFirst | 在該串列開頭插入指定的元素, |
| size | 回傳此串列中的元素數, |
| clear | 從串列中洗掉所有元素, 此呼叫回傳后,串列將為空, |
| contains | 如果此串列包含指定的元素,則回傳true` |
| listIterator | 從串列中的指定位置開始,回傳此串列中元素的串列迭代器(按適當的順序), |
| straem | 為集合創建流 |
ArrayList與LinkedList的區別
| ArrayLIst | LinkedList | |
|---|---|---|
| 資料結構 | 陣列 | 鏈表 |
| 查詢速度 | 快 | 慢 |
| 增刪速度 | 慢 | 快 |
| 記憶體空間 | 小 | 大 |
| 應用場景 | 查詢較多 | 增刪較多 |
HashMap
特點:
? 1.無序
? 2.key可以為null,哈希值為0
? 3.key不可以重復,重復的key,新值會覆寫舊值
優點:增刪改查快
缺點:無序
1.HashMap的構造方法:
| 方法 | 作用 |
|---|---|
| HashMap() | 構造一個空的 HashMap ,默認初始容量(16)和默認負載系數(0.75), |
| HashMap(int initialCapacity) | 構造一個空的 HashMap具有指定的初始容量和默認負載因子(0.75) |
| HashMap(int initialCapacity, float loadFactor) | 構造一個空的HashMap具有指定的初始容量和負載因子, |
| HashMap(Map<? extends K,? extends V> m) | HashMap(int initialCapacity, float loadFactor)構造一個新的 HashMap與指定的相同的映射 Map` |
2.HashMap中常用的方法:
| 方法名 | 作用 |
|---|---|
| size | 回傳此地圖中鍵值映射的數量, |
| isEmpty | 如果此地圖不包含鍵值映射,則回傳 true , |
| get | 回傳到指定鍵所映射的值,或null如果此映射包含該鍵的映射, |
| put | 將指定的值與此映射中的指定鍵相關聯, 如果地圖先前包含了該鍵的映射,則替換舊值, |
| remove | 從該地圖中洗掉指定鍵的映射(如果存在), |
| clear | 從這張地圖中洗掉所有的映射, 此呼叫回傳后,地圖將為空, |
| containsKey | 如果此映射包含指定鍵的映射,則回傳 true , |
| keySet | 回傳此地圖中包含的鍵的Set視圖, 該集合由地圖支持,因此對地圖的更改將反映在集合中,反之亦然, 如果在集合中的迭代正在進行中修改映射(除了通過迭代器自己的remov操作),迭代的結果是未定義的, 該組支持元件移除,即從映射中相應的映射,經由Iterator.remove,Set.remove,removeAll,retainAll和clear操作, 它不支持add或addAll操作, |
其中put與get方法在hashmap中用的最為頻繁,在實際開發中,hashmap多用于快取資料
LinkedHashMap
特點:
- 有序
- key唯一
- key為null
優點:有序
LInkedHashMap中常用的方法:
| 方法 | 作用 |
|---|---|
| put(K,V) | 添加元素 |
| get(Object) | 獲取指定鍵的元素 |
| containsKey(Object) | 查詢集合中是否包含指定鍵 |
| remove(Object) | 洗掉指定鍵的元素 |
| keyset() | 以set集合的形式回傳所有值 |
| size() | 獲取集合大小 |
| isEmpty() | 判斷集合是否為空 |
| clear() | 清空集合 |
TreeMap(二叉樹映射)
特點:
- 對key有序
- 無序
- key不可為null
- key唯一
優點:對key有序
缺點:無序
keymap的常用方法:
| 方法 | 作用 |
|---|---|
| put(K,V) | 添加元素 |
| get(Object) | 獲取指定鍵的元素 |
| containsKey(Object) | 查詢集合中是否包含指定鍵 |
| remove(Object) | 洗掉指定鍵的元素 |
| keyset() | 以set集合的形式回傳所有值 |
| size() | 獲取集合大小 |
| isEmpty() | 判斷集合是否為空 |
| clear() | 清空集合 |
| descendingMap | 倒序遍歷 |
HashSet(哈希集合)
特點:
- 無序
- 值唯一
- 值可為null
優點:增刪改查快
缺點:無序
1.HashSet的構造方法:
| 構造方法 | 說明 |
|---|---|
| HashSet() | 構造一個新的空集合; 背景HashMap實體具有默認初始容量(16)和負載因子 |
| HashSet(Collection<? extends E> c) | 構造一個包含指定集合中的元素的新集合, |
| HashSet(int initialCapacity) | 構造一個新的空集合; 背景HashMap實體具有指定的初始容量和默認負載因子(0.75) |
| HashSet(int initialCapacity, float loadFactor) | 構造一個新的空集合; 背景HashMap實體具有指定的初始容量和指定的負載因子, |
2.HashSet的常用方法
| 方法 | 作用 |
|---|---|
| add | 添加元素 |
| containsKey(Object) | 查詢集合中是否包含指定鍵 |
| remove(Object) | 洗掉指定鍵 |
| iteartor | 迭代器 |
| size() | 獲取集合大小 |
| isEmpty() | 判斷集合是否為空 |
| clear() | 清空集合 |
3.HashSet與HashMap的區別
| Hashmap | Hashset |
|---|---|
| key是key,value是value | 把key當成value使用,value再用統一的值填充 |
LInkedHashSet(鏈式哈希集合)
特點:
- 有序
- 值唯一
- 值可位null
優點:有序,增刪快
缺點:查詢慢
1.LinkedHashSet的常用方法
| 方法 | 作用 |
|---|---|
| add | 添加元素 |
| containsKey(Object) | 查詢集合中是否包含指定鍵 |
| remove(Object) | 洗掉指定鍵 |
| iteartor | 迭代器 |
| size() | 獲取集合大小 |
| isEmpty() | 判斷集合是否為空 |
| clear() | 清空集合 |
2.LinkedHahsSet與LinkedHashMap的區別
| LinkedHashSet | LinkedhashMap | |
|---|---|---|
| 存盤方式 | key是key,value是value | 把key當成value使用,value再用統一的值填充 |
| 排序方式 | 添加順序 訪問順序 | 添加順序 |
TreeSet(二叉樹集合)
特點:
- 無序
- 對值排序
- 值不可為null
- 值唯一
優點:對值排序
缺點:無序
1.TreeSet的常用方法:
| 方法 | 作用 |
|---|---|
| add | 添加元素 |
| containsKey(Object) | 查詢集合中是否包含指定鍵 |
| remove(Object) | 洗掉指定鍵 |
| iteartor | 迭代器 |
| size() | 獲取集合大小 |
| isEmpty() | 判斷集合是否為空 |
| clear() | 清空集合 |
| descendingIterator | 倒敘遍歷 |
2.HashSet與TreeSet的對比
| HashSet | LInkEdHashSet | Treeset |
|---|---|---|
| 添加、查詢快 | 添加、修改、洗掉快;有序 | 只有需要對元素進行排序時使用 |
快速失敗(fail-fast)機制
? 一種容器保護機制,防止多個執行緒并發修改同一個容器的內容,如果發生了并發修改的情況就會觸發快速失敗機制,也就是拋出ConcurrentModificationException(并發修改例外)
eg:
當你在迭代遍歷某個容器的程序中國,另一個執行緒介入其中,并且插入或洗掉此容器中的某個元素,那么就會出現問題,單執行緒和多執行緒同理!
我們看一下代碼:
可以看出,我們在下面迭代遍歷的同時,進行插入操作
import java.util.ArrayList;
import java.util.Iterator;
public class FailFast {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
Iterator<String> iterator = list.iterator();
list.add("1");
list.add("2");
while (iterator.hasNext()){
System.out.println(iterator.next());}
}
}
輸出:
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:911)
at java.util.ArrayList$Itr.next(ArrayList.java:861)
at com.gather.map.FailFast.main(FailFast.java:14)
那么為了防止這類問題出現,java容器類采用了快速失敗機制,主要用與監視容器的變化
那么如何避免上述問題:我們只需要采用執行緒安全的容器即可
| 執行緒不安全 | 執行緒安全 |
|---|---|
| ArrayLIst | CopyOnWriteArrayList |
| LinkedList | |
| HashMap | ConcurrentHashMap |
| LinkedHashMap | |
| TreeMap | |
| HashSet | CopyOnWriteArraySet |
| LinkedHashSet | |
| TreeSet |
代碼示例:
import java.util.Iterator;
import java.util.concurrent.CopyOnWriteArrayList;
public class FailFast2 {
public static void main(String[] args) {
//創建一個支持并發的集合
CopyOnWriteArrayList list=new CopyOnWriteArrayList();
//另一個執行緒修改器
new Thread(new Runnable() {
@Override
public void run() {
list.add("一個簡單的多執行緒");
list.add("lingstar");
}
}).start();
//獲取迭代器
Iterator<String> iterator = list.iterator();
//遍歷集合
while (iterator.hasNext()){
//獲取元素
System.out.println(iterator.next());
}
}
}
輸出:
一個簡單的多執行緒
lingstar
ConcurrentHashMap
特點:
- 無序
- key唯一
- key、value不可為null
- 執行緒安全
優點:增刪改查快
缺點:無序
1.ConcurrentHashMap的常用方法
| 方法 | 作用 |
|---|---|
| put | 添加元素 |
| get(Object) | 獲取指定鍵的元素 |
| containsKey(Object) | 查詢集合中是否包含指定鍵 |
| remove(Object) | 洗掉指定鍵 |
| keySet() | 以set集合的形式回傳所有鍵 |
| size() | 獲取集合大小 |
| isEmpty() | 判斷集合是否為空 |
| clear() | 清空集合 |
2.ConcurrentHashMap與HashMap的區別
| hashMap | ConcurrentHahsmap | |
|---|---|---|
| 執行緒是否安全 | 不安全 | 安全 |
| 擴容 | 單執行緒擴容 | 多執行緒協同擴容 |
| 統計元素個數 | size | baseCount+CounterCell() |
| key,value能否為null | 能 | 不能 |
本文來自博客園,作者:星余明,轉載請注明原文鏈接:https://www.cnblogs.com/lingstar/p/16499093.html
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/499847.html
標籤:其他
上一篇:如何定義一個泛型類呢?
下一篇:如何定義一個泛型介面呢?
