異常、泛型和集合框架 異常 泛型 泛型類 泛型接口 泛型方法、通配符和上下限 泛型支持的類型 集合框架 集合體系結構 Collection集合 Collection的遍歷方式 認識并發修改異常問題 List集合 List集合的特有方法 ArrayList底層原理 LinkedList的底層原理 LinkedList的應用場景
異常
Java的異常體系
Java.lang.Throwable Error:代表的系統級別錯誤(屬于嚴重問題),也就是說系統一旦出現問題,sun公司會把這些問題封裝為Error對象給出來。 Exception:叫異常:它代表的才是我們程序可能出現的問題,所以通常會用Exception以及它的孩子來封裝程序出現的問題。 運行時異常:RuntimeException及其子類,編譯階段不會出現錯誤提醒,運行時出現的異常 編譯時異常:“其他異常…” 編譯階段就會出現錯誤提醒的。 拋出異常(throws) 在方法上使用throws關鍵字,可以將方法內部出現的異常拋出去給調用者處理。
方法 throws 異常1 ,異常2 ,異常3 . . { …
}
try {
} catch ( 異常類型1 變量) {
} catch ( 異常類型2 變量) {
} . . .
異常的作用
異常使用來定位程序bug的關鍵信息。 可以作為方法內部的一種特殊返回值,以便通知上層調用者,方法的執行問題。
自定義異常
Java無法為這個世界上全部的問題都提供異常類來代表, 如果企業自己的某種問題,想通過異常來表示,以便用異常來管理該問題,那就需要自己來定義異常類了。 自定義運行時異常 定義一個異常繼承RuntimeException。 重寫構造器。 通過 throw new 異常類(xxx)來創建異常對象拋出 特點:編譯階段不報錯,運行時才可能出現,提醒不屬于激進型。 自定義編譯時異常 定義一個異常繼承Exception。 重寫構造器。 通過 throw new 異常類(xxx)創建異常對象并拋出。 特點:編譯階段就報錯,提醒比較激進。
異常的處理方案
方案一:底層異常層層往上拋出,最外層捕獲異常,記錄下異常信息,并響應適合用戶觀看的信息進行提示。 方案二:最外層捕獲異常后,嘗試重新修復。
異常的兩種處理方式
方法 throws 異常1 ,異常2 ,異常3 ..{…
}
try {
} catch ( 異常類型1 變量) { } catch ( 異常類型2 變量) {
} . . .
泛型
定義類、接口、方法是,同時聲明了一個或多個類型變量(如:)
public class ArrayList < E > { . . .
}
作用:泛型提供了在編譯階段約束所能操作的數據類型,并自動進行檢查的能力. 這樣可以避免強制類型轉換,及其可能出現的異常。 泛型的本質:把具體的數據類型作為參數給類型變量。
泛型類
修飾符 class 類名< 類型變量,類型變量,…> {
}
類型變量建議用大寫的英文字母,常用的有:E、T、K、V 等
泛型接口
修飾符 interface 接口名< 類型變量,類型變量,…> {
}
泛型方法、通配符和上下限
修飾符 < 類型變量,類型變量,…> 返回值類型 方法名( 形參列表) { }
通配符 就是 “?”,可以在 “使用泛型” 的時候代表一切類型; E T K V 是在定義泛型的時候使用。 泛型的上下限: 泛型上限:? extends Car: ? 能接收的必須是Car或者其子類 。 泛型下限:? super Car:? 能接收的必須是Car或者其父類。
泛型支持的類型
泛型不支持基本數據類型,只能支持對象類型(引用數據類型)。
集合框架
集合是一種容器,用來裝數據的,類似于數組,但集合的大小可變,開發中也非常常用。
集合體系結構
Collection 代表單列集合,每個元素(數據)只包括一個值。 Map 代表雙列集合,每個元素包含兩個值(鍵值對)。
Collection
Collection Collection集合特點 List系列集合:添加的元素是有序、可重復、有索引。 ArrayList、LinekdList:有序、可重復、無索引。 Set系列集合:添加的元素是無序、不重復、無索引。 HashSet:無序、不重復、無索引。 LinkedHashSet:有序、不重復、無索引。 TreeSet:按照大小默認升序排序、不重復、無索引。
Collection集合
Collection是單列集合的祖宗,它規定的方法(功能)是全部單列集合都會繼承的。
方法名 說明 public boolean add(E e) 把給定的對象添加到當前集合中 public void clear() 清空集合中所有的元素 public boolean remove(E e) 把給定的對象在當前集合中刪除 public boolean contains(Object obj) 判斷當前集合中是否包含給定的對象 public boolean isEmpty() 判斷當前集合是否為空 public int size() 返回集合中元素的個數。 public Object[] toArray() 把集合中的元素,存儲到數組中
Collection的遍歷方式
迭代器遍歷 迭代器是用來遍歷集合的專用方式(數組沒有迭代器),在Java中迭代器的代表是Iterator。
方法名稱 說明 Iterator iterator() 返回集合中的迭代器對象,該迭代器對象默認指向當前集合的第一個元素
方法名稱 說明 boolean hasNext() 詢問當前位置是否有元素存在,存在返回true ,不存在返回false E next() 獲取當前位置的元素,并同時將迭代器對象指向下一個元素處。
增強 for 循環
增強for可以用來遍歷集合或者數組 增強for遍歷集合,本質就是迭代器遍歷集合的簡化寫法。
for ( 元素的數據類型 變量名 : 數組或者集合) {
}
Lambda表達式
JDK 8開始的新技術Lambda表達式,提供了一種更簡單、更直接的方式來遍歷集合。
方法名稱 說明 default void forEach(Consumer<? super T> action) 結合lambda遍歷集合
Collection < String > lists = new ArrayList < > ( ) ;
. . .
lists. forEach ( new Consumer < String > ( ) { @Override public void accept ( String s) { System . out. println ( s) ; }
} ) ;
Collection < String > lists = new ArrayList < > ( ) ;
. . .
lists. forEach ( s -> { System . out. println ( s) ;
} ) ;
認識并發修改異常問題
遍歷集合的同時又存在增刪集合元素的行為時可能出現業務異常,這種現象被稱之為并發修改異常問題。
解決并發修改異常問題的方案
如果集合支持索引,可以使用for循環遍歷,每刪除數據后做 i–;或者可以倒著遍歷。 可以使用迭代器遍歷,并用迭代器提供的刪除方法刪除數據。 增強for循環/Lambda遍歷均不能解決并發修改異常問題,因此增它們只適合做數據的遍歷,不適合同時做增刪操作。
List集合
ArrayList和LinkedList,底層實現不同,適應的場景不同。
List集合的特有方法
List集合因為支持索引,所以多了很多與索引相關的方法。
方法名稱 說明 void add(int index,E element) 在此集合中的指定位置插入指定的元素 E remove(int index) 刪除指定索引處的元素,返回被刪除的元素 E set(int index,E element) 修改指定索引處的元素,返回被修改的元素 E get(int index) 返回指定索引處的元素
ArrayList底層原理
ArrayList底層是基于數組存儲數據的。 數組的特點
LinkedList的底層原理
LinkedList底層是基于鏈表存儲數據的。 基于雙鏈表實現的。 特點:查詢慢,增刪相對較快,但對首尾元素進行增刪改查的速度是極快的。 鏈表的特點: 鏈表中的數據是一個一個獨立的結點組成的,結點在內存中是不連續的,每個結點包含數據值和下一個結點的地址。 查詢慢,無論查詢哪個數據都要從頭開始找。 鏈表增刪相對快. 雙鏈表:對首尾元素進行增刪改查的速度是極快的。 LinkedList新增了很多首尾操作的特有方法。
方法名稱 說明 public void addFirst(E e) 在該列表開頭插入指定的元素 public void addLast(E e) 將指定的元素追加到此列表的末尾 public E getFirst() 返回此列表中的第一個元素 public E getLast() 返回此列表中的最后一個元素 public E removeFirst() 從此列表中刪除并返回第一個元素 public E removeLast() 從此列表中刪除并返回最后一個元素
LinkedList的應用場景
用來設計隊列 用來設計棧 棧的特點:后進先出,先進后出。 數據進入棧模型的過程稱為:壓/進棧(push) 數據離開棧模型的過程稱為:彈/出棧(pop) 使用首尾元素,用Linked來實現很合適。