《offcer來了》第二章學習筆記

1.集合

Java四種集合:List、Queue、Set和Map

v2-488327163fe94274b32055d2e1fdaf4f_r

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。

v2-7ec7858332a7c91a093d4d574dc84ada_r

HashMap常用參數:

capacity:當前數組容量,默認16。每次擴容是之前兩倍。

loadFactor:負載因子,默認0.75。

threhold:擴容閾值,值等於 capacity * loadFactor。

HashMap查找數據,根據Hash值可以快速定位到數組下標,但需要對鏈表順序遍歷才能找到,時間複雜度O(n)。

Java8對此進行了優化。當鏈表中的元素超過8個以後,會將鏈表轉化爲紅黑樹調高查詢效率,時間複雜度爲O(logN)。

v2-a5d095aa8d9a0c0376e4e636ea58e294_r
ConcurrentHashMap

分段鎖實現,線程安全。

通過分段鎖思想實現併發操作。

有多個Segment組成(Segment數量就是鎖的併發度,默認16個),每個Segment繼承自ReentrantLock並單獨加鎖。所以每次加鎖操作鎖住的是一個Segment,保證了每個Segment安全,就實現了整個ConcurrentHashMap的安全。

v2-64abd064a58d5adfee4c38512c34337f_r

每個Segment內部數據結構和HashMap相同。如上圖。

Java8種ConcurrentHashMap引入了紅黑樹。如下圖。

v2-1fcd7f3dacf78afc4d228aaf19d6fa89_r
HashTable

線程安全。

遺留類。

同一時刻只能一個線程寫HashTable。

併發不如ConcurrentHashMap。

TreeMap

基於二叉樹。

同時實現了SortedMap保障元素順序存取,默認按照鍵值升序。也可以自定義排序比較器。

適用於實現排序的映射列表。鍵值必須實現Comparable接口或採用自定義比較器。

LinkedHashMap

HashMap子類,內部使用鏈表保存元素插入順序,當通過Iterator遍歷時,會按照元素插入順序訪問。

2.異常分類及處理

異常定義:

在方法正常執行時,通過拋異常退出方法。

在異常中封裝了錯誤信息和原因。

調用方可以根據該異常選擇處理或者繼續往下拋。

異常分類:

Throwable是所有Error和Exception父類。

常見Error有AWTError、ThreadDeath。

Exception可以分爲RuntimeException和CheckedExcption。

v2-5b8233e8f80917cdd50e0a365e9a82f1_r

Error

出現通常因爲系統內部錯誤或者資源耗盡。

Java不能處理Error。

Excption

分爲運行異常與檢查異常

RuntimeException:指Java運行期間拋出的異常。可以被捕獲並處理。常見的有空指針異常、類強轉異常、數組越界異常。

CheckedException:指編譯階段對程序的檢查。要求對程序可能出現的異常通過try catch捕獲處理。常見的包括IO異常、SQL異常、ClassNotFound異常。

v2-c7127afd0bb7b5f124fa0358ca73e365_r

異常處理方式:

  • 拋出異常
    • 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類型。

v2-c174d8014c7b118f7be63f0b5d1c23a1_r

@Retention:

定義註解保留級別,即被描述註解在什麼級別有效。

SOURCE:源文件有效

CLASS:Class文件中有效

RUNTIME:運行時有效

@Documented:

表示這個註解應該被javadoc工具記錄

@Inherited:

標記註解,表明被標註的類是被繼承的。

一個被@Inherited修飾的註解修飾一個類,表明這個註解將對該類的子類生效。

5.內部類

靜態內部類

定義在類內部的靜態類。

靜態內部類可以訪問外部類的靜態變量與方法。

靜態內部類中可以定義靜態變量、方法、構造方法。

靜態內部類通過 “外部類.靜態內部類” 方式調用。

成員內部類

定義在類內部的非靜態類。

成員內部類中不能定義靜態方法和變量(final修飾的)除外。因爲成員內部類時非靜態的。

局部內部類

定義在類方法中的類。

匿名內部類

匿名內部類指通過繼承一個類或者實現一個接口定義的類。

匿名內部類沒有class修飾,因爲匿名內部類直接使用new 生成對象引用。

6.泛型

本質是參數化類型,提供了編譯時的安全檢測。

泛型標記E、T、K、V、N、?

v2-dd3068731eb96cb609342deb1df9394d_r

對泛型上限的限定 <? 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關鍵字可以防止變量被序列化。
v2-6991fb1e1f4c167cf81d773c5411cf6c_r

序列化與反序列化

v2-5ac0216669ca088e03eca1fbde334cc1_r

8.總結

image-20200422001857406

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章