異常, 迭代器, 包裝類, StringBuffer(基本使用), 容器Collection, TreeSet容器中排序, ...
* 常見異常
* 數組越界異常
* 空指針異常
*
*
* 特點: 當程式出現異常的時候, 程式會列印異常信息並中斷程式
* 所以當同時出現多個異常的時候只能執行第一個, 後邊的用不到
*
* 單異常 * 對異常的處理 ->> 檢測異常,捕獲異常, 處理異常, finally(回收資源之類的收尾工作) * try{ * 可能出異常的代碼 * }catch(Exception e) { e是要捕獲的異常 * 對異常的代碼進行處理 * }finally{ * 不論怎樣都會執行的代碼(除非程式結束)(被System.exit()之類的代碼 GANK) * } * * * 多異常 * try{ * 可能出異常的代碼 * }catch(第一型異常 e1) { e1 * ... * }catch(第二型異常 e2) { e2 * ... * }catch(Exception e3) { default 處理 * ... * }finally{ * 不論怎樣都會執行的代碼(被System.exit()之類的代碼 GANK) * }
* 如果try代碼塊的語句發生異常, 會立即catch 並終止try代碼塊的執行, 如果try代碼塊沒有異常, try代碼塊會全部執行
* 由於異常的先後捕獲順序不同, 如果前邊的 第一型異常 是 第二型異常 的父類 那麼 發生第二型異常時其不會被 e2 捕獲 其會被 e1捕獲;
* 所以捕獲順序必須先進行上層捕獲!!!最後可以加上個Exception e3 來捕獲任意類型的異常
* finally 中的功能 例如: 資源釋放 ->> (線程鎖, 流, 資料庫連接) 等的關閉
*
* 子類的同名方法中聲明的異常可以與父類的不一致也可以不聲明異常, 但是此時子類方法不能再拋出異常
* 如果子類同名方法聲明瞭異常父類必須聲明異常
*
*
* try finally 結構, 不進行catch
* 自定義異常 由於內部有異常的基本功能 所以一般都繼承自Exception
*
* 自定義異常的原因: 系統沒有我們需要的異常(我們需要的比較特殊), 比如訂單異常 用戶信息異常之類的 (訂單里你總不能給我負數的錢吧~)
*
* 異常分類
* 編譯異常: 在編譯階段拋出, 處理異常 除RuntimeException以外的所有異常
* 所有的工作都要程式員自己完成
* 運行時異常: 在運行階段拋出, 處理的異常 對應RunException
* 所有的異常我們都可以不管
* 異常處理的方式:
* 異常的聲明
* trycatch語句
*
* throw : 拋出異常
* throws : 聲明異常-->>告訴調用者此方法可能出異常
*
* 異常聲明後交給調用者處理, 調用者不處理那麼交給jvm虛擬機處理
* trycatch 是真的對異常的處理
*/
實例:
try { div(5, -2); }catch (FushuException e) { System.out.println("處理異常"); } finally { System.out.println("收尾"); } ------------------------------------------------------- public static int div(int x, int y) throws FushuException{ if(y<=0){ FushuException f = new FushuException(); throw f; //手動生成除數為負數的FushuException異常 // catch(f) { // System.out.println("處理異常"); // } } return x/y; } -------------------------------------------------------- class FushuException extends Exception{ private static final long serialVersionUID = 1L; public FushuException(){} public FushuException(String message){super(message);} //加上super() 才能拋給jvm一份異常 } //在重寫的方法中使用異常的註意點: ///* // * 1.子類的同名方法中聲明的異常等級要=<父類的. // * 2.子類的同名方法中聲明的異常可以與父類的不一致,也可以不聲明異常.但是此時子類方法不能再拋出異常 // * 3.如果子類同名方法聲明瞭異常,父類必須聲明異常.
包裝類 Integer Character String StringBuffer StringBuilder 等
/*
* 包裝類, 專門將簡單數據類型進行封裝 byte Byte short Short int Integer long Long float
* Float double Double boolean Boolean char Character
*
* 1.方便實現簡單數據類型和字元串之間的轉化 2.便於在集合中存儲 3.可以更加方便對簡單數據類型進行操作
*/
/*
* 對於Integer來說, 數字範圍在在一個位元組範圍內
* 後邊再定義它,直接使用前邊的
* 超過一個位元組其會新建對象
*/
// 包裝類
// * 基本類型轉成字元串類型
// static String Integer.toString(int i)
// static String Double.toString(double d)
// 字元串類型轉基本類型
// 只能轉字元串類型的
// int Integer.parseInt("23")
// double Double.parseDouble("3.45")
//
// 把十進位轉成其它進位
// Integer.toHexString()
// Integer.toOctalString()
// Integer.toBinaryString()
//
// 把其它進位轉十進位
// Integer.parseInt(數據,進位)
模板設計模式
* 模板設計模式: 實現一個功能的時候, 分成兩部分(確定和不確定部分), 將確定的部分有當前類實現, 不確定的部分教育子類實現
* 子類實現的結果又會反過來影響確定的部分
*
* 實例: 求一個程式運行的時間
*
* 分析:
* 開始時間, 運行過程, 結束時間
*/
public class Demo5 { public static void main(String[] args) { Fu f = new Zi(); System.out.println(f.getTime()); } } abstract class Fu{ //開始時間, 運行過程, 結束時間 /* * 此處為固定部分 運行過程是不確定部分交給子類 */ public double getTime(){ long startTime = System.nanoTime(); // this.show(); for(short i =90;i<100;i++) System.out.println(i); long endTime = System.nanoTime(); return endTime - startTime; } public abstract void show(); } class Zi extends Fu{ public void show() { for(int i =0;i<100;i++) System.out.println(i); } }
* 對於String的比較, 按照ascii碼(中文好像按照拼音順序) 比較
*
* 從左邊第一個開始比較, 碼數比較大的為較大的字元串
* compareTo 返回值為 前邊的字元-後邊的字元的值, 結束符號為 /u0000
String[] strs = str1.split(""); //->>1 2 3 a
"1,2,3".split(","); //->> 1 2 3 ','被忽略
System.out.println(Arrays.toString(strs));
// String:
//1.判斷:
//判斷是否包含一個子字元串
//boolean contains(CharSequence s)
//判斷兩個字元串的內容是否相同
//boolean equals(Object anObject)
//忽略大小寫判斷兩個字元串的內容是否相同
//boolean equalsIgnoreCase(String anotherString)
//判斷是否以某字元串開頭
//boolean startsWith(String prefix)
//判斷是否以某字元串結尾
//boolean endsWith(String suffix)
//2.轉換:將字元數組轉換成字元串
//1:使用構造方法
//String(char[] value)
//String(char[] value, int offset, int count)
//2:使用靜態方法
//static String copyValueOf(char[] data)
//static String copyValueOf(char[] data, int offset, int count)
//將字元串轉成字元數組
//char[] toCharArray()
//將位元組數組轉成字元串
//String(byte[] bytes)
//String(byte[] bytes, int offset, int length)
//String(byte[] bytes, String charsetName)//使用指定的編碼將位元組數組轉換成字元成
//將字元串轉成位元組數組
//byte[] getBytes()
//將基本數據類型轉換成字元串
//String.valueOf()
//3.替換:
//String replace(char oldChar, char newChar)
//子串:
//String substring(int beginIndex)
//String substring(int beginIndex, int endIndex) //包含起始位置,不包含結束位置,到結束位置的前一位
//轉換,去除空格,比較:
//大小寫轉換
//String toLowerCase()
//String toUpperCase()
//將字元串兩端的空格去掉
//String trim()
//按字典順序比較兩個字元串
//int compareTo(String anotherString)
//4.切割: String[] split(String)
* 可變字元串: 字元串緩衝區 StringBuffer jdk1.0 :: 線程安全的要考慮線程安全問題 StringBuilder jdk1.5
* ::線程不安全的不需要考慮線程安全問題
*
* 區分: 在不考慮線程安全的情況下儘量使用StringBuilder效率高速度快
StringBuffer stf = new StringBuffer(); // 事實上先
/*
* public StringBuffer() { super(16); }
* AbstractStringBuilder(int capacity) { value = new char[capacity]; }
*/
//驗證是不是一個對象(其沒有修改記憶體) !!!!!!!!!!!!!!!!!!!!!!!!! 敲黑板哦,
System.out.println(stf.append("1") == stf.append("2")); //還是在比較地址
// 1.存儲:
// StringBuffer append(boolean b) 從最後插入
// StringBuffer insert(int offset, boolean b) 從指定位置插入
// 2.刪除:
// StringBuffer delete(int start, int end)
// StringBuffer deleteCharAt(int index)
// 3.修改:
// StringBuffer replace(int start, int end, String str) 替換指定的子字元串
// void setCharAt(int index, char ch) 修改一個字元
// 4.獲取:
// char charAt(int index)
// int indexOf(String str)
// int indexOf(String str, int fromIndex)
// int lastIndexOf(String str)
// 返回指定子字元串(從右邊開始計數)在此字元串第一次出現時的索引
// int lastIndexOf(String str, int fromIndex)
// 返回指定子字元串(從右邊開始計數,範圍:當前指定的位置-0)在此字元串第一次出現時的索引
// int length()
// 返回長度(字元數)。
// 5.反轉:
// StringBuffer reverse()
Date
//1,系統預設提供的格式 有限的四種格式, 分別是short long full, default //第一個參數是設計日期的格式, 第二個格式是這隻時間的格式 DateFormat df = DateFormat.getDateTimeInstance(DateFormat.LONG,DateFormat.SHORT ); Date d = new Date(); String s= df.format(d); System.out.println(s); //2,自定義的格式 SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd hh:mm:sss"); s = simpleDateFormat.format(new Date()); System.out.println(s);
Math
System.out.println(Math.abs(-1)); System.out.println(Math.floor(4.4999)); //floor 向下取整 System.out.println(Math.ceil(4.4)); //ceil 向上取整 System.out.println((long)(Math.random()*10));
* 容器: 分為 Collection 和Map
*
* 區分容器和數組, 數組>>> 數組可以存儲不同類型的多個數據, 數據類型 可以是簡單數據類型也可以是引用數據類型 缺點: 創建的是一個定製,
* 只能存儲固定長度的數據, 一旦存滿了, 就不能再繼續
*
* 容器>>> 可以存儲不同類型的多個數據, 只能存儲引用數據類型 缺點: 只能存儲引用數據類型 優點: 存儲空間會隨著存儲數據的增大而增大,
* 所以可以更加合理的利用記憶體空間, 方法較多, 方便實現功能
*
* 數據存儲的分類>>> 短期存儲: 一旦電腦關閉, 存儲的數據會被立刻釋放,-變數, 對象, 數組, 容器 長期存儲: 直接存儲到磁碟上,
* 數據不會隨著電腦的關閉丟失
*
*
* Collection : >List >> ArrayList >> Vector >>LinkedList >Set >> HashSet
* >>TreeSet Map: >>HashMap >> TreeMap >> Hashtable
Collection<String> c = new ArrayList<String>(); Collection<String> b = new LinkedList<String>(); Collection a = new LinkedList<String>(); // Collection中定義是整個集合體系最共性的方法: // 1.添加: // boolean add(Object o) // boolean addAll(Collection<? extends E> c) c.add("123");//arrlist中add是直接存進去引用, addall是複製一份記憶體加進去 linkedlist 也這樣... c.add("asd"); System.out.println(c); b.add("dtryfhggjh"); c.addAll(b); c.addAll(a); System.out.println(c); /* * 當集合中存在不同類型的數據時, 需要進行容錯處理 * 迭代器模式:就是提供一種方法對一個容器對象中的各個元素進行訪問,而又不暴露該對象容器的內部細節。 */ Iterator<String> i = c.iterator();//迭代器剛剛創建出來時是指向一個類似於Head的東西的對象的地址的 System.out.println(i); while(i.hasNext())//hasNext() 判斷當前迭代器下一個位置是否有元素 System.out.println(i.next());//next() 將下一個位置的元素取出,並且位置向後移動1步 while(i.hasNext())//這裡再進行遍歷時會失敗,因為當前的位置已經在集合的最後-_-| System.out.println(i.next()); //想要再次遍歷, 重新獲取迭代器 Iterator
//foreach 事實上對集合的遍歷也是通過迭代器實現的;
// 2.刪除:
// boolean remove(Object o)
// boolean removeAll(Collection<?> c)
// void clear()
// 3.判斷:
// boolean contains(Object o)
// boolean containsAll(Collection<?> c)
// boolean isEmpty() //判斷集合是否為空
// boolean equals(Object o)
// 4.獲取:
// Iterator<E> iterator() //獲取集合中的對象
// int size() //獲取集合中對象的個數
// 5.集合變數組:
// Object[] toArray()
/*
* ConcurrentModificationException: 當方法檢測到對象的併發修改,但不允許這種修改時,拋出此異常。
*
* 例如,某個線程在 Collection 上進行迭代時,通常不允許另一個線性修改該
* Collection。通常在這些情況下,迭代的結果是不確定的。如果檢測到這種行為,一些迭代器實現(包括 JRE 提供的所有通用
* collection 實現)可能選擇拋出此異常。執行該操作的迭代器稱為快速失敗
* 迭代器,因為迭代器很快就完全失敗,而不會冒著在將來某個時間任意發生不確定行為的風險。
*
* 註意,此異常不會始終指出對象已經由不同
* 線程併發修改。如果單線程發出違反對象協定的方法調用序列,則該對象可能拋出此異常。例如,如果線程使用快速失敗迭代器在 collection
* 上迭代時直接修改該 collection,則迭代器將拋出此異常。
*
* 註意,迭代器的快速失敗行為無法得到保證,因為一般來說,不可能對是否出現不同步併發修改做出任何硬性保證。快速失敗操作會盡最大努力拋出
* ConcurrentModificationException。因此,為提高此類操作的正確性而編寫一個依賴於此異常的程式是錯誤的做法,
* 正確做法是:ConcurrentModificationException 應該僅用於檢測 bug。
*/
/*
* Collection List : 存儲有先後順序 可重覆 ArrayList:數據結構是數組, 線程不安全, 查找效率高, 添加刪除速度慢
* Vector : 數據結構是數組, 線程安全, 查找效率高, 添加刪除速度慢,使用枚舉器 LinkedList : 數據結構是鏈表, 線程不安全,使用迭代器;
* 查找效率低, 添加刪除速度快 Set : 存儲沒有先後順序 不可重覆
*/
ListIterator i = list.listIterator(10); while (i.hasNext()) { System.out.println(i.next()); // if(true) i.remove(); } while(i.hasPrevious()){ System.out.println(i.previous()); }
// * List:特有方法,可以操作下標
// 1.增:
// void add(int index, E element)
// boolean addAll(int index, Collection<? extends E> c)
// 2.刪
// E remove(int index)
// 3.改
// E set(int index, E element)
// 4.查
// ListIterator<E> listIterator()
// 返回此列表元素的列表迭代器(按適當順序)。
// ListIterator<E> listIterator(int index)
// List<E> subList(int fromIndex, int toIndex)
// E get(int index)
// 5.刪除全部對象
//void clear()
// https://www.jianshu.com/p/724f763fd242
//使用ListIterator 期間不要用list帶的 增加或刪除操作 要使用 ListTerator自帶的增刪
* contains 使用indexOf return indexOf(o) >= 0;
/*Set
* 無序的
* HashSet 數據結構是Hash表
* TreeSet 數據結構是二叉樹
* HashSet 去重先對比元素的HashCode, 然後如果HashCode相同使用元素的equals對比是否相同
* 所以想要使用HashSet 必須先 重寫HashCode 然後重寫equals()
* 由於HashSet是按照的HashCode添加元素和比較元素, 因此HashSet不能進行排序
*
* TreeSet 是使用了紅黑樹的數據結構 使用TreeSet時, 其在添加時會根據compareTo()[來自Compareable介面]方法添加, 輸出時按前序輸出,所以實現了排序
* 實現Compareable介面才能讓對象實現比較大小的功能
* 所以想要使用TreeSet必須實現Compareable 介面 實現 compareTo 方法
*
* 對TreeSet排序有兩種方式
* 1: 元素實現Compareable介面 的compareTo(),
* 2: 創建實現介面Compareator介面的對象(其中)
*/