collection大致介紹
Collection是集合層次結構中的根介面,
集合表示一組物件,有些集合允許重復元素,有些則不允許,有些是有序的,有些是無序的,
JDK沒有提供此介面的任何直接實作:它提供了更具體的子介面(如Set和List)的實作,
這個介面通常用于在需要最大通用性的地方傳遞和操作集合 包或多集(可能包含重復元素的無序集合)應該直接實作此介面,
Collection的大致結構體系:

其中常用的有:
List, ArrayList, LinkedList, Vector.
Set, HashSet, TreeSet, LinkedHashList
下文中會挨個看看大致的特性和部分原始碼.
Collection介面提供的功能:
1.添加:
// 添加一個元素.
boolean add(E e);
// 添加多個元素.
boolean addAll(Collection<? extends E> c);
2.洗掉:
// 洗掉一個元素.
boolean remove(Object o);
// 洗掉多個元素.
boolean removeAll(Collection<?> c);
// 清空集合
void clear();
3.判斷:
// 判斷是否為空,為空則回傳true
boolean isEmpty();
// 判斷是否包含元素
boolean contains(Object o);
// 是否全部包含指定元素
boolean containsAll(Collection<?> c);
// 判斷是否相等
boolean equals(Object o);
4.獲取:
// 繼承自Iterable<E>的迭代器, 用于遍歷所有元素
Iterator<E> iterator();
// 回傳集合的哈希碼
int hashCode();
5.長度:
//回傳此集合中的元素數目,如果數量超過int最大值就回傳int最大值
int size();
6.交集:
// 移除未包含在c中的所有元素.回傳值表示是否發生過移除操作
boolean retainAll(Collection<?> c);
7. 轉換
// 轉換為陣列
Object[] toArray();
// 轉換為特定型別的陣列
<T> T[] toArray(T[] a);
8. 流操作
// 串行流操作
default Stream<E> stream()
// 并行流操作
default Stream<E> parallelStream()
Iterator 大致介紹
Iterator(迭代器),用于以迭代的方式遍歷集合.
是一種模式、詳細可見迭代器設計模式.
可以使得序列型別的資料結構的遍歷行為與被遍歷的物件分離,即我們無需關心該序列的底層結構是什么樣子的,
只要拿到這個物件,使用迭代器就可以遍歷這個物件的內部,
一般是在集合內提供私有的實作方法,用于迭代集合類.
Tterator提供的介面:
// 是否有下一個元素
boolean hasNext();
// 回傳迭代中的下一個元素,
E next();
/**
* 從基礎集合中移除此迭代器回傳的最后一個元素(可選操作),
* 此方法在每次呼叫next時只能呼叫一次,
* 如果沒有繼承方法,默認會拋出 UnsupportedOperationException("remove") 例外
*/
default void remove()
// 提供函式式編程
default void forEachRemaining(Consumer<? super E> action)
Fail-Fast 機制
概念
fail-fast機制,即快速失敗機制,是java集合中的一種錯誤檢測機制,
當在迭代集合的程序中集合的結構發生改變(對集合結構的操作會記錄操作次數),就會發生fail-fast,拋出ConcurrentModificationException例外,
在面對并發修改時,迭代器會快速而干凈地失敗,而不是在將來某個不確定的時間冒任意的、不確定的行為的風險,
fail-fast機制并不保證在不同步的修改下一定拋出例外,它只是盡最大努力去發現并拋出例外,迭代器的快速故障行為應該只用于檢測bug,
原始碼中 如何實作的
以為迭代ArrayList為例:
fail-fast的實作依賴于ArrayList<E>的父類AbstractList<E>,在AbstractList<E>中,有一個protected transient int modCount = 0;的成員變數來記錄集合被操作的次數.
在ArrayList中, add,remove,replace等操作都會有modCount++來記錄集合的被操作次數.
在進行迭代的程序中呼叫每個方法前對modCount和開始迭代時記錄的expectedModCount進行比對. 如果不一樣就快速拋出ConcurrentModificationException錯誤,防止因為意外產生錯誤.
// 呼叫迭代器
public Iterator<E> iterator() {
return new Itr();
}
// ArrayList中自己實作的迭代器部分代碼
private class Itr implements Iterator<E> {
int cursor; // index of next element to return
int lastRet = -1; // index of last element returned; -1 if no such
// 初始化時記錄當前的運算元
int expectedModCount = modCount;
......
......
@SuppressWarnings("unchecked")
public E next() {
checkForComodification();
......
......
}
// 比對運算元的值是否有差異
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}
值傳遞和參考傳遞, 深復制和淺復制
值傳遞和參考傳遞概念:
- 值傳遞(pass by value)是指在呼叫函式時將實際引數復制一份傳遞到函式中,這樣在函式中如果對引數進行修改,將不會影響到實際引數.
- 參考傳遞(pass by reference)是指在呼叫函式時將實際引數的地址直接傳遞到函式中,那么在函式中對引數所進行的修改,將影響到實際引數.
在java中, 基本型別變數傳遞的是值的副本, 相當于把自己賦值一份傳遞,即使自己的副本變了,自己也不會改變.
而物件型變數, java傳遞的是參考的副本(復制指向地址的指標),而不是自己實際值的副本.所以傳遞后的物件被改變的話, 之前的物件也會同步改變.因為指向的記憶體中的實際物件被改變了.
P.S.在這里, String型別有些特殊, 一方面, String屬于物件, 傳遞的是參考的副本, 另一方面,String的特殊結構(字串常量都存在堆記憶體中的字串常量池中), 且String不可更改, 只能創建新的.所以String傳遞后更改也不會影響之前的.
深復制和淺復制概念:
- 淺拷貝:對基本資料型別進行值傳遞,對參考資料型別進行參考傳遞般的拷貝,此為淺拷貝,
- 深拷貝:對基本資料型別進行值傳遞,對參考資料型別,創建一個新的物件,并復制其內容,此為深拷貝,
Collection中參考的System.arraycopy()就屬于淺拷貝.
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/179241.html
標籤:Java
上一篇:用非常硬核的JAVA序列化手段實作物件流的持久化保存
下一篇:java OA辦公系統原始碼 Springboot Activiti作業流 vue.js 前后分離 集成代碼生成器
