常用類
常用類概述:
-
內部類
-
Object類
-
包裝類
-
數學類
-
時間類
-
字串
-
String Builder和StringBuffer
-
DecimalFormat
一、內部類
概念:在一個類內部再定義一個完整的類。
一般情況下類與類之間是相互獨立的,內部類的意思就是打破這種獨立思想,讓一個類成為另一個類的內部資訊,和成員變數、成員方法同等級別。
內部類的好處:
把一個類寫在外面和寫在裡面最終達到的結果都一樣,那我們為什麼還要使用內部類,豈不是多此一舉嗎?
採用內部類這種技術,可以隱藏細節和內部結構,封裝性更好,讓程式的結構更加合理!如果類很多且都暴露在外面,那麼類與類之間的呼叫就會十分繁瑣!
內部類的分類:
1.成員內部類(非靜態內部類)
【參考程式碼】
package NeiBuLei;
public class OuterClass {
//成員變數
private String OuterName;
//成員方法
public void display(){
System.out.println("這是外部類方法!");
System.out.println(OuterName);
}
//內部類
public class InnerClass{
//成員變數
private String InnerNme;
//構造方法
public InnerClass() {
InnerNme = "Inner Class";
}
//成員方法
public void display(){
System.out.println("這是內部類方法!");
System.out.println(InnerNme);
}
}
// 主方法
public static void main(String[] args) {
OuterClass outerClass = new OuterClass();
outerClass.display();//這是外部類方法! null
// 這個類是內部類,已經不是獨立的類了,因此不能像外部類一樣直接建立!
//InnerClass innerClass = new InnerClass(); 行不通
OuterClass.InnerClass innerClass = outerClass.new InnerClass();// 同成員方法/變數 只是加了個字首
innerClass.display();// 這是內部類方法!
}
}
輸出結果:
這是外部類方法!
null
這是內部類方法!
Inner Class
總結:成員內部類(非靜態內部類)的使用就是將內部類作為外部類的的一個成員變數/成員方法來使用,所以必須依賴於外部類的物件才能呼叫,用法和成員變數/成員方法一致!
2.區域性內部類
區域性內部類:基本的內部類還可以在一個方法體中定義。
package NeiBuLei;
public class OuterClass {
//成員變數
private String OuterName;
//成員方法
public void display(){
class InnerClass {
public void print(){
System.out.println("這是一個區域性內部類方法!");
}
}
InnerClass innerClass = new InnerClass();
innerClass.print();
}
// 主方法
public static void main(String[] args) {
OuterClass outerClass = new OuterClass();
outerClass.display();
}
}
3.靜態內部類
靜態內部類的構造不需要依賴於外部類物件,類中的靜態元件都不需要依賴於任何物件,可以直接通過類本身進行構造。
package NeiBuLei;
public class OuterClass {
//成員變數
private String OuterName;
//成員方法
public void display(){
System.out.println("這是外部類方法!");
System.out.println(OuterName);
}
//靜態內部類
public static class InnerClass{
private String InnerName;
public InnerClass() {
InnerName = "Inner Class";
}
//成員方法
public void display(){
System.out.println("這是靜態內部類方法!");
System.out.println(InnerName);
}
}
// 主方法
public static void main(String[] args) {
OuterClass outerClass = new OuterClass();
outerClass.display();
// 靜態內部類的構造不依賴與外部類,可以直接通過類本身進行構造!
InnerClass innerClass = new InnerClass();
innerClass.display();
}
}
輸出結果:
這是外部類方法!
null
這是靜態內部類方法!
Inner Class
4.匿名內部類
匿名內部類:沒有名字的內部類。
匿名內部類主要應用與介面的實現!
介面:
package NeiBuLei;
public interface MyInterface {
public void test();
}
實現類:
package NeiBuLei;
public class MyImplement implements MyInterface{
@Override
public void test() {
System.out.println("test");
}
}
匿名內部類的使用:
package NeiBuLei;
public class Test {
public static void main(String[] args) {
//實現類
MyInterface myInterface = new MyImplement();
myInterface.test();
//匿名內部類
MyInterface myInterface1 = new MyInterface() { // 介面是不能new的,這裡new的是介面的實現類(和實現類是一樣的(同一個東西),沒有例項而已)
@Override
public void test() {
System.out.println("test");
}
};
myInterface.test();
/**
* 最終兩種實現方式的結果都是一樣的!
*/
}
}
匿名內部類的好處:
我們定義介面之後,它的實現類不需要去單獨建立一個檔案去寫它的實現,我們可以把這個實現類的操作寫到我們呼叫的地方就可以了!寫起來更加簡潔、方便。
匿名內部類的缺點:
耦合度太高了!
二、Object類
Object類常用方法:
1.equals方法
==
與equals
的對比【面試題】+ jdk檢視原碼
==是一個比較運算子
-
==: 既可以判斷基本型別,又可以判斷引用型別
-
==: 如果判斷的是基本型別,判斷的是值是否相等。
//==: 如果判斷的是基本型別,判斷的是 值 是否相等 int x1 = 10; int x2 = 10; double x3 = 10.0; System.out.println(x1 == x2);//true System.out.println(x1 == x3);//true
-
==: 如果判斷的是引用型別,判斷的是地址是否相等,即判斷是不是同一個物件
package Equals; public class Test01 { public static void main(String[] args) { //==: 如果判斷的是引用型別,判斷的是地址是否相等,即判斷是不是同一個物件 A a = new A(); A b = a; A c = b; System.out.println(a==c);// ? true System.out.println(b==c);// true B obj = a; System.out.println(obj==c);// true } } class B{} class A extends B{}
- equals方法是Object類中的方法,只能判斷引用型別。
idea檢視Jdk原碼:滑鼠游標放在要檢視的方法上,直接輸入
ctrl + b
檢視某個類所有方法:
ctrl + F12
- 預設判斷的是地址是否相等,子類(Object類是所有類的父類)往往重寫該方法,用於判斷內容是否相等。
/*
Object類 equals()方法原碼
//預設判斷地址是否一樣
public boolean equals(Object obj) {
return (this == obj);
}
子類往往重寫該方法,用於判斷內容是否相等 String類中的equals()方法原碼(重寫了父類equals()方法)
public boolean equals(Object anObject) {
if (this == anObject) { // 如果是同一個物件(地址相同)
return true; // 返回true
}
if (anObject instanceof String) { // 判斷型別
String anotherString = (String)anObject; // 向下轉型
int n = value.length;
if (n == anotherString.value.length) { // 如果長度相同
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) { // 比較每一個字元
if (v1[i] != v2[i])
return false;
i++;
}
return true; // 如果兩個字串每一個字元都相同,則返回true
}
}
return false;
}
*/
在看個例子
【小練習】
寫出輸出結果:
package Equals;
public class EqualsTest01 {
public static void main(String[] args) {
Person p1 = new Person();
p1.name = "tom";
Person p2 = new Person();
p2.name = "tom";
System.out.println(p1 == p2);// 引用型別——判斷是否為同一個物件(地址)
System.out.println(p1.name.equals(p2.name));// p.name是String型別,重寫了equals()方法——判斷內容是否一樣
System.out.println(p1.equals(p2));//p1,p2屬於Person類,該類並沒有重寫equals()方法(繼承父類equals()方法,即判斷地址)
String s1 = new String("abc");
String s2 = new String("abc");
System.out.println(s1.equals(s2));
System.out.println(s1 == s2);
}
}
class Person{
public String name;
}
輸出結果:
false
true
false
true
false
2.hashCode方法
小結:(可以當作地址來看但它本質上不是地址)
- 提高具有雜湊結構的容器的效率
- 兩個引用,如果指向的是同一個物件,則雜湊值肯定一樣
- 兩個引用,如果指向的是不同物件,則雜湊值是不一樣的
- 雜湊值主要根據地址號來!不能將雜湊值完全等價於地址
- 在後面的集合中hashCode如果需要的話,也會重寫
package hashCode;
public class HashCode {
public static void main(String[] args) {
AA aa = new AA();
AA aa2 = new AA();
AA aa3 = aa;
System.out.println("aa.hashCode()="+ aa.hashCode());
System.out.println("aa2.hashCode()="+ aa2.hashCode());
System.out.println("aa3.hashCode()="+ aa3.hashCode());
}
}
class AA{}
aa.hashCode()=460141958
aa2.hashCode()=1163157884
aa3.hashCode()=460141958
3.toString方法
基本介紹:
預設返回:全類名 + @ + 雜湊值的十六進位制
/*
Object toString()原碼
//(1)getClass().getName() 類的全類名(包名+類名)
//(2)Integer.toHexString(hashCode()) 將hashCode的值轉成16進位制字串
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
*/
子類往往重寫toString方法,用於返回物件的屬性資訊(快捷鍵:alt + insert
),當然我們也可以自己定製。
當我們輸出一個物件時,toString()方法會被預設呼叫
4.finzlize方法
finzlize方法:當垃圾收集確定不再有對該物件的引用時,垃圾收集器在物件上呼叫該物件。
- 當物件被回收時,系統自動呼叫該物件的finzlize方法。子類可以重寫該方法,做一些釋放資源的操作
- 什麼時候被回收:當某個物件沒有任何引用時,則jvm就認為這個物件是一個垃圾物件,就會時候垃圾回收機制來銷燬該物件,在銷燬該物件前,會先呼叫finzlize方法。
- 垃圾回收機制的呼叫,是由系統來決定(即有自己的GC演算法),也可以通過System.gc()主動觸發垃圾回收機制。
注:在實際開發中,幾乎不會用finzlize方法,更多的是為了應付面試
三、包裝類
1.基本資料型別以及對應的包裝類:
byte -> Byte
short -> Short
int -> Integer
long -> Long
float -> Float
double -> Double
char -> Character
boolean -> Boolean
這些類都在java.lang包
2.包裝類的意義:
- 讓基本資料型別有物件導向的特徵
- 封裝了字串轉化成基本資料型別的方法(重點)
3.包裝類常用方法:
-
Integer.parseInt()
-
Long.paseLong()
-
Double.parseDouble()
【參考程式碼】
public class Test {
public static void main(String[] args) {
// Integer i = new Integer(10);// 建立包裝類物件
// Integer ii = 10; // 自動打包
// System.out.println(i+10); // 在使用上,int 和Integer 其實沒有區別,可以互相使用
// System.out.println(ii+10);
// int j = ii;// 自動解包
// System.out.println(j+100);
String a = "12";
String b = "34";
System.out.println(a+b); // 1234
// 轉型:
// 字串轉成int的唯一方案
int c = Integer.parseInt(a);
int d = Integer.parseInt(b);
System.out.println(c+d); // 46
// 字串轉成double型別
String e = "1.25";
double f = Double.parseDouble(e);
System.out.println(f*6); // 7.5
// 轉成long型別
long l = Long.parseLong("1234567");
System.out.println(l);
}
}
四、數學類
數學類的方法都是靜態方法,可以直接引用——Math.方法();
常用數學類方法:
- abs():獲取絕對值
- max():求最大值
- min():求最小值
- pow():求次冪
- round():四捨五入
- sqrt():求平方根
五、時間類
Java常用時間類:
-
Date 日期類
-
Calendar 日曆類
-
SimpleDateFormat 格式化時間類
Date和Calendar類 在java.util包中
SimpleDateFormat類 在java.text包
1.Date 日期
【1】new Date() 可以獲取到系統時間
【2】getTime() 能獲取到時間的long形式,可以用來計算時間差
getTime()——獲取計算機底層儲存的數字,返回一個數字用來表示時間,這個數字的型別long,單位為毫秒。
【參考程式碼】
import java.util.Date;
public class Test {
public static void main(String[] args) {
Date d = new Date();
System.out.println(d); // 系統時間
//get...()——獲取年月日.....
System.out.println(d.getYear()+1900); // 從1900年開始算的
System.out.println(d.getMonth()+1); // 月份從0開始計算
System.out.println(d.getDate()); // 天數
System.out.println(d.getHours());// 小時
//getTime()——獲取到時間的毫秒形式 返回的是long
System.out.println(d.getTime());
}
}
2.Calendar 日曆
【1】get() 獲取到時間的某一部分
【2】set() 設定時間 - -> 計算時間:系統已經幫我們設定好了,不用擔心二月有多少天等問題,計算時間十分方便
注:Calendar 日曆類是抽象類,因此不可以去new物件。雖然抽象類不能建立物件,但是jdk官方提供了一個例項物件的操作:
Calendar rightNow = Calendar.getInstance();
我們通過這條程式碼就是直接造了一個Calender的物件
【參考程式碼】:get() 獲取到時間的某一部分:
package date;
import java.util.Calendar;
public class TestCalendar {
public static void main(String[] args) {
Calendar cal = Calendar.getInstance();
// System.out.println(cal);
/*
假設當天:
2021
8
10
*/
cal.set(Calendar.DATE,cal.get(Calendar.DATE)+31); // 計算時間(這裡用天數計算的)
// 獲取Calendar建立的物件裡的所有內容
System.out.println(cal.get(Calendar.YEAR)); // 2021 年
System.out.println(cal.get(Calendar.MONTH)+1); // 月份:從0開始的 結果:為10月
System.out.println(cal.get(Calendar.DATE)); // 日
System.out.println(cal.get(Calendar.HOUR_OF_DAY));// 小時
System.out.println(cal.get(Calendar.MINUTE));
System.out.println(cal.get(Calendar.SECOND));
}
}
【參考程式碼】:set() 設定時間 - -> 計算時間:
注:cal.setTime(d); 把Date轉化成Calendar
package date;
import java.util.Calendar;
import java.util.Date;
public class TestCalendar {
public static void main(String[] args) {
Date d = new Date();
Calendar cal = Calendar.getInstance();
cal.setTime(d);// 把Date轉化成Calendar
System.out.println(cal);
System.out.println(cal.get(Calendar.YEAR)); // 年
System.out.println(cal.get(Calendar.MONTH)+1); // 月份:從0開始的
System.out.println(cal.get(Calendar.DATE)); // 日
}
}
3.SimpleDateFormat格式化時間
Date,Calendar通過引用也可以進行時間的格式化,但比較繁瑣,而SimpleDateFormat類是專門幫我們格式化時間的工具類,它在java.text包中。
【時間格式】:yyyy-MM-dd HH:mm:ss
SimpleDateFormat類有兩大常用方法:
【1】format(Date):
format(Date) 幫我們把時間轉成字串,字串的格式為SimpleDateFormat類定義物件時設定的時間格式
【參考程式碼】
package Simple;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.logging.SimpleFormatter;
public class Test {
public static void main(String[] args) {
Date d = new Date();
System.out.println(d); //Thu Aug 12 08:40:08 CST 2021 不美觀
// 設定格式化時間的模式,我們常用yyyy-MM-dd HH:mm:ss這個模式
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");// 時間格式
String s = sdf.format(d); // 格式化時間
System.out.println(s); // 2021-08-12 08:45:09
}
}
【2】parse(String):
parse(String) 幫我們把字串轉化成時間
【參考程式碼】
package Simple;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;
public class Test2 {
public static void main(String[] args) throws ParseException {
Scanner sc = new Scanner(System.in);
System.out.println("請輸入一個時間(yyyy-MM-dd HH:mm:ss):");
String s = sc.nextLine();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date d = sdf.parse(s); // 把字串轉成時間
System.out.println(d);
/*
請輸入一個時間(yyyy-MM-dd HH:mm:ss):
2021-08-12 12:25:21
Thu Aug 12 12:25:21 CST 2021
*/
}
}
注:由於使用者輸入的字串不一定是我們要求的格式,可能是任何東西,想把它們轉成時間是不可能的,你不可能把一個人轉成時間 對吧,因此存在著很大的風險未處理(異常: java.text.ParseException),為此我們需要處理異常。
4.計算時間差
計算思路:
- 格式化時間
- 先將字串轉化成long型別時間
- 計算毫秒級別時間差,取絕對值
- 毫秒級別時間差轉成秒級別
- 秒級別時間差轉成分鐘級別
- 分鐘級別時間差轉化顯示成xx小時xx分鐘
【參考程式碼】
package Simple;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class TestDiff {
public static void main(String[] args) throws ParseException {
String s1 = "2021-08-12 12:00:00"; // 開始時間
String s2 = "2021-08-12 14:35:00"; // 結束時間
//格式化時間
SimpleDateFormat sdf = new SimpleDateFormat("YYYY-MM-dd HH:mm:ss");
//將字串轉成時間形式
Date d1 = sdf.parse(s1);
Date d2 = sdf.parse(s2);
//計算時間差:先要獲取時間毫秒形式(long型別) 再做差
long long1 = d1.getTime();
long long2 = d2.getTime();
long diffTime = Math.abs(long1 - long2);
// 秒級別時間差
long diffSec = diffTime / 1000;
// 分級別時間差
long diffMin = diffSec / 60;
//顯示 xx小時xx分鐘
long displayHours = diffMin / 60; // 小時
long displayMin = diffMin % 60; //分鐘
System.out.println("您學習的時長為:"+displayHours+"小時"+displayMin+"分鐘");
}
}
六、String類
字串類常用方法
方法彙總:
修飾符和返回值的型別 | 方法名 | 解釋 |
---|---|---|
char | charAt() | 獲取某個位置的字元 |
String | concat() | 字串的拼接。一般字串拼接直接相加就好了 |
boolean | contains() | 判斷原字串是否含有xxx字串,常用於子串的判斷 |
boolean | endsWith() | 判斷原字串是否以xxx字串結尾 |
boolean | startsWith() | 判斷原字串是否以xxx字串開頭 |
boolean | equals() | 判斷兩邊字串內容是否相同;==判斷地址是否相同 |
boolean | equalsIgnoreCase() | 忽略大小寫判斷兩邊字串的內容是否一樣 |
int | indexOf() | 計算給出字串第一個出現的位置 |
int | LastindexOf() | 計算給出字串最後一個出現的位置 |
int | length() | 計算字串的長度 |
String | replace() | 字串內容的替換 |
String[] | split() | 字串切割,最終結果是一個字串陣列 |
String | substring() | 字串擷取,左閉右開:[ ) |
String | trim() | 去掉字串左右兩邊的空格,中間的不行 |
static String | valueOf() | 官方:基本資料型別轉為字串操作;直接:變數 + "" |
注:字串是一個不可變的型別(final類),幾乎所有的字串操作都會返回一個新字串而不是在原有基礎上進行修改。
【示例程式碼】
public class Test {
public static void main(String[] args) {
String s = "我的名字叫李華";
s.concat("hhh"); // 在字串s上拼接,拼接hhh
System.out.println(s);// 我的名字叫李華
//字串是不可變的資料型別
//幾乎所有的字串操作都會返回一個新字串
String s1 = s.concat("hhh"); // 在字串s上拼接,拼接hhh
System.out.println(s1);//我的名字叫李華hhh
String str1 = "李華喜歡看羅老師的視訊";
str1.replace("李華","張三");
System.out.println(str3); //李華喜歡看羅老師的視訊 並沒有替換 字串是不變的str1還是str1
String str2 = str1.replace("李華","張三");//幾乎所有的字串操作都會返回一個新字串 新串要用新變數接
System.out.println(str2);//張三喜歡看羅老師的視訊
}
}
package String;
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
String s = "我的名字叫李華";
System.out.println(s.charAt(0)); // 獲取第0個位置的字元
s.concat("hhh");
System.out.println(s);// 我的名字叫李華
//字串是不可變的資料型別
//幾乎所有的字串操作都會返回一個新字串
String s1 = s.concat("hhh"); // 在字串s上拼接,拼接hhh
System.out.println(s1);//我的名字叫李華hhh
System.out.println(s.contains("李華")); //true
System.out.println(s.contains("牛津")); //false
System.out.println("邀請李華來參加英語沙龍活動".endsWith("活動"));//true 判斷是否以xxx為結尾
System.out.println("邀請李華來參加英語沙龍活動".startsWith("李華"));//false 判斷是否以xxx開頭
// equals字串內容是否相同
// 接受邀請參加活動的李華到現場後要輸入驗證碼
// String yanZhengMa = "AAkm";
//
// Scanner sc = new Scanner(System.in);
//
// System.out.println("請輸入驗證碼("+yanZhengMa+")");
//
// String userInput = sc.nextLine();
//
// if(yanZhengMa.equalsIgnoreCase("aakm")){ // 忽略大小寫判斷兩邊的內容是否一樣
// System.out.println("歡迎參加英語沙龍活動!");
// }else{
// System.out.println("您未受到邀請,請現場報名!");
// }
// String str = "李華玩得很開心!";
// System.out.println(str.indexOf("開心"));// 5 計算給出字串第一個出現的位置
String str2 = "李華成績很好";
System.out.println(str2.length()); // 6 計算字串的長度
String str3 = "李華喜歡看羅老師的視訊";
str3.replace("李華","張三");
System.out.println(str3); //李華喜歡看羅老師的視訊 並沒有替換 字串是不變的str3還是str3
String str4 = str3.replace("李華","張三");//幾乎所有的字串操作都會返回一個新字串 新串要用新變數接
System.out.println(str4);//張三喜歡看羅老師的視訊
String str5 = "哈哈_呵呵_嘻嘻_噢no";
String[] ss = str5.split("_");//切割
System.out.println(ss[0]);//哈哈
System.out.println(ss[1]);//哈哈
System.out.println(ss[2]);//嘻嘻
System.out.println(ss[3]);//噢no
String str6 = "今天天氣不錯";
System.out.println(str6.substring(2,4));//天氣 字串擷取 [ ) 左閉右開,右邊取不到
String str7 =" 哈 哈 ";
System.out.println(str7.trim());// 去掉左右兩邊的空格
int i = 10;
System.out.println(String.valueOf(i)); // 基本資料型別轉為字串
System.out.println(i+""); // 野路子
}
}
七、String Builder和StringBuffer
String類的缺點:
String 是一個不可變的資料型別,每每拼接都會產生一個新的字串,那麼記憶體遲早會被這些拼接的字串塞滿。
String類和StringBuilder和StringBuffer類的區別:
StringBuilder和StringBuffer:可變的字串,不產生新物件,比較省記憶體,當進行大量的字串拼接時建議使用StringBuffer和StringBuilder,但它們兩個一些方法的實現幾乎跟String一樣。
StringBuffer和StringBuilder類:
【相似點】
兩者用法一模一樣,可以認為是一個類
【區別】
-
StringBuffer執行緒安全,StringBuilder非執行緒安全。
-
StringBuilder相比於StringBuffer有速度優勢,多數情況下建議使用StringBuilder類,但當被要求執行緒安全時必須使用StringBuilder類
字串拼接方法:append()方法
StringBuffer和StringBuilder 轉成String類 :
StringBuilder sb = new StringBuilder("貓喜歡吃魚"); String s = sb.toString();
【參考程式碼】
package String;
public class TestStringBuilder {
public static void main(String[] args) {
StringBuilder sb = new StringBuilder();// 一個空的字串""
StringBuilder sb2 = new StringBuilder("貓喜歡吃魚");
System.out.println(sb2);// 貓喜歡吃魚
sb2.append(",狗也喜歡吃魚");
System.out.println(sb2);// 追加 貓喜歡吃魚,狗也喜歡吃魚
sb2.insert(1,"哈哈哈");
System.out.println(sb2); //貓哈哈哈喜歡吃魚,狗也喜歡吃魚
// 上述的操作huan'c
// 把StringBuilder轉化成String
String s = sb2.toString();
System.out.println(s); //貓哈哈哈喜歡吃魚,狗也喜歡吃魚
// 上述操作都可以將StringBuilder換成StringBuffer,結果一樣
}
}
八、DecimalFormat
DecimalFormat:對小數進行格式化,保留幾位小數。與格式化時間聯想記。
. 表示小數點
0和# 表示數位,保留幾位就幾個0或者#
【參考程式碼】
import java.text.DecimalFormat;
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
double d= 10/3.0;
System.out.println(d);//3.3333333333333335
// . 表示小數點
// 0和#表示數字
// 保留兩位小數 格式
DecimalFormat df = new DecimalFormat(".00"); // 或者.##
String s = df.format(d); // 把 d 轉成上面設定的格式
System.out.println(s);//3.33
}
}
總結
轉眼這個學期又快要結束了,在繁忙的課業之餘,經過了好久好久,終於將學習的各個小知識點整合起來啦!希望對在前進道路上學習的你有些許幫助!
注:如果文章有任何錯誤或不足,請各位大佬盡情指出,評論留言留下您寶貴的建議!如果這篇文章對你有些許幫助,希望可愛親切的您點個贊推薦一手,非常感謝啦