轉載請說明出處!
四、Java集合(List、Set、Queue、Map)
Java集合體系是一個樹狀,如果按照類似OSI網絡模型來看的話,整個Java集合就是應用層,而底層的數組就是TCP/IP層。
而它也是全網各面試題中出現概率最高的。
對於集合,有幾個核心知識點是需要了解的:底層數據結構、擴容機制、效率、線程案例等。
整個Java集合大致分爲兩類:Collection接口與Map接口
下圖來源於網絡:
$4.1、 Collection接口:
繼承自Iteraor接口,因此其子類都擁有迭代器可以遍歷。collectin接口直接子類:List接口、Set接口、Queue接口。
List接口的子類有
-
ArrayList
1、擴容機制: 數組默認長度爲10,還有一個空的數組,當擴容時,如果數組長度比允許的最大長度大,則擴容至最大長度; 否則按照原數組的1.5倍擴容
/** 1.初始化時:默認容量爲10.
* Constructs an empty list with an initial capacity of ten.
*/
public ArrayList() {
//elementData爲Object[]:因此ArrayList底層是基於數組。
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
/***
*2. 往list中添加元素
* 在裏面要判斷list的容量,如果不夠就做擴容處理。
*/
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
/** 3. 擴容核心操作
*
*/
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;//舊長度
int newCapacity = oldCapacity + (oldCapacity >> 1);//在舊長度的基礎上加上一半,即1.5倍作爲新長度
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}
-
LinkedList
爲雙鏈表集合(實現了Deque接口), 由於ArryList是基於數組,它在內存上是一塊連續的地址,因此它查詢元素效率高。但是在刪除,插入時,得對數組進行移動,內存消耗大。而linkedList是基於雙鏈表,插入,刪除效率高。
-
Vector
與ArrayList一樣,底層是數組,但Vector是線程安全的,而ArrayList是非安全的。擴容大小也有區別:vector擴容至原數組的2倍,而ArrayList爲1.5倍
//Vector基本與ArrayList一樣:
//1、基於Object[]數組;
//2、默認容量爲10;
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
//capacityIncrement:當vector容量不夠,需要擴容時的增量值。
int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
capacityIncrement : oldCapacity);///當vector自動擴容的增量值小於或等於0時,新容量爲原容量的2倍。
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
elementData = Arrays.copyOf(elementData, newCapacity);
}
$4.2、Queue
隊列,是接口,繼承自Collection.先進先出原則(FIFO)–一端進,另一端出,可理解爲“管道”,BlockingQueue(阻塞式隊列),實現了Queue接口。常用於生產者消費者模式,共享數據隊列
$4.3、HashMap、HashTable、ConcurrentHashmap
下面是總結的結論,最好結合源碼來看,加深印象。畢竟這種知識點就好比考試,會用,但長時間不看,具體細節就又不記得了。
- HashMap允許存null。HashTable不允許;
- HashMap是非線程安全,HashTable是線程安全;
- HashMap與HashTable在計算Key的hash值獲取在數組中的位置時,HashMap採用按位與的方式,而HashTable採用取餘的方式,因此,HashMap與HashTable快。
-concurrenthashmap採用分段鎖,內部是segment數組,而hashtable也是鎖住整個map,因此前者效率更高。
五、反射、泛型
$5.1、泛型
對於它的使用可能再熟悉不過了,需要了解一點的是它有一個“類型擦除”的動作。所謂“類型擦除”,是指JVM在編譯的過程中,針對泛型類型,會根據所設的類型邊界來生成字節碼。如下:
//1.當未指定泛型類型邊界時,編譯器默認替換爲Object
private void setName(List<A> names){
.....
}
//在編譯時,會進行泛型參數類型替換:
private void setName(List<Object> names){}
//2.當有指定泛型類型父類時,編譯器會替換成泛型的父類
private void setName(List<A extends User> names{}
$5.2、反射
對於Java反射原理,重點是要了解下JVM的類加載機制、以及一些重要的類,方法等。
- 原理:簡單理解是:在JVM進行類加載時,會爲每個java文件的class生成一個Class對象,裏面包含了該類的一些基本信息(屬性,方法等),因此反射就是利用ClassLoader類加載器來提取目標Class對象,從而讀取裏面的Field屬性,Method方法。最後調用相應的API實現功能。
- 應用:可以動態的修改,達到靈活性。
- 爲了安全,Android9.0開始對@hide API進行一些反射的操作限制
六、final 、finaly、finalize
- final:關鍵字,由它修飾的類或方法,或變量不可繼承、複寫、修改
- finaly:與try catch一起用,最後執行
- finalize:爲Object方法,由JVM在GC時最後調用。
第二節完,下一篇講分享面試知識點【Java運行時數據區】、【Java垃圾回收機制】、【Java多線程】、【JVM類加載】