集合
Collection(單列集合)
(1)List(有序,可重複)
A: ArrayList
底層數據結構是數組,查詢快,增刪慢
線程不安全,效率高
B: Vector
底層數據結構是數組,查詢快,增刪慢
線程安全,效率低
C: LinkedList
底層數據結構是鏈表,查詢慢,增刪快
線程不安全,效率高
(2)Set(無序,唯一)
A: HashSet
底層數據結構是哈希表
哈希表依賴兩個方法:hashCode()和equals()
執行順序:
首先判斷hashCode()值是否相同
相同:繼續執行equals()方法
返回true:元素重複了,不添加
返回false:直接把元素添加到集合
不同:就直接把元素添加到集合
最終:
自動生成hashCode()和equals()即可
a: LinkedHashSet
底層數據結構由鏈表和哈希表組成。
由鏈表保證元素有序。
由哈希表保證元素唯一。
B: TreeSet
底層數據結構是紅黑樹(是一種自平衡的二叉樹)
如何保證元素唯一性呢?
根據比較的返回值是否是0來決定
如何保證元素的排序呢?
兩種方式
自然排序(元素具備比較性)
讓元素所屬的類實現Comparable接口
比較器排序(集合具備比較性)
讓集合接收一個Comparator的實現類對象
Map(雙列集合)
A:Map集合的數據結構僅僅針對鍵有效,與值無關。
B:存儲的是鍵值對形式的元素,鍵唯一,值可重複
(1)HashMap
底層數據結構是哈希表。線程不安全,效率高。
哈希表依賴兩個方法:hashCode()和equals()
執行順序:
首先判斷hashCode()值是否相同
相同:繼續執行equals()方法
返回true:元素重複了,不添加
返回false:直接把元素添加到集合
不同:就直接把元素添加到集合
最終:
自動生成hashCode()和equals()即可
A: LinkedHashMap
底層數據結構由鏈表和哈希表組成。
由鏈表保證元素有序。
由哈希表保證元素唯一。
(2)Hashtable
底層數據結構是哈希表。線程安全,效率低。
哈希表依賴兩個方法:hashCode()和equals()
執行順序:
首先判斷hashCode()值是否相同
相同:繼續執行equals()方法
返回true:元素重複了,不添加
返回false:直接把元素添加到集合
不同:就直接把元素添加到集合
最終:
自動生成hashCode()和equals()即可
A: LinkedHashMap
底層數據結構由鏈表和哈希表組成。
由鏈表保證元素有序。
由哈希表保證元素唯一。
(3)TreeMap
底層數據結構是紅黑樹(是一種自平衡的二叉樹)
如何保證元素唯一性呢?
根據比較的返回值是否是0來決定
如何保證元素的排序呢?
兩種方式
自然排序(元素具備比較性)
讓元素所屬的類實現Comparable接口
比較器排序(集合具備比較性)
讓集合接收一個Comparator的實現類對象
2 異常
(1)程序出現了不正常的情況
舉例:今天天氣很好,班長出去旅行,騎着自行車,去山裏面呼吸新鮮空氣
問題1:山路坍塌了,班長及時停住了,但是過不去了。嚴重的問題。
問題2:班長出門推自行車,發現氣沒了,把氣吹起來。出發前就應該檢查的問題。
問題3:班長騎着車在山路上愜意的行駛着,山路兩邊是有小石子的,中間是光滑的水泥路。
一直在平坦的水泥路上行駛,是沒有任何問題的,但是,他偏偏要騎到小石子上,結果爆胎了。旅道的過程中出現的問題、
(2)
程序的異常:Throwable
嚴重問題:Error 我們不處理,這種問題一般都是很嚴重的,比如說內存溢出。
問題:Exception
編譯期問題:不是RuntimeException的異常 必須進行處理的,因爲你不處理,編譯就不能通過。
運行期問題:RuntimeException 這種問題我們也不處理,因爲是你的問題,而且這個問題出現肯定是我們的代碼不夠嚴謹,需要修改代碼。
(3)JVM默認處理異常:
如果程序出現了問題,我們沒有做任何處理,最終jvm會做出默認的處理。
把異常的名稱,原因以及出現的問題等信息輸出在控制檯。
同時會結束程序。
(4)我們自己如何進行處理異常呢?
A:try...catch...finally
B:throws 拋出
try...catch...finally的處理格式:
try{
可能出現問題的代碼:
}catch(異常名 變量){
針對問題的處理:
}finally {
釋放資源;
}
變形格式:
try{
可能出現問題的代碼;
}catch(異常名 變量){
針對問題的處理;
}
***注意事項:
1:能明確的儘量明確,不要用大的來處理。
2:平級關係的異常誰前誰後無關係,如果出現了子父關係,父必須在後面
***注意:
A:try裏面的代碼越少越好。
B:catch裏面必須有內容,哪怕是給出一個簡單的提示
C:一旦try裏面出了問題,就會在這裏把問題給拋出去,然後和catch裏面的問題進行匹配。一旦有匹配的,就執行了catch裏面的處理,然後結束了try...catch。繼續執行後面的語句。
------------------------------------------------
A:一個異常
B:二個異常
a:每一個寫一個try...catch
b:寫一個try,多個catch
------------------------------------------------
//一個異常的處理
int a = 10;
//int b =2;
int b =0;
try{
System.out.println(a/b);
}catch(ArithmeticException ae){
System.out.println("除數不能爲0");
}
System.out.println("over");
//輸出: 除數不能爲0
over
------------------------------------------------
//兩個異常的處理
int a = 10;
int b = 0;
int[] arr = {1,2,3};
try{
System.out.println(arr[3]);
System.out.println(a/b);
}catch(ArithmeticException e){
System.out.println("除數不能爲0");
}catch(ArrayIndexOutOfBoundsException e){
System.out.println("你訪問了不該訪問的索引");
}
System.out.println("over");
//輸出: 你訪問了不該訪問的索引
over
-------------------------------------------------
//如果無法明確異常
int a = 10;
int b = 0;
int[] arr = {1,2,3};
try{
System.out.println(arr[3]);
System.out.println(a/b);
System.out.println("這裏出現了一個異常,你不太清楚是誰,該怎麼辦呢?");
}catch(Exception e){
System.out.println("出問題了");
}
System.out.println("over");
//輸出: 出問題了
over
---------------------------------------------------
//正常情況
try{
System.out.println(arr[3]);
System.out.println(a/b);
System.out.println("這裏出現了一個異常,你不太清楚是誰,該怎麼辦呢?");
}catch(ArithmeticException e){
System.out.println("除數不能爲0");
}catch(ArrayIndexOutOfBoundsException e){
System.out.println("你訪問了不該訪問的索引");
}catch(Exception e){
System.out.println("出問題了");
}
---------------------------------------------------
(5) JDK7針對多個異常的處理方案
try{
}catch(異常名1 | 異常名2 | ... 變量) {
}
注意:這個方法雖然簡潔,但是也不夠好。
A:處理方式是一致的(實際開發中,好多時候可能就是針對同類型的問題,給出同一個處理)
B:多個異常間必須是平級關係。(Exception會出錯)
//jdk7的處理方案
try{
System.out.println(arr[3]);
System.out.println(a/b);
}catch(ArithmeticException | ArrayIndexOutOfBoundsException e){
System.out.println("出問題了");
}
3 編譯期異常和運行期異常
區別
編譯期異常:Java程序必須顯示處理,否則程序就會發生錯誤,無法通過編譯
運行期異常:無需顯示處理,也可以和編譯時異常一樣處理
在try裏面發現問題後,jvm會幫我們生成一個異常對象,然後把這個對象拋出,和catch裏面的類進行匹配。
如果該對象是某個類型的,就會執行該catch裏面的處理信息。
4 Throwable的幾個常見方法
異常中要了解的幾個方法:
public String getMessage():異常的消息字符串
public String toString():返回異常的簡單信息描述
此對象的類name(全路徑名)
":"(冒號和一個空格)
調用此對象getLocalizedMessage()方法的結果(默認返回的是getMessage()內容)
printStackTrace() 獲取異常類名和異常信息,以及異常出現在程序中的位置,返回值void,把信息輸出在控制檯。
String s = "2014-11-20";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try{
Date d = sdf.parse(s);
System.out.println(d);
}catch(ParseException e){ //ParseException e = new ParseException();
//getMessage()
//System.out.println(e.getMessage());
//Unparseable date:"2014-11-20"
//toString()
//System.out.println(e.toString());
//java.text.parseException:Unparseable date:"2014-11-20"
e.printStackTrace();
//跳轉到某個指定的頁面(index.html)
}
System.out.println("over");
5 throws的方式處理異常
有些時候,我們是可以對異常進行處理的,但是又有些時候,我們根本就沒有權限去處理某個異常。
或者說,我處理不了,就不處理了。
爲了結局出錯問題,java針對這種情況,就提供了另一種處理方案:拋出。
格式:
throws 異常類名
注意:這個格式必須跟在方法的括號後面
注意:儘量不要在main方法上拋出異常
但是講課爲了方便就這樣做了。。。
小結:
編譯期異常拋出,將來調用者必須處理。
運行期異常拋出,將來調用可以不用處理。
-------------------------------------------------------------
System.out.println("今天天氣真好!");
//編譯時異常處理
try{
method();
}catch(ParseException e){
e.printStackTrace();
}
System.out.println("但是就是不該有霧霾");
method2();
//運行期異常的拋出 不需要異常處理
public static void method2() throws ParseException(){
int a = 10;
int b =0;
System.out.println(a/b);
}
//編譯時異常的拋出
public static void method() throws ParseException(){
String s = "2014-11-20";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date d = sdf.parse(s);
System.out.println(d);
}
//輸出: 今天天氣真好!
一段java錯誤提示...
但是就是不該有霧霾
一段java錯誤提示...
---------------------------------------------------------------
6 throw的概述以及和throws的區別
throw:如果出現了異常情況,我們可以把異常拋出,這個時候拋出的應該是異常的對象
(在功能方法內部出現某種情況,程序不能繼續運行,需要進行跳轉時,就用throw把異常對象拋出)
***
throws
用在方法聲明後面,跟的是異常類名
可以跟多個異常類名,用逗號隔開
表示拋出異常,由該方法的調用者來處理
throws表示出現異常的一種可能性,並不一定會發生這些異常
throw
用在方法體內,跟的是異常對象名
只能拋出一個異常對象名
表示拋出異常,由方法體內的語句處理
throw則是拋出了異常,執行throw則一定拋出了某種異常
public static void method(){
int a = 10;
int b = 0;
if(b ==0){
throw new ArithmeticException();
}else{
System.out.println(a/b);
}
}
7 異常處理使用情況
原則:如果該功能內部可以將問題處理,用try,如果處理不了,交由調用者處理,這是用throws。
區別:
後續程序需要繼續運行就try
後續程序不需要繼續運行就throws
***8 finally
(1)finally:異常處理,一般都會執行
格式
try...catch...finally
----------------------------
(2)面試題 final finally finalize 三者的區別
final:最終的意思,可以修飾類,成員變量,成員方法
修飾類,類不能被繼承
修飾變量,變量是常量
修飾方法,方法不能被重寫
finally:是異常處理的一部分,用於釋放資源
一般來說,代碼肯定會執行。特殊情況:在執行到finally之前,jvm退出,例如System.exit();
finalize:是Object類的一個方法,用於垃圾回收。
(3)面試題 如果catch裏面有return語句,請問finally裏面的代碼還有執行嗎
如果會,請問在return前,還是return後。
會,因爲除非jvm退出,否則finally能執行。
前。
更準確的說,是在return 的中間。
int a = 10;
try{
System.out.println(a/0);
a = 20;
}catch (ArithmeticException e){
a = 30;
return a;
// return a 在程序執行到這一步的首,這裏不是return a,而是return 30 ,這個返回路徑就完成了。
// 但是,它發現後面還有finally ,所以繼續執行finally的內容, a =40
//再次回到以前的返回路徑,繼續走return 30
}finally{
a = 40;
//return a; 如果這裏有return a 則返回的是 40
}
return a;
}
9 異常注意事項
A:子類重寫父類方法時,子類的方法必須拋出相同的異常或父類異常的子類。(父親壞了,兒子不能比父親更壞)
B:如果父類拋出了多個異常,子類重寫父類時,只能拋出相同的異常或者是他的子集,子類不能拋出父類沒有的異常
C:如果被重寫的方法沒有異常拋出,那麼子類的方法絕對不可以拋出異常,如果子類方法內有異常發生,那麼子類只能try,不能throws
10 File類的概述和構造方法
我們要想實現IO的操作,就必須知道硬盤上文件的表現形式
而java提供了一個類File供我們使用
File:文件和目錄(文件夾)路徑名的抽象表示形式
(1)構造方法:
File(String pathname):根據一個路徑得到File對象
File(String parent,String child):根據一個目錄和一個子文件/目錄得到File對象
File(File parent,String child):根據一個父File對象和一個子文件/目錄得到File對象
----------------------------------
//File(String pathname):根據一個路徑得到File對象
//把e:\\demo\\a.txt封裝成一個File對象
File file = new File("E:\\demo\\a.txt");
//File(String parent,String child):根據一個目錄和一個子文件/目錄得到File對象
File file2 = new File("E:\\demo","a.txt");
//File(File parent,String child):根據一個父File對象和一個子文件/目錄得到File對象
File file3 = new File("e:\\demo");
File file4 = new File(file3,"a.txt");
//以上三種方式其實一樣
(2)創建功能
public boolean createNewFile():創建文件
public boolean mkdir():創建文件夾,如果存在這樣的文件夾,就不創建了
public Boolean mkdirs():創建文件夾,如果目錄不存在,則創建該目錄
//需求,在e盤目錄下創建一個文件夾demo
File file = new File("e:\\demo");
System.out.println("mkdir:"+file.mkdir());
//需求:在e盤目錄demo下創建一個文件a.txt
File file2 = new File("e:\\demo\\a.txt");
System.out.println("createNewFile:"+file2.createNewFile());
//需求:在e盤目錄test下創建一個文件b.txt
File file3 = new File("e:\\test\\a.txt");
System.out.println("createNewFile:"+file3.createNewFile());
//會報錯! 注意:想要在某個目錄下創建內容,該目錄必須存在
//需求,在e盤目錄test下創建目錄aaa
File file4 = new File("e:\\test\\aaa");
System.out.println("mkdir:"+file4.mkdir());
//會報錯,需要一步一步來
File file5 = new File("e:\\test");
System.out.println("mkdir:"+file5.mkdir());
File file6 = new File("e:\\test\\aaa");
System.out.println("mkdir:"+file6.mkdir());
//其實還有更簡單的方法
File file7 = new File("e:\\aaa\\bbb\\ccc\ddd");
System.out.println("mkdirs:"+file7.mkdirs());
(3)刪除功能
public boolean delete():
A:如果你創建文件或者文件夾忘了寫盤符路徑,那麼,默認在項目路徑下
B:Java中的刪除不走回收站
C:要刪除一個文件夾,請注意該文件夾不能包含文件或文件夾
File file = new File("e:\\aaa\\bbb");
System.out.println("mkdirs:"+file.mkdirs());
File file2 = new File("e:\\aaa");
System.out.println("delete:"+file2.delete());
//刪除失敗 因爲 aaa文件夾中有東西,必須全部刪除後,才能刪除aaa
File file3 = new File("e:\\aaa\\bbb");
System.out.println("delete:"+file3.delete());
File file4 = new File("e:\\aaa");
System.out.println("delete:"+file4.delete());
(4)重命名功能
路徑以盤符開始:絕對路徑 c:\\a.txt
路徑不以盤符開始:相對路徑 a.txt
public boolean renameTo(File dest)
//創建一個文件對象
File file = new File("林青霞.jpg");
//改名
File newFile = new File("東方不敗.jpg");
file.renameTo(newFile);
(5)判斷功能
public boolean isDirectory() :判斷是否是目錄
public boolean isFile() :判斷是否是文件
public boolean exists() :判斷是否存在
public boolean canRead() :判斷是否可讀
public boolean canWrite() :判斷是否可寫
public boolean isHidden() :判斷是否隱藏
(6)獲取功能
public String getAbsolutePath() :獲取絕對路徑
public String getPath() :獲取相對路徑
public String getName() :獲取名稱
public long length() : 獲取長度,字節數
public long lastModified() :獲取最後一次的修改時間,毫秒值
(7)高級獲取功能
public String[] list():獲取指定目錄下的所有文件或者文件夾的名稱數組
public File[] listFiles() :獲取指定目錄下的所有文件或者文件夾的File數組
//指定一個目錄
File file = new File("e:\\");
//public String[] list()
String strArray = file.list();
for(String s : strArray){
Sytstem.out.println(s);
}
//public File[] listFiles()
File[] fileArray = file.listFiles();
for(File f : fileArray){
Sytem.out.println(f.getName());
}
(8)輸出指定目錄下指定後綴名的文件名
//指定一個目錄
File file = new File("e:\\");
//獲取該目錄下所有文件或者文件夾的file數組
File[] fileArray = file.listFiles();
//遍歷該File數組,得到每一個File對象,然後判斷
for(File f : fileArray){
//是否是文件
if(f.isFile()){
//繼續判斷是否以.jpg結尾
if(f.getName().endsWith(".jpg"))
//輸出該文件名稱
System.out.println(f.getName());
}
}
(9) 改進輸出指定目錄下的指定後綴名的文件名
A:先獲取所有的,然後遍歷的時候,一次判斷,如果滿足條件就輸出
B:獲取的時候就已經是滿足條件了的,然後輸出即可
想要實現這個效果,就必須學習一個接口:文件名稱過濾器
public String[] list(FilenameFilter filter)
public File[] listFiles(FilenameFilter filter)
//指定一個目錄
File file = new File("e:\\");
//獲取該目錄下所有文件或者文件夾的String數組
//public String[] list(FilenameFilter filter)
String[] strArray = file.list(new FilenameFilter(){
@Override
public boolean accpet(File dir,String name){
//return false
//return true
//通過這個測試,我們知道了,到底把這個文件或者文件夾的名稱加不加到數組中,取決於這裏的返回值是true還是false
//所以,這個的true或者false應該是通過某種判斷得到的
File file = new File(dir,name);
//System.out.println(file)
boolean flag = file.isFile();
boolean flag2 = name.endsWith(".jpg");
return flag && flag2;
for(String s : strArray){
System.out.println(s);
}
//return new File(dir,name).isFile() &&name.endsWith(".jpg");
}