1.集合
Java四種集合:List、Queue、Set和Map
1.1.List:可重複
有序的Collection
ArrayList:
基於數組實現,增刪慢,查詢快,線程不安全
Vector:
基於數組實現,增刪慢,查詢快,線程安全
LinkedList:
基於雙向鏈實現,增刪快,查詢慢,線程不安全
1.2.Queue:隊列
ArrayBlockingQueue:
基於數組實現的有界阻塞隊列
LinkedBlockingQueue:
基於鏈表實現的有界阻塞隊列
PriorityBlockingQueue:
支持優先級排序的無阻塞隊列
DelayQueue:
支持延遲操作的無界阻塞隊列
SynchronousQueue:
用於線程同步的阻塞隊列
LinkedTransferQueue:
基於鏈表實現的無界阻塞隊列
LinkedBlockingDeque:
基於鏈表實現的雙向阻塞隊列
1.3.Set:不可重複
特性獨一無二,適合存儲無序且值不等的元素。
對象的相等性本質是對象內存地址計算出對象的HashCode值是否相同。
HashSet
HashMap實現,無序。
先判斷對象散列值是否相等,相等再通過equals比較,也相等,就視作同一元素。
TreeSet
二叉樹實現。
Interger和String基礎對象類型可以根據TreeSet默認排序存儲。
自定義類型必須實現Comparable接口和覆寫compareTo函數。
LinkedHashSet
繼承HashSet,HashMap實現數據結構,雙向鏈表記錄順序。
底層使用LinkedHashMap。
1.4.Map
HashMap
數組+鏈表,線程不安全。
如果要線程安全,可以使用Collections的synchronizedMap方法或者用ConcurrentHashMap數據結構。
HashMap數據結構:
內部是數組,數組的每個元素都是一個單向鏈表。鏈表中每個元素都是Entry。Entry包含四個屬性:key、value、hash值和指向下個鏈表的next。
HashMap常用參數:
capacity:當前數組容量,默認16。每次擴容是之前兩倍。
loadFactor:負載因子,默認0.75。
threhold:擴容閾值,值等於 capacity * loadFactor。
HashMap查找數據,根據Hash值可以快速定位到數組下標,但需要對鏈表順序遍歷才能找到,時間複雜度O(n)。
Java8對此進行了優化。當鏈表中的元素超過8個以後,會將鏈表轉化爲紅黑樹調高查詢效率,時間複雜度爲O(logN)。
ConcurrentHashMap
分段鎖實現,線程安全。
通過分段鎖思想實現併發操作。
有多個Segment組成(Segment數量就是鎖的併發度,默認16個),每個Segment繼承自ReentrantLock並單獨加鎖。所以每次加鎖操作鎖住的是一個Segment,保證了每個Segment安全,就實現了整個ConcurrentHashMap的安全。
每個Segment內部數據結構和HashMap相同。如上圖。
Java8種ConcurrentHashMap引入了紅黑樹。如下圖。
HashTable
線程安全。
遺留類。
同一時刻只能一個線程寫HashTable。
併發不如ConcurrentHashMap。
TreeMap
基於二叉樹。
同時實現了SortedMap保障元素順序存取,默認按照鍵值升序。也可以自定義排序比較器。
適用於實現排序的映射列表。鍵值必須實現Comparable接口或採用自定義比較器。
LinkedHashMap
HashMap子類,內部使用鏈表保存元素插入順序,當通過Iterator遍歷時,會按照元素插入順序訪問。
2.異常分類及處理
異常定義:
在方法正常執行時,通過拋異常退出方法。
在異常中封裝了錯誤信息和原因。
調用方可以根據該異常選擇處理或者繼續往下拋。
異常分類:
Throwable是所有Error和Exception父類。
常見Error有AWTError、ThreadDeath。
Exception可以分爲RuntimeException和CheckedExcption。
Error
出現通常因爲系統內部錯誤或者資源耗盡。
Java不能處理Error。
Excption
分爲運行異常與檢查異常
RuntimeException:指Java運行期間拋出的異常。可以被捕獲並處理。常見的有空指針異常、類強轉異常、數組越界異常。
CheckedException:指編譯階段對程序的檢查。要求對程序可能出現的異常通過try catch捕獲處理。常見的包括IO異常、SQL異常、ClassNotFound異常。
異常處理方式:
- 拋出異常
- throws用於方法定義上,可能拋出的異常
- throw 作用在方法內,表示明確拋出一個異常
- 捕獲異常
- 通過try catch捕獲和處理異常
3.反射機制
動態語言的概念
動態語言指在運行時可以改變結構的語言,比如新的屬性、方法的增加、刪除。
- JS、Ruby、Python屬於動態語言。
- C、C++屬於非動態語言。
- Java屬於半動態。
反射機制的概念
在程序運行期間,能對一個類都能獲取其屬性和方法,並能任意調用。
反射的應用
Java對象分爲編譯時類型與運行時類型。
編譯時指聲明對象的類型。
運行類型指爲對象賦值的類型。無法在編譯時獲取對象真實信息,只能通過反射獲取。這是反射的核心。
Java反射API
常用API
- Class類:用於獲取類的屬性、方法信息
- Filed類:用於獲取和設置類中屬性值
- Method類:用於獲取方法的描述信息和執行某個方法
- Constructor類:類的構造方法
反射步驟
1.獲取想要操作類的Class對象
2.調用Class對象類中的定義方法
3.使用反射API獲取並調用類屬性和方法信息
創建對象的兩個方法
使用Class對象的newInstance方法,要求對應類有無參構造方法
通過Class對象的Constructor對象的newInstance方法創建Class對應類實例
Method的invoke方法
動態調用類對象的方法。
步驟:獲取對象的Method,並調用Method的invoke方法。
4.註解
註解的概念
一個接口,Java提供設置程序中元素的關聯信息和元數據的方法。
標準元註解
@Target:
說明註解修飾對象的範圍。可用於包、類、類成員、方法參數和本地變量。
target類型。
@Retention:
定義註解保留級別,即被描述註解在什麼級別有效。
SOURCE:源文件有效
CLASS:Class文件中有效
RUNTIME:運行時有效
@Documented:
表示這個註解應該被javadoc工具記錄
@Inherited:
標記註解,表明被標註的類是被繼承的。
一個被@Inherited修飾的註解修飾一個類,表明這個註解將對該類的子類生效。
5.內部類
靜態內部類
定義在類內部的靜態類。
靜態內部類可以訪問外部類的靜態變量與方法。
靜態內部類中可以定義靜態變量、方法、構造方法。
靜態內部類通過 “外部類.靜態內部類” 方式調用。
成員內部類
定義在類內部的非靜態類。
成員內部類中不能定義靜態方法和變量(final修飾的)除外。因爲成員內部類時非靜態的。
局部內部類
定義在類方法中的類。
匿名內部類
匿名內部類指通過繼承一個類或者實現一個接口定義的類。
匿名內部類沒有class修飾,因爲匿名內部類直接使用new 生成對象引用。
6.泛型
本質是參數化類型,提供了編譯時的安全檢測。
泛型標記E、T、K、V、N、?
對泛型上限的限定 <? extends T>
對泛型下限的限定 <? super T>
泛型方法
指將方法參數類型定義爲泛型,以便接收不同類型參數。比如常見的main方法。
public static void main(String args[]) {
}
泛型類
指在類定義時在類定義了泛型,以便類使用時根據不同參數類型實例化。
public class Result<T> {
public T data;
}
7.序列化
Java對象在內存中創建,如果想持久化Java對象到磁盤,需要使用序列化。
除了持久化對象,還用在RPC調用和網絡傳輸中。
Java序列化API的使用
Java序列化API爲對象序列化提供了標準機制,有一下注意事項:
- 實現序列化,只要實現java.io.Serializable接口即可
- 序列化與反序列化要保持序列化的ID一致
- 序列化不保存靜態變量
- 需要序列化父類的變量,父類也要實現Serializable接口
- 使用Transient關鍵字可以防止變量被序列化。