Java基礎知識(八)
1、概述
(1)本身基於哈希表,可以保證鍵的唯一性。
(2)Map集合只針對鍵有效,當集合中出現兩個鍵一樣時,後者所對應的值會覆蓋掉前者所對應的值存儲。
2、常見存儲類型
(1)HashMap<String,String>;(2)HashMap<Inreger,Inreger>
(3)HashMap<Student,String>;(4)HashMap<String,Student>
3、當鍵的類型不同時
(1)鍵為自定義類型時,鍵可重復,若要保證鍵的唯一性,需在自定義類中重寫equals()方法和hashCode()方法。
4、HashMap集合與HashTable集合區別
(1)共同點:都是map接口的實現類,都是基於哈希表的實現類。
(2)HashMap集合:線程不安全的類,不同步,執行效率高(允許鍵和值是null)。
(3)HashTable集合:線程安全的類,同步,執行效率低(不允許有null鍵和null值)。
5、例如:
(1)測試類代碼
package 集合.HashMap集合; import java.util.HashMap; import java.util.Set; public class Demo { public static void main(String[] args) { //創建HashMap對象 HashMap<Student,String> hm=new HashMap<Student,String>(); //創建自定義類對象 Student s1=new Student("章澤天",26); Student s2=new Student("黃燦燦",27); Student s3=new Student("章澤天",26); //存儲 hm.put(s1, "北大"); hm.put(s2, "武大"); hm.put(s3, "清華"); //獲取所有鍵 Set<Student> set=hm.keySet(); //遍歷 for(Student key:set) { String value=hm.get(key); System.out.println(key.getName()+","+key.getAge()+","+value); } } }
(2)自定義類代碼
package 集合.HashMap集合; public class Student { private String name; private int age; public Student() { // TODO Auto-generated constructor stub } public Student(String name,int age) { // TODO Auto-generated constructor stub this.name=name; this.age=age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Student other = (Student) obj; if (age != other.age) return false; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; return true; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + age; result = prime * result + ((name == null) ? 0 : name.hashCode()); return result; } }
(3)運行結果
二、LinkedHashMap<K,V>集合
1、概述:是Map接口基於哈希表和鏈接列表實現的。
2、特點:鍵唯一,且元素有序。
(1)保證鍵的唯一性:哈希表。
(2)保證元素有序性(存儲和取出一致):鏈接列表。
三、TreeMap<K,V>集合
1、概述:基於紅黑樹結構的Map接口的實現。
2、特點:鍵值唯一,且可排序。
3、鍵為自定義類型時:若需要結果以某種順序輸出,需使用自然排序或選擇器排序。
4、例如:采用選擇器排序
(1)測試類代碼:
package 集合.TreeMap集合;
import java.util.Comparator;
import java.util.Set;
import java.util.TreeMap;
import 集合.HashMap集合.Student;
public class Test {
public static void main(String[] args) {
//創建集合對象,采用選擇器排序接口匿名類對象的方式對輸出結果進行排序
TreeMap<Student,String> tm=new TreeMap<Student,String>(new Comparator<Student>() {
//重寫Comparator接口的compare()方法
@Override
public int compare(Student s1, Student s2) {
//主要排序條件,年齡從小到大
int num1=s1.getAge()-s2.getAge();
//次要排序條件,姓名長度由短到長
int num2=(num1==0)?s1.getName().length()-s2.getName().length():num1;
return num2;
}
});
//創建自定義類對象
Student s1=new Student("zhangzetian",26);
Student s2=new Student("huangcancan",27);
Student s3=new Student("zhangzetian",26);
Student s4=new Student("lijian",38);
Student s5=new Student("yangzi",26);
//存儲
tm.put(s1, "北大");
tm.put(s2, "武大");
tm.put(s3, "清華");
tm.put(s4, "清華");
tm.put(s5, "北影");
//獲取所有鍵
Set<Student> set=tm.keySet();
//遍歷
for(Student key:set) {
String value=tm.get(key);
System.out.println(key.getName()+","+key.getAge()+","+value);
}
}
}
(2)自定義類代碼:
package 集合.TreeMap集合;
public class Student {
private String name;
private int age;
public Student() {
// TODO Auto-generated constructor stub
}
public Student(String name,int age) {
// TODO Auto-generated constructor stub
this.name=name;
this.age=age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
(3)運行結果:
四、Collections
1、概述:正對集合操作的工具類。
2、特有功能
(1)public static <T> int binarySearch(List<T> list, T key)
二分查找
(2)static T max(Collection coll)獲取集合中的最大值
(3)public static void reverse(List<?> list)將集合中的元素順序反轉
(4)public static void shuffle(List<?> list)將集合中的元素打亂,隨機置換
(5)public static void sort(List<T> list)排序
3、Collection和Collections區別
(1)Collection:頂層次單列集合的根接口,是一個集合,是一個接口。
(2)Collections:是針對集合操作的工具類,特有功能:隨機置換,二分查找,將集合的元素進行反轉等。
4、例如
(1)代碼:
package 集合.Collections類;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Test {
public static void main(String[] args) {
List<Integer> list=new ArrayList<Integer>();
//添加元素
list.add(8);
list.add(29);
list.add(5);
list.add(23);
list.add(11);
//輸出集合
System.out.println("list集合:"+list);
//排序
Collections.sort(list);
System.out.println("sort:"+list);
//二分查找
int index=Collections.binarySearch(list,11);
System.out.println("binarySearch:"+index);
//反轉集合中元素順序
Collections.reverse(list);
System.out.println("reverse:"+list);
//隨機置換
Collections.shuffle(list);
System.out.println("shuffle:"+list);
//求最大值
int max=Collections.max(list);
System.out.println("max:"+max);
}
}
(2)運行結果:
五、Exception
1、Throwable 類:Java 語言中所有錯誤或異常的超類。分為error和exception兩類。
2、Error:嚴重錯誤。例如:內存溢出。
3、Exception:異常
(1)運行時期異常:RuntimeException,編譯通過,但開發者代碼不嚴謹,無需顯示處理,可像編譯時期異常處理。
(2)編譯時期異常:非運行時期異常,編譯不能通過,開發者必須處理。
4、異常處理
(1)捕獲異常(標準):try...catch...finally
A、變形格式:try...catch.../try...catch...catch.../catch...等
B、標準格式:
try{
可能出現異常的代碼(越少越好)
}catch(異常類 異常類對象){
處理異常
當try中的異常正好與catch中的異常匹配時,此時會執行catch中的代碼
}finally{
釋放資源
}
C、處理多個異常(JDK7以後的功能):
try{
可能出現異常的代碼(越少越好)
}catch(異常類1|異常類2|異常類3…… 異常類對象){
處理異常
當try中的異常正好與catch中的異常匹配時,此時會執行catch中的代碼。
(catch中的異常必須為同一級別的異常)
}finally{
釋放資源(finally語句體一定會執行的,除非是Jvm退出。)
}
D、捕獲異常處理過程:執行try裏面的代碼,若出現異常,try會通過代碼中的問題創建一個異常對象,然後判斷異常對象和catch裏面的異常類是否一致, 如果一致,catch裏面的代碼就會執行Throwable裏面的方法。
(2)拋出異常:
A、throws...表示拋出異常,後面跟的異常類名,並且可以多個異常類名中間用逗號隔開。在方法上拋出,由調用者處理,表示拋出異常的可能性。
a、格式:修飾符 返回值 方法名() throws 異常類名{……}
b、throws拋出異常時,跟在方法後面。
B、throw...拋出異常,拋出的是一個異常對象。在語句體中拋出的,由語句體進行處理,表示拋出異常的肯定性。
a、格式:throw new 異常類名(),采用匿名對象的方式。
5、Throwable常用方法
(1)public String getMessage() :消息字符串
(2)public String toString(): 異常的簡短描述 ": ",由冒號和空格組成。
(3)public void printStackTrace():包含了消息字符串,還有": "信息描述,具體出現異常的代碼定位以及定位的源碼上。
上述三種方法,主要用在catch代碼部分。
6、自定義異常類
(1)方式1:自定義一個類,繼承自Exception
(2)方式2:自定義一個類,繼承自RuntimeException
(3)例如:
自定義類:
public class MyException extends Exception {
public MyException() {}
public MyException(String message) {
super(message);
}
}
測試類:
package 異常.自定義類異常;
import java.util.Scanner;
public class ExceptionTest {
public static void main(String[] args) throws MyException{
Scanner sc=new Scanner(System.in) ;
System.out.println("請輸入學生成績:");
int score=sc.nextInt();
//調用成績校驗方法
check(score);
}
public static void check(int score) throws MyException{
if(score<0||score>100) {
//拋出異常對象
throw new MyException("該學生成績不合理");
}else {
System.out.println("該學生成績合理!");
}
}
}
運行結果:
7、異常類中註意事項
(1)子類重寫父類的方法的時候,子類的方法的拋出的異常要麽是父類的方法異常一樣,要麽是父類方法異常的子類。
(2)子類重寫父類方法的時候,如果父類中的這個方法沒有拋出異常,那麽子類重寫的這個方法也不能拋出異常,只能try...catch。
(3)finally語句體一定會執行的,除非是Jvm退出。
8、常見面試題
(1)final、finally、finalize三者區別?
final:可修飾類,該類不能被繼承;修飾變量,該變量為常量;修飾成員方法,給成員方法不能被重寫。
finally:釋放資源。
finalize:與垃圾回收器有關的方法。gc(),運行垃圾回收器,實際是調用finalize()方法。
(2)如果catch裏面有return 語句,finally中的代碼還會執行,是在return語句之前執行還是return後執行?
finally中代碼一定會執行,是在return前執行。
(3)throws和throw的區別?
throws:表示拋出異常,後跟的異常類名,並且可以多個異常類名中間逗號隔開,在方法上拋出,由調用者處理,表示拋出異常的可能性。
throw:表示拋出異常,拋出的是一個異常對象,在語句體中拋出的,由語句體進行處理,表示拋出異常的肯定性。
六、File類
1、概述:表示文件或者目錄的路徑的抽象表現形式。
2、創建文件對象功能
(1)public File(String pathname):pathname的抽象路徑的表現形式,創建一個新 File 實例 (開發中使用)。
(2)public File(String parent,String child)根據 parent 路徑和 child 路徑創建一個新 File 實例。
(3)public File(File parent, String child)根據一個file對象和一個文件路徑來構造File實例。
上述三種方式都表示文件/目錄的路徑的抽象形式。
3、創建功能(返回值為能否創建成功)
(1)public boolean createNewFile():創建文件,當文件不存在的時候,創建此抽象路徑下的文件。
(2)public boolean mkdir():創建一個文件夾,若文件夾不存在,創建成功,否則創建失敗。
(3)public boolean mkdirs():創建文件夾,如果父目錄不存在,此目錄創建成功,否則是創建失敗。
(4)例如:
package File類.創建;
import java.io.File;
import java.io.IOException;
public class Chuangjian {
public static void main(String[] args) throws IOException{
File file1=new File("e:\\JavaSE\\大腦袋.txt");
System.out.println("creatNewFile:"+file1.createNewFile());
File file2=new File("e:\\BR");
System.out.println("mkdir:"+file2.mkdir());
File file3=new File("e:\\BR蘇蘇不酥");
System.out.println("mkdirs:"+file3.mkdirs());
}
}
4、刪除功能(返回值為是否刪除成功)
(1)public boolean delete():刪除文件或者文件夾(目錄不能是空的):逐一刪除文件或者目錄。
(2)例如:
package File類.刪除;
import java.io.File;
public class DelectFile {
public static void main(String[] args) {
File file=new File("e:\\JavaSE\\大腦袋.txt");
System.out.println("deleteFile:"+file.delete());
}
}
5、重命名功能(返回值為是否重命名成功)
(1)public boolean renameTo(File dest):重新命名此抽象路徑名表示的文件。
(2)若需重命名的文件與重命名的名稱路徑名一致,則只是重命名。若兩次路徑名稱不一致,則是重命名,並且剪切。
(3)例如:
package File類.renameToFile;
import java.io.File;
public class RenameToFile {
public static void main(String[] args) {
File file1=new File("e:\\BR");
File file2=new File("e:\\火娃");
System.out.println("RenameToFile:"+file1.renameTo(file2));
}
}
6、判斷功能
(1)public boolean isDirectory():判斷是否是文件夾。
(2)public boolean isFile() :判斷是否是文件。
(3)public boolean canRead(): 判斷是否可讀。
(4)public boolean canWriter():判斷是否可寫。
(5)public boolean exists() :判斷是否存在。
(6)public boolean isHidden():判斷是否是隱藏文件。
7、獲取功能(重點)
(1)public String getAbsolutePath()獲取抽象文件的絕對路徑。
(2)public String getPath()獲取相對路徑的字符串。
(3)public String getName()返回由此抽象路徑名表示的文件或目錄的名稱。
(4)public long length()返回由此抽象路徑名表示的文件的長度。
(5)public long lastModified()文件最後一次被修改的時間(時間毫秒值)
(6)例如:
package File類.獲取;
import java.io.File;
public class GetTest {
public static void main(String[] args) {
File file=new File("e:\\火娃");
System.out.println("getAbsolutePath:"+file.getAbsolutePath());
System.out.println("getPath:"+file.getPath());
System.out.println("getName:"+file.getName());
System.out.println("length:"+file.length());
System.out.println("lastModified:"+file.lastModified());
}
}
運行結果:
8、高級功能(重點)
(1)獲取當前某個路徑下的所有的文件夾以及文件名稱的字符串數組:
A、public String[] list()獲取全部
B、public String[] list(FilenameFilter filter)過濾後獲取
(2)獲取當前某個路徑下所有的文件夾以及文件的File數組:
A、public File[] listFiles()獲取全部
B、public File[] listFiles(FilenameFilter filter)過濾後獲取
補充:FilenameFilter,一個接口,文件名稱過濾器。
(3)例如:獲取f盤下所有文件夾/文件的名稱
package File類.高級;
import java.io.File;
public class GetEfile {
public static void main(String[] args) {
File file=new File("f:\\");
//獲取存儲文件名稱的字符串數組
String[] list=file.list();
//遍歷獲取的字符串數組
for(String str:list) {
System.out.println("String[]:"+str);
}
System.out.println("------------------------------");
//獲取存儲文件名稱的文件數組
File[] listfiles=file.listFiles();
//遍歷獲取的文件數組
for(File f:listfiles) {
System.out.println("File[]:"+f);
}
}
}
運行結果:
9、測試功能
(1)boolean accept(File dir, String name)測試指定文件是否應該包含在某一文件列表中。
(2)該方法是FilenameFilter接口中的方法,當高級功能過濾文件需要時,重寫該方法。
例題:判斷F盤下是否有後綴名為.rar的文件,若有輸出此文件名稱。
package File類.高級;
import java.io.File;
import java.io.FilenameFilter;
public class GuoLv {
public static void main(String[] args) {
File file=new File("F:\\");
//獲取存儲文件名稱的字符串數組,采用文件過濾器,匿名內部類方式篩選文件
String[] list=file.list(new FilenameFilter() {
//重寫FilenameFilter接口中的accept()方法
@Override
public boolean accept(File dir, String name) {
//創建文件對象,並指定路徑
File f=new File(dir,name);
//判斷是否為文件
boolean flag1=f.isFile();
//判斷後綴名是否為.rar
boolean flag2=name.endsWith(".rar");
return flag1&&flag2;
}
});
//遍歷獲取的字符串數組
for(String str:list) {
System.out.println("String[]:"+str);
}
}
}
運行結果:
10、路徑分類
(1)絕對路徑(帶盤符):盤符名:\xx\xx.後綴名
(2)相對路徑(不帶盤符):xx.後綴名
11、創建文件時,如果未寫盤符,創建位置:創建在當前的路徑項目下。
七、IO流(對文件進行操作)
1、概述:設備和設備之間的一種數據傳輸。
2、IO流分類
(1)按流的方向分:
A、輸入流:讀取文件,把硬盤上文件讀取出來後輸出文件內容。
B、輸出流:寫文件,將從某硬盤上讀取的內容,寫在另一硬盤上。
(2)按數據的類型劃分:
A、字節流(對文本文件進行操作時優先選擇)
a、字節輸入流:InputStream,讀取字節,讀取字節輸入流的所有類的超類。
b、字節輸出流:OutputStream,寫字節,寫字節輸出流的所有類的超類。
B、字符流
a、字符輸入流:Reader,讀取字符,讀取字符的抽象類。
b、字符輸出流:Writer,寫字符,寫字符的抽象類。
3、實例化
(1)使用字節流進行操作,無法創建字節輸入/出流對象InputStream/OutputSteam 抽象類,不能實例化,需要通過其子FileInputSteam/FileOutputSteam進行實例化。
(2)使用字節流進行操作,無法創建字符輸入/出流對象Reader/Wirter抽象類,不能實例化,需要通過其子FileReader/FileWirter進行實例化。
4、不同操作系統的換行符號
(1)windows:\r\n
(2)linux:\n
(3)mac:\r
(4)一些高級記事本對任何的換行符號都會有效果。
5、開發步驟
(1)創建字節/字符輸入/輸出流對象;
(2)讀/寫數據;
(3)關閉資源。
6、OutputStream
(1)概述:抽象類,字節輸出流。
(2)子實現類:FileOutputStream
(3)例如:給e盤中火娃文件夾中的大腦袋文件寫入“br”內容:
package IO流.OutputStream類;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class OutputStreamDemo {
public static void main(String[] args) throws FileNotFoundException,IOException{
//創建字節輸出流對象
FileOutputStream fos=new FileOutputStream("e:\\火娃\\大腦袋");
//使用流對象給文件寫數據
fos.write("br".getBytes());
//關閉資源
fos.close();
}
}
7、字節輸出流寫數據方法
(1)public void write(int b):一次寫一個字節
(2)public void write(byte[] b) :一次寫一個字節數組
(3)public void write(byte[] b, int off,int len):一次寫一部分字節數組
(4)例如:
package IO流.OutputStream類;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class OutputFangfa {
public static void main(String[] args) throws FileNotFoundException,IOException{
//創建字節輸出流對象
FileOutputStream fos=new FileOutputStream("e:\\火娃\\大腦袋");
//一次寫一個字節
fos.write(97);
//定義一個字節數組
byte[] bys= {97,48,98};
//一次寫一個字節數組
fos.write(bys);
//一次寫字節數組的一部分
fos.write(bys,0,2);
//關閉資源
fos.close();
}
}
8、末尾追加數據功能
(1)public FileOutputStream(File file, boolean append):指定為true,末尾追加數據。
(2)例如:
package IO流.OutputStream類;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class AppendDemo {
public static void main(String[] args) throws FileNotFoundException,IOException{
//創建字節輸出流對象
FileOutputStream fos=new FileOutputStream("e:\\火娃\\大腦袋",true);
//寫數據
for(int x=0;x<10;x++) {
//追加內容
fos.write(("hello"+x).getBytes());
fos.write(("\r\n"+x).getBytes());
}
//關閉資源
fos.close();
}
}
9、IO流中加入異常處理
(1)標準格式:try...catch...finally...
(2)註意事項:finally訪問該對象時,需將該對象放在try語句外面。
(3)例如:
package IO流.OutputStream類;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class IOexceptin {
public static void main(String[] args) throws FileNotFoundException,IOException{
//創建字節輸出流對象
FileOutputStream fos=null;
try {
fos=new FileOutputStream("e:\\火娃\\大腦袋");
fos.write("bighead".getBytes());
}catch(IOException e){
//處理異常
e.printStackTrace();
}finally {//釋放資源
if(fos!=null) {
try {
fos.close();
}catch(IOException e1){
e1.printStackTrace();
}
}
}
}
}
10、InputStream
(1)概述:抽象類,字節輸入流。
(2)子實現類:FileInputStream
(3)構造方法:public FileInputStream(String name)
11、數據讀取方式
(1)public abstract int read()一次讀取一個字節
(2)public int read(byte[] b)一次讀取一個字節數組 (讀取實際的字節數),指定字節數的長度時一般指定為1024的倍數。(效率大於第一種方式)。
(3)例如:
方法一:一次讀取一個字節
package IO流.InputStream;
import java.io.FileNotFoundException;
import java.io.FileInputStream;
import java.io.IOException;
public class ReadDemo {
public static void main(String[] args) throws FileNotFoundException,IOException{
//創建字節輸出流對象
FileInputStream fis=new FileInputStream("e:\\火娃\\大腦袋");
int by=0;
//當fis文件不為空時讀取字節
while((by=fis.read())!=-1) {
System.out.println((char)by);
}
//關閉資源
fis.close();
}
}
方法二:一次讀取一個字節數組
package IO流.InputStream;
import java.io.FileNotFoundException;
import java.io.FileInputStream;
import java.io.IOException;
public class ReadDemo {
public static void main(String[] args) throws FileNotFoundException,IOException{
//創建字節輸出流對象
FileInputStream fis=new FileInputStream("e:\\火娃\\大腦袋");
int by=0;
//當fis文件不為空時讀取字節
while((by=fis.read())!=-1) {
System.out.println((char)by);
}
//關閉資源
fis.close();
}
}
11、復制文件
(1)讀取源文件:FileInputStream
(2)輸出目的地文件:FileOutputStream
(3)例1:復制文本文件,一次讀取一個字節
package IO流.Copy;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class Copy1 {
public static void main(String[] args) throws FileNotFoundException, IOException{
//定義源文件輸入流對象
FileInputStream fis=new FileInputStream("e:\\BR蘇蘇不酥\\大腦袋");
//定義目的地文件輸出流對象
FileOutputStream fos=new FileOutputStream("e:\\BR蘇蘇不酥\\bighead");
int by=0;
while((by=fis.read())!=-1) {
fos.write(by);
}
fos.close();
fis.close();
}
}
(4)例2:復制jpg文件,一次讀取一個字節數組
package IO流.Copy;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class Copy2 {
public static void main(String[] args) throws FileNotFoundException, IOException{
//定義源文件輸入流對象
FileInputStream fis=new FileInputStream("e:\\BR蘇蘇不酥\\大腦袋.jpg");
//定義目的地文件輸出流對象
FileOutputStream fos=new FileOutputStream("e:\\BR蘇蘇不酥\\bighead.jpg");
byte[] by=new byte[1024];
int len=0;
while((len=fis.read())!=-1) {
fos.write(by,0,len);
}
fos.close();
fis.close();
}
}
Java基礎知識(八)