這一塊的內容主要是有關Collections工具類、例外,以及File檔案的主要內容
Collections工具類
Collections工具類的概述:
可以針對ArrayList存盤基本包裝類的元素進行排序
Collection和Collections的區別
- Collection是單列集合的頂層介面,有兩大子介面List和Set
- Collections是針對集合操作的工具類,可以針對集合進行排序,以及查找(二分查找)
需要熟知的方法
public static void sort(List list)
public static int binarySearch(List<?> list,T key)
public static T max(Collection<?> coll)
public static void reverse(List<?> list)
public static void shuffle(List<?> list)
代碼舉例:
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(100);
list.add(23);
list.add(200);
list.add(10);
System.out.println(list);
//排序(升序)
Collections.sort(list);
System.out.println(list);
//使用二分查找尋找串列中數字100的位置
int i = Collections.binarySearch(list, 100);
System.out.println(i);
//回傳集合中最大的數字
Integer max = Collections.max(list);
System.out.println(max);
//將集合反轉
Collections.reverse(list);
System.out.println(list);
System.out.println("*****隨機置換*****");
//打亂排序
Collections.shuffle(list);
System.out.println(list);
}
}
//[100, 23, 200, 10]
//[10, 23, 100, 200]
//2
//200
//[200, 100, 23, 10]
//*****隨機置換*****
//[10, 23, 100, 200]
對ArrayList存盤的自定義物件排序
我們可以看到一共有兩種排序,第一個是自然排序,第二個是比較器排序

方式一:自然排序
但是在使用自然排序的時候,我們的Studet類要實作Comparable介面

不然會出現這個錯誤

繼承之后的Student類
class Student implements Comparable<Student>{
private String name;
private int age;
public int compareTo(Student student){
int i = this.getAge() - student.getAge();
int i1 = i == 0 ? this.getName().compareTo(student.getName()) : i;
return i1;
}
Student(){}
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;
}
Student(String name, int age){
this.name = name;
this.age = age;
}
}
public static void main(String[] args) {
ArrayList<Student> students = new ArrayList<Student>();
Student s1 = new Student("zhangsan", 21);
Student s2 = new Student("lisi", 25);
Student s3 = new Student("wangwu", 28);
Student s4 = new Student("zhaoliu", 22);
students.add(s1);
students.add(s2);
students.add(s3);
students.add(s4);
//自然排序
Collections.sort(students);
for(Student s:students){
System.out.println(s.getName()+"---"+s.getAge());
}
}
}
//zhangsan---21
//zhaoliu---22
//lisi---25
//wangwu---28
方式二:比較器排序
public static void main(String[] args) {
ArrayList<Student> students = new ArrayList<Student>();
Student s1 = new Student("zhangsan", 21);
Student s2 = new Student("lisi", 25);
Student s3 = new Student("wangwu", 28);
Student s4 = new Student("zhaoliu", 22);
students.add(s1);
students.add(s2);
students.add(s3);
students.add(s4);
//自然排序
Collections.sort(students);
Collections.sort(students, new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
int i = o1.getAge() - o2.getAge();
int i1 = i == 0 ? o1.getName().compareTo(o2.getName()) : i;
return i1;
}
});
for(Student s:students){
System.out.println(s.getName()+"---"+s.getAge());
}
}
}
例外
什么是例外
程式出現了不正常的情況
程式的例外:Throwable
嚴重的問題
Error我們不處理,這種問題一般都是比較嚴重的,比如說記憶體溢位OOM
問題:例外Exception
運行時例外
RuntimeException 這種問題我們也不進行處理,因為這種問題是你自己的問題,比如說代碼不嚴謹
編譯時例外
不是RuntimeException的,就是編譯時期例外,必須要進行處理,如果不處理,程式編譯不通過,無法運行
如果程式出現了問題,我們沒有做任何處理,最終JVM會做出默認的處理,把例外的名稱,相關原因,以及出現的問題資訊輸出在控制臺,同時程式會結束,后面的代碼不會運行
代碼舉例:
我們可以看到,當我們沒有寫if判斷的時候,控制臺列印出來:ArithmeticException
這屬于運行時例外,是我們必須要進行處理的,我們加上一個if判斷,程式就不走這行代碼了
public static void main(String[] args) {
int a = 10;
int b = 0;
if(!(b==0)){
System.out.println(a/b);
}
//ArithmeticException: / by zero
// System.out.println(a/b);
System.out.println("over");
}
}
//over
如何處理例外
- try…catch…finally
- thorws 拋出
try…catch…finally處理格式
try{
可能會出現問題的代碼
}catch(例外類名 變數名){
針對問題的處理;
}finally{
釋放資源;
}
try…catch…finally變形格式
try{
可能會出現問題的代碼
}catch(例外類名 變數名){
針對問題的處理;
}
注意
- try里面的代碼越少越好
- catch里面必須要有內容,哪怕只是一句簡單的提示
public static void main(String[] args) {
int a = 10;
int b = 0;
try{
System.out.println(a/b);
}catch (ArithmeticException e){
System.out.println("除數不能為0");
}
System.out.println("over");
}
}
//除數不能為0
//over
處理例外的注意點
1、處理一個例外
2、處理兩個例外
1)每一個寫一個try…catch
2)寫一個try,多個catch
try{
可能會出現問題的代碼;
}catch(例外類名 變數名){
針對問題的處理;
}catch(例外類名 變數名){
針對問題的處理;
}catch(例外類名 變數名){
針對問題的處理;
}
注意:
- 能明確例外的型別盡量明確,不要用大的處理(Exception)
- 評級的關系例外誰在誰前誰后無所謂,如果出現了父子繼承關系,父必須在后面
- 一旦try里面的代碼出錯了,就回去匹配catch里面的例外,繼續執行后面的代碼
代碼舉例:
public class ExceptionDemo3 {
//處理一個例外
private static void fun1(){
int a = 10;
int b = 0;
try{
System.out.println(a/b);
}catch (ArithmeticException e){
System.out.println("除數不能為0");
}
}
//處理兩個例外
private static void fun2(){
int a = 10;
int b = 0;
try{
System.out.println(a/b);
}catch(ArithmeticException e){
System.out.println("除數不能為0");
}
int []arr = new int[]{1,2,3};
try {
System.out.println(arr[3]);
}catch (IndexOutOfBoundsException e){
System.out.println("陣列下標越界例外");
}
}
private static void fun3(){
int a = 10;
int b = 0;
int []arr = new int[]{1,2,3};
try {
System.out.println(a/b);
System.out.println(arr[3]);
} catch (ArithmeticException e){
System.out.println("除數不能為0");
}catch (IndexOutOfBoundsException e){
System.out.println("陣列下標越界例外");
}catch (Exception e){
System.out.println("例外的父類");
}
}
public static void main(String[] args) {
//處理一個例外
fun1();
System.out.println("*************");
//處理兩個例外
fun2();
System.out.println("*************");
fun3();
}
}
//除數不能為0
//*************
//除數不能為0
//陣列下標越界例外
//*************
//除數不能為0
JDK7的新特性以及注意事項,新的處理例外的方式
try{
可能出現問題的代碼
}catch(例外類名1|例外類名2|…變數){
…
}
注意事項
- 處理方式是一致的,這個方式雖然簡潔,但是也不夠好,針對多種型別的問題,只給出了一種解決方案
- 多個例外之間必須是平級關系
private static void fun(){
int a = 10;
int b = 0;
int []arr = new int[]{1,2,3};
try {
System.out.println(a/b);
System.out.println(arr[3]);
}catch (ArithmeticException|ArrayIndexOutOfBoundsException e){//這里多個例外之間必須是平級關系,不能出現Exception
System.out.println("出現了問題");
}
}
public static void main(String[] args) {
fun();
}
}
//出現了問題
編譯時例外和運行時例外的區別
- 編譯時期例外:Java程式必須要顯示處理,否則程式就會發生錯誤,無法通過編譯
- 運行時期例外:無須顯示處理,但是也可以和編譯時期例外一樣處理
編譯時期例外:
如果不對sdf.parse()進行一個try catch,會編譯出錯
public static void main(String[] args) {
String s = "20211-8-14";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try{
Date date = sdf.parse(s);
}catch (ParseException e){
System.out.println("日期決議出錯");
}
}
}
//日期決議出錯
例外中需要掌握的方法
- getMessage()
獲取例外資訊,回傳字串 - toString()
獲取例外類名和例外資訊,回傳字串
回傳此可拋出的簡短描述, 結果是:
這個物件的類的name
“:”(一個冒號和一個空格)
呼叫這個物件的getLocalizedMessage()方法的結果
默認回傳的是getMessage()的內容
如果getLocalizedMessage回傳null ,那么只回傳類名 - printStackTrace()
獲取例外類名和例外資訊,以及例外出現在程式中的位置,回傳void
代碼舉例:
public static void main(String[] args) {
String s = "2021-8-14";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {
Date date = sdf.parse(s);
System.out.println(date);
}catch (ParseException e){
//獲取例外資訊,回傳字串
System.out.println(e.getMessage());
//獲取例外類名和例外資訊,回傳字串
System.out.println(e.toString());
e.printStackTrace();
}
}
}
//Unparseable date: "2021-8-14"
//java.text.ParseException: Unparseable date: "2021-8-14"
//java.text.ParseException: Unparseable date: "2021-8-14"
// at java.text.DateFormat.parse(Unknown Source)
// at com.bigdata.shujia21.ExceptionDemo6.main
拋出例外
拋出例外的引入
有些時候,我們可以對例外進行處理,但是有些時候,我們根本沒有權限去處理某個例外,或者說,我們處理不了,就干脆不處理了,為了解決這樣的問題,并且程式還能繼續運行,Java針對這種情況,提供了另一個處理方案:拋出
格式:
throws 例外類名
注意:這個格式必須跟在方法的括號后面
注意:
盡量不要在main方法上拋出
總結:
- 編譯時期例外拋出,將來呼叫者必須要做處理
- 運行時期例外拋出,將來呼叫者可以不做處理
fun1中出現了編譯時期例外,main函式呼叫的時候,必須要做處理
fun中出現了運行時期例外,main函式呼叫的時候,可以不做處理
public static void main(String[] args) {
fun();
fun1();//這一行會出錯
}
private static void fun()throws ArithmeticException{
int a = 10;
int b = 0;
System.out.println(a/b);
}
private static void fun1() throws ParseException {
String s = "2021-8-14";
SimpleDateFormat asd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = asd.parse(s);
System.out.println(date);
}
}
throw和throws
throw:如果出現了例外情況,我們就應該把例外拋出
這個時候throw拋出的是例外的物件
public static void main(String[] args) {
fun();
try {
fun2();
}catch (Exception e){
e.printStackTrace();
}
}
private static void fun2()throws Exception{
int a = 10;
int b = 0;
if(b==0){
throw new Exception();
}else {
System.out.println(a/b);
}
}
private static void fun(){
int a = 10;
int b = 0;
if(b == 0){
System.out.println("這里b=0");
throw new ArithmeticException();
}else{
System.out.println(a/b);
}
}
finally
finally:被finally控制的陳述句體一定會執行
特殊情況:在執行到finally之前JVM推出了(比如System.exit(0))
格式:
try…catch…finally…
finally在生活中,在開發程序中有什么作用呢?
一般用于釋放資源,在IO流操作和資料操作的時候經常見到
public static void main(String[] args) {
String s = "2021-8-14";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = null;
try{
date = sdf.parse(s);
}catch (Exception e){
e.printStackTrace();
}finally {
System.out.println("finally一般用于釋放資源");
}
System.out.println(date);
}
}
//finally一般用于釋放資源
//java.text.ParseException: Unparseable date: "2021-8-14"
//null
// at java.text.DateFormat.parse(Unknown Source)
// at com.bigdata.shujia21.FinallyDemo1.main(FinallyDemo1.java:13)
面試題:final、finally、finalize的區別
-
final:最終的意思,可以修飾類、成員變數、成員方法
- 修飾類,類不能被繼承
- 修飾變數,變數變成常量
- 修飾方法,方法不能重寫
-
finally:是處理例外的一部分,用于釋放資源,一般來說都會執行,
特殊情況:在執行到finally之前JVM退出了(比如System.exit(0)) -
finalize:是Object中的一個方法,用于垃圾回收,堆記憶體空間沒有參考指向它,手動回收
-
如果catch里面有return陳述句,finally的代碼還會執行嗎?
會,在return前,
代碼舉例:
public static void main(String[] args) {
System.out.println(getInt());
}
private static int getInt() {
int a = 10;
try {
System.out.println(a / 0);
a = 20;
} catch (Exception e) {
a = 30;
return a;
/*
在這里,return a執行到這一步的時候,這里不是return a,而是return 30
從這里開始,就已經形成了回傳路徑,已經有東西回傳了,但是,
它發現后面還有finally,就會繼續執行finally的內容,a=40
再次回到之前的路徑,繼續往前走return 30
*/
} finally {
a = 40;
}
return a;
}
自定義例外
java中不可能把所有的情況都考慮到,所以在開發中,可能會自己定義例外
但是我們,我自己隨便寫的一個類它僅僅是普通的類,不是例外類,于是需要繼承Exception,或者RuntimeException
public class MyException extends Exception{
public MyException() {
}
public MyException(String message) {
super(message);
}
}
public class ExceptionStudentDemo {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("請輸入學生的成績:");
int score = sc.nextInt();
Teacher t = new Teacher();
try{
t.check(score);
}catch (MyException me){
me.printStackTrace();
}
}
}
public class Teacher {
public void check(int score) throws MyException{
if(score<0 || score>100){
throw new MyException("分數有誤,必須在0-100之間");
}else {
System.out.println("分數沒問題");
}
}
}
File
File的引入
我們要想實作IO操作,就必須知道硬碟上檔案的表現形式
Java就提供了一個類供我們使用:File
File:檔案和目錄(檔案夾)路徑名的抽象表現形式
構造方法
- File(File parent, String child)
從父抽象路徑名和子路徑名字串創建新的 File實體, - File(String pathname)
通過將給定的路徑名字串轉換為抽象路徑名來創建新的 File實體, - File(String parent, String child)
從父路徑名字串和子路徑名字串創建新的 File實體,
代碼舉例:
public static void main(String[] args) {
//File(String pathname) 根據一個路徑得到File物件
File file = new File("D:\\demo\\a.txt");
System.out.println(file);
//File(String parent, String child) 根據一個目錄和一個子檔案/目錄得到File物件
File file1 = new File("D:\\demo", "a.txt");
System.out.println(file1);
//File(File parent, String child) 根據一個父File物件和一個子檔案/目錄得到File物件
File file2 = new File("D:\\demo");
File file3 = new File(file2, "a.txt");
System.out.println(file3);
}
}
//D:\demo\a.txt
//D:\demo\a.txt
//D:\demo\a.txt
創建功能
- public boolean createNewFile()
- public boolean mkdir()
- public boolean mkdirs()
public static void main(String[] args) {
//需求:D盤下,創建demo2檔案夾
//public boolean mkdir() 創建檔案夾,如果已經存在這樣的檔案夾,就不創建了,回傳false
File file = new File("D:\\demo2");
System.out.println(file.mkdir());
//需求:D盤demo2下,創建檔案b.txt
File file1 = new File("D:\\demo2\\a.txt");
try {
System.out.println(file1.createNewFile());
} catch (IOException e) {
e.printStackTrace();
}
//public boolean mkdirs()
//創建多級目錄,多級檔案夾
File file2 = new File("D:\\demo2\\demo3\\demo4");
System.out.println(file2.mkdirs());
}
//false
//false
//true
洗掉功能
public boolean delete()
代碼:
public static void main(String[] args) {
File file = new File("a.txt");
try {
System.out.println(file.createNewFile());
} catch (IOException e) {
e.printStackTrace();
}
File file1 = new File("demo\\demo2\\demo3");
System.out.println(file1.mkdirs());
File file2 = new File("a.txt");
System.out.println(file2.delete());
//要洗掉以一個檔案夾,必須目錄為空才能洗掉
File file3 = new File("demo\\demo2\\demo3");
System.out.println(file3.delete());
File file4 = new File("demo\\demo2");
System.out.println(file4.delete());
File demo = new File("demo");
System.out.println(demo.delete());
}
重命名功能
public boolean renameTo(file dest)
public static void main(String[] args) throws IOException {
//創建一個檔案物件
File file = new File("a.txt");
// System.out.println(file.createNewFile());
//現在我想重名為 b.txt
File file1 = new File("b.txt");
System.out.println(file.renameTo(file1));
}
判斷功能
- public boolean isDirectory()
- public boolean isFile()
- public boolean exists()
- public boolean canRead()
- public boolean canWrite()
- public boolean isHidden()
public static void main(String[] args) {
File file = new File("a.txt");
try {
System.out.println(file.createNewFile());
} catch (IOException e) {
e.printStackTrace();
}
//public boolean isDirectory() 判斷是否是檔案夾
System.out.println(file.isDirectory());
//public boolean isFile() 判斷是否是檔案
System.out.println(file.isFile());
//public boolean exists() 判斷File物件是否存在
System.out.println(file.exists());
//public boolean canRead() 判斷是否可讀
System.out.println(file.canRead());
//public boolean canWrite() 判斷是否可寫
System.out.println(file.canWrite());
//public boolean isHidden() 判斷是否隱藏
System.out.println(file.isHidden());
}
基本獲取功能
- public String getAbsolutePath()
- public String getPath()
- public String getName()
- public long length()
- public long lastModified()
代碼舉例:
public static void main(String[] args) {
File demo = new File("demo");
demo.mkdir();
File file = new File("demo\\a.txt");
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
//public String getAbsolutePath()
//獲取絕對路徑,或者說是完整路徑
String absolutePath = file.getAbsolutePath();
System.out.println(absolutePath);
//public String getPath()
//獲取相對路徑
String path = file.getPath();
System.out.println(path);
//public long length()
//獲取的長度是位元組數
File file1 = new File("D:\\BigDaTa\\JavaProject\\demo\\a.txt");
System.out.println(file1.length());
//public long lastModified()
//獲取到的是時間戳,精確到毫秒
System.out.println(file.lastModified());
//1628929592356
//時間戳與日期的轉換
Date date = new Date(1628929592356L);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String s = sdf.format(date);
System.out.println(s);
}
高級獲取功能
- public String[] list()
- public File[] listFiles()
代碼舉例:
public static void main(String[] args) {
File file = new File("D:\\照片,");
//public String[] list()
//獲取指定目錄下的所有檔案或者檔案夾的名稱陣列
String[] list = file.list();
for(String s:list){
System.out.println(s);
}
System.out.println("**********************");
//public File[] listFiles()
///獲取指定目錄下的所有檔案或者檔案夾的File陣列
File[] files = file.listFiles();
for(File f:files){
System.out.println(f.getName());
}
}
小案例,獲取一個目錄里面所有帶jpg后綴的檔案
public static void main(String[] args) {
//獲取file物件
File file = new File("D:\\照片,");
//獲取該目錄下所有檔案和檔案夾的陣列
File[] files = file.listFiles();
//定義一個儲存集合的名字
ArrayList<String> strings = new ArrayList<String>();
//遍歷file陣列,得到每一個file物件,然后判斷是否是檔案
int count = 0;
for(File f:files){
//判斷是否是檔案
if(f.isFile()){
//繼續判斷是否是.jpg結尾
if(f.getName().endsWith(".jpg")){
count++;
//輸出檔案名稱
strings.add(f.getName());
}
}
}
System.out.println("該目錄下有"+count+"個以.jpg為后綴的檔案");
System.out.println("分別是:");
for(String s:strings){
System.out.println(s);
}
}
感謝閱讀,我是啊帥和和,一位大資料專業即將大四學生,祝你快樂,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/293905.html
標籤:其他
上一篇:Spark核心編程
下一篇:一文詳細決議kafka重平衡機制
