1. 程式人生 > >JAVA集合類簡要筆記 - 內部類 包裝類 Object類 String類 BigDecimal類 system類

JAVA集合類簡要筆記 - 內部類 包裝類 Object類 String類 BigDecimal類 system類

# 常用類 ## 內部類 成員內部類、靜態內部類、區域性內部類、匿名內部類 概念:在一個類的內部再定義一個完整的類 特點: - 編譯之後可生成獨立的位元組碼檔案 - 內部類可直接訪問外部類私有成員,而不破壞封裝 - 可為外部類提供必要的內部功能元件 ``Outer$Inner.class`` ``Outer.class`` ```java // 身體 class Body{ // 頭部 class Header{ // 也會生成class檔案 } } ``` ### 成員內部類 - 在類的內部定義,與例項變數、例項方法同級別的類 - 外部類的一個例項部分,建立內部類物件時,必須依賴外部類物件 - 當外部類、內部類存在重名屬性時,會優先訪問內部類屬性 - 成員內部類裡不能定義**靜態成員**、可以包含**靜態常量(final)** ```java // 外部類 public class Outer{ //例項變數 private String name = "張三"; private int age = 20; //內部類 class Inner{ private String address = "北京"; private String phone = "110"; private String name = "李四"; //方法 public void show(){ //列印外部類屬性 此時有重名屬性name sout(Outer.this.name); // 張三 sout(age); //列印內部類中的屬性 sout(name); // 李四 sout(address); sout(phone); } } } // 測試類 public class Test{ psvm(String[] args){ // 建立外部類物件 Outer outer = new Outer(); // 建立內部類物件 Inner inner = outer.new Inner(); //一步到位 Inner inner = new Outer(.new Inner(); inner.show(); } } ``` ### 靜態內部類 - 不依賴外部類物件,可直接建立或通過類名訪問,可宣告靜態成員 ```java // 外部類 public class Outer{ //例項變數 private String name = "xxx"; private int age = 20; // 靜態內部類,和外部類相同 static class Inner{ private String address = "上海"; private String phone = "111"; // 靜態成員 private static int count = 1000; //方法 public void show(){ // 呼叫外部類的屬性 // 1. 先建立外部類物件 Outer outer = new Outer(); // 2. 呼叫外部類物件的屬性 sout(outer.name); sout(outer.age); // 呼叫靜態內部類的屬性和方法 sout(address); sout(phone); // 呼叫靜態內部類的靜態屬性 sout(Inner.count); } } } // 測試類 public class Test{ psvm(String[] args){ // 直接建立靜態內部類物件 Outer.Inner inner = new Outer.Inner(); inner.show(); } } ``` ### 區域性內部類 - 定義在外部類**方法**中,作用範圍和建立物件範圍僅限於當前方法 - 區域性內部類訪問外部類當前方法中的區域性變數時,因無法保障變數的生命週期與自身相同,變數必須修飾為final - 限制類的使用範圍 ```java // 外部類 public class Outer{ //例項變數 private String name = "劉德華"; private int age = 35; //方法 public void show(){ // 定義區域性變數 String address = "sz"; // 區域性內部類:注意不能加任何訪問修飾符 class Inner{ private String phone = "11234"; private String email = "[email protected]"; public void show2(){ // 訪問外部類的屬性 sout(name); // 相當於 Outer.this.name sout(age); // 訪問內部類的屬性 sout(this.phone); sout(this.email); // 訪問區域性變數 jdk1.7要求必須常量final、jdk1.8自動新增final } } // 建立區域性內部類物件 Inner inner = new Inner(); inner.show2(); } } // 測試類 public class Test{ psvm(String[] args){ // 建立外部類物件 Outer outer = new Outer(); outer.show(); } } ``` ### 匿名內部類 - 沒有類名的區域性內部類(一切特徵都與區域性內部類相同) - 必須繼承一個父類或者實現一個介面 - 定義類、實現類、建立物件的語法合併,只能建立一個該類的物件 - 優點:減少程式碼量 - 缺點可讀性較差 ```java // 使用匿名內部類優化(相當於建立了一個區域性內部類) Usb usb = new Usb(){ // Usb為一個介面 @Override public void service(){ sout("連線電腦成功,fan開始工作") } }; usb.service(); ``` ## Object 類 - 超類、基類,所有類的直接或間接父類,位於繼承樹的最頂層 - 任何類,如沒有書寫extends顯示繼承某個類,都預設直接繼承Object類,否則為間接繼承 - Object類中所定義的方法,是所有物件都具備的方法 - Object型別可以儲存任何物件 - 作為引數,可接受任何物件 - 作為返回值,可返回任何物件 ### getClass() 方法 - ``public final Class getClass(){}`` - 返回引用中儲存的實際物件型別 - 應用:通常用於判斷兩個引用中實際儲存物件型別是否一致 ```java // 判斷s1 和 s2是不是同一個型別 Class class1 = s1.getClass(); Class class2 = s2.getClass(); // getClass返回 class型別 ``` ### hashCode()方法 - ``public int hashCode(){}`` - 返回該物件的雜湊碼值 - 雜湊值根據物件的地址或字串或數字使用hash演算法計算出來的int型別的值 - 一般情況下相同物件返回相同雜湊碼 ```java s1.hashCode(); s2.hashCode(); // 自然不同 Student s3 = s1; // 此時s3的hashCode與s1相同 ``` ### toString()方法 - ``public String toSring(){}`` - 返回該物件的字串表示(表現形式) - 可以根據程式需求覆蓋該方法,如:展示物件各個屬性值 ```java sout(s1.toString()); // 直接列印包+類名+雜湊值 // 重寫 alt + enter + s @override public String toString(){ return "Student [name = " + name + ", age = " + age + "]"; } ``` ### equals()方法 - ``public boolean equals(Object obj){}`` - 預設實現為(this == obj), 比較兩個物件地址是否相同 - 可進行覆蓋,比較兩個物件的內容是否相同 ```java // 判斷兩個物件是否相等 sout(s1.equals(s2)); // false Student s4 = new Strudent("小明", 17); Student s5 = new Strudent("小明", 17); sout(s4.equals(s5)); // false 堆中地址不同 // 重寫 改變其比較內容 /* 步驟 1. 比較兩個應用是否指向同一個物件 2. 判斷obj是否為null 3. 判斷兩個引用只想的實際物件型別是否一致 4. 強制型別轉換 5. 依次比較各個屬性值是否相同 */ @override public boolean equals(Object obj){ // 1. if(this == obj){ return true; } // 2. if(obj == null){ return false; } // 3. // if(this.getClass() == obj.getClass()){ // // } // instanceof 判斷物件是否是某種型別 if(obj instanceof Student){ // 4.強制型別轉換 Student s = (Student)obj; // 5. 比較屬性 if(this.name.equals(s.getName()) && this.age == s.getAge()){ return true; } } return false; } ``` ### finalize() 方法 - 當物件被判定為垃圾物件時,由JVM自動呼叫此方法,用以標記垃圾物件,進入回收佇列 - 垃圾物件:沒有有效引用指向此物件時,為垃圾物件 - 垃圾回收:由gc銷燬垃圾物件,釋放資料儲存空間 - 自動回收機制:JVM的記憶體耗盡,一次性回收所有垃圾物件 - 手動回收機制:使用``System.gc();``通知JVM執行垃圾回收 ```java @Override protected void finalize() throws Throwable{ sout(this.name + "物件被回收了"); } psvm(String[] args){ Student s1 = new Student("aaa", 29); // 不是垃圾 new Student("bbb", 30); // 是辣雞 會被回收 //回收垃圾 System.gc(); sout("回收垃圾"); // 打印出 “回收垃圾 // aaa物件被回收了” } ``` ## 包裝類 - **基本資料型別**所對應的**引用資料型別** - Object 可統一所有資料,包裝類的預設值是null | 基本資料型別 | 包裝型別 | | :----------: | :-------: | | byte | Byte | | short | Short | | int | Integer | | long | Long | | float | Float | | double | Double | | boolean | Boolean | | char | Character | ### 型別轉換與裝箱、拆箱 - 8種包裝類提供不用型別間的轉換方式 1. Number父類中提供的6個共性方法 2. ``parseXXX( )``靜態方法 3. ``valueOf( )``靜態方法 - 注意:需保證型別相容,否則丟擲NumberFormatException異常 ```java psvm(String[] args){ // 裝箱, 基本型別 → 引用型別 // 基本型別 int num1 = 18; // 使用Integer類建立物件 Integer integer1 = new Integer(num1); Integer integer2 = Integer.valueOf(num1); // 拆箱, 引用型別 → 基本型別 Integer integer3 = new Integer(100); int num2 = integer3.intValue(); // 上述為jdk1.5之前方法,之後提供了自動裝箱拆箱 int age = 30; // 自動裝箱 Integer integer4 = age; // 自動拆箱 int age2 = integer4; // 基本型別和字串之間轉換 // 1. 基本型別轉成字串 int n1 = 100; // 1.1 使用+號 String s1 = n1 + ""; // 1.2 使用Integer中的toString()方法 String s2 = Integer.toString(n1); String s2 = Integer.toString(n1, x); // x為進位制要求 // 2. 字串轉成基本型別 String str = "150"; // 使用Integer.parseXXX(); int n2 = Integer.parseInt(str); // boolean 字串形式轉成基本型別,"true" ---> true 非“true ———> false String str2 = "true"; boolean b1 = Boolean.parseBoolean(str2); } ``` ### 整數緩衝區 - Java預先建立了256個常用的證書包裝型別物件 - 在實際應用當中,對已建立的物件進行復用 ```java psvm(String[] args){ // 面試題 Integer integer1 = new Integer(100); Integer integer2 = new Integer(100); sout(integer1 == integer2); // false Integer integer3 = new Integer(100);// 自動裝箱 // 相當於呼叫 Integer.valueOf(100); Integer integer4 = new Integer(100); sout(integer3 == integer4); // true Integer integer5 = new Integer(200);// 自動裝箱 Integer integer6 = new Integer(200); sout(integer5 == integer6); // false // 因為快取區陣列 [-128, 127] 在這之內地址一樣 } ``` ## String 類 - 字串是常量,建立之後不可改變 - 字串字面值儲存在字串池中,可以共享 - ``String s = "Hello";``產生一個物件,字串池中儲存 - ``String s = new String("Hello");`` 產生兩個物件,**堆、池**各一個 ### 常用方法 ```java // 1. length(); 返回字串長度 // 2. charAt(int index); 返回某個位置的字元 // 3. contains(String str); 判斷是否包含某個字串 String content = "java是最好的語言, java no1"; sout(content.length()); // 10 sout(content.charAt(content.length() - 1)); // 言 sout(content.contains("java")); // true // 4. toCharArray(); 返回字串對應陣列 // 5. indexOf(); 返回子字串首次出現的位置 // 6. lastIndexOf(); 返回字串最後一次出現的位置 sout(content.toCharArray()); sout(content.indexOf"java")); // 0 sout(content.indexOf("java", 4)); // 從索引4開始找 返回12 sout(content.lastIndexOf("java")); // 12 // 7. trim(); //去掉字串前後空格 // 8. toUpperCase(); toLowerCase(); 轉換大小寫 // 9. endWith(str); startWith(str); 判斷是否以str 結尾、開頭 String ct = " hello world "; sout(ct.trim()); // "hello world" sout(ct.toUpperCase()); // HELLO WORLD sout(ct.toLowerCase()); // hello world sout(ct.endWith("world")); // true sout(ct.startWith("hello")) // true // 10. replace(char old, char new); 用心的字元或字串替換舊的字元或字串 // 11. split(); 對字串拆分 sout(content.replace("java", "php")); // php是最好的語言, php no1 String say = "java is the best language"; String[] arr = arr.say.split(" "); // "[ ,]+" 表示空格 逗號切分 +號表示切分可以多個 比如多個空格 sout(arr.length); // 5 for(String string : arr){ sout(string); } // 打印出 //java //is //the //best //language // 補充兩個equals/compareTo();比較大小 String s1 = "hello"; String s2 = "HELLO"; sout(s1.equalsIgnoreCase(s2));// 忽略大小寫比較true // compareTo(); 兩字元不同時比較字元字典序的ascii碼 // 字元相同時比較長度 返回差值 ``` ### 案例演示 需求: 1. 已知String str = "this is a text"; 2. 將str中的單詞單獨獲取 3. 將str中的text替換成practice 4. 在text前面插入一個easy 5. 將每個單詞的首字母改為大寫 ```java psvm(String[] args){ String str = "this is a text"; // 2. String[] arr = str.split(" "); for(String s : arr){ sout(s); } // 3. String str2 = str.replace("text", "practice"); // 4. String str3 = str.replace("text", "easy text"); // 5. for(int i = 0; i < arr.length; i ++){ char first = arr[i].charAt(0); char upperfirst = Character.toUpperCase(first); String new = upperfirst + arr[i].substring(1); } } ``` ### 可變字串 - StringBuffer : 可變長字串,執行效率慢、執行緒安全 - StringBuilder : 可邊長字串、執行快、執行緒不安全 效率都比String高且節省記憶體 ```java psvm(String[] args){ // StringBuffer 和 StringBuilder 用法一致 StringBuffer sb = new StringBuffer(); // 1. append(); 追加 sb.append("java no1"); // 2. insert(); 新增、插入 sb.insert(0, "在第一個位置插入"); // 3.replace(); 替換 sb.replace(0, 9, str); // 左閉右開 // 4. delete(); 刪除 sb.delete(0, 5); // 左閉右開 // 5. 清空 sb.delete(0, sb.length()); } ``` ## BigDecimal 類 - 位置 ``java.math`` 包中 - 作用 精確計算浮點數 - 建立方式 ``BigDecimal bd = new BigDecimal("1.0");`` ```java BigDecimal bd1 = new BigDecimal("1.0"); // 需用字串 BigDecimal bd2 = new BigDecimal("0.9"); // 減法 BigDecimal r1 = bd1.subtract(bd2); sout(r1); // 0.1 // 加法 BigDecimal r2 = bd1.add(bd2); //乘法 BigDecimal r3 = bd1.multiply(bd2); // 除法 BigDecimal r4 = new BigDecimal("1.4").subtract(new BigDecimal("0.5")).divide(new BigDecimal("0.9"), x, BigDecimal.ROUND_HALF_UP); //除不盡時 x填保留位數 後面為四捨五入之意 ``` ### Date 類 Date表示特定的瞬間,精確到毫秒。Date類中的大部分方法都已經被Calendar類中的方法所取代 時間單位:1s = 1,000ms = 1,000,000 μs = 1,000,000,000 = ns ```java psvm(String[] args){ // 1 建立Date物件 Date date1 = new Date(); sout(date1.toString()); //WED Sept 02 22:25:23 CST 2020 sout(date1.toLocaleString()); // 已過時 但也能用 2020-9-2 // 建立昨天的 Date date2 = new Date(date1.getTime() - (60*60*24*1000)); sout(date2.toLocaleString()); // 2 方法after before boolean b1 = date.after(date2); sout(b1); //true boolean b2 = date1.before(date2); sout(b2); //false // 比較compareTo(); int d = date1.compareTo(date1); sout(d); // 多的為1 少的為 -1 // 比較是否相等 equals() boolean b3 = date1.equals(date2); sout(b3); // false } ``` ### Calendar - Calendar提供了獲取或設定各種日曆欄位的方法 - 構造方法 ``protected Calendar();`` 由於是protected 所以無法直接建立 - 其他方法 | 方法名 | 說明 | | ------------------------------------------------------------ | ------------------------------------------ | | static Calendar getInstance() | 使用預設時區和區域獲取日曆 | | void set(int year, int month, int date, int hourofday, int minute, int second) | 設定日曆的年、月、日、時、分、秒 | | int get(int field) | 返回給定日曆欄位的值。欄位比如年、月、日 | | void setTime(Date date) | 用給定的date設定此日曆時間 | | Date getTime() | 返回一個date表示此日曆的時間 | | void add(int field, int amount) | 按照日曆的規則,給指定欄位新增或減少時間量 | | long getTimeInMilles() | 毫秒為單位返回該日曆的時間值 | ```java psvm(String[] args){ // 1. 建立 Calendar 物件 Calendar calendar = Calendar.getInstance(); sout(calendar.getTime().toLocaleString()); // 2. 獲取時間資訊 // 獲取年 int year = calendar.get(Calendar.YEAR); // 獲取月 從 0 - 11 int month = calendar.get(Calendar.MONTH); // 日 int month = calendar.get(Calendar.DAY_OF_MONTH); // 小時 int hour = calendar.get(Calendar.HOUR_OF_DAY); // 分鐘 int minute = calendar.get(Calendar.MINUTE); // 秒 int second = calendar.get(Calendar.SECOND); // 3. 修改時間 Calendar calendar2 = Calendar.getInstance(); calendar2.set(Calendar.DAY_OF_MONTH, x); // 4. add修改時間 calendar2.add(Calendar.HOUR, x); // x為正就加 負就減 // 5. 補充方法 int max = calendar2.getActualMaximum(Calendar.DAY_OF_MONTH);// 月數最大天數 int min = calendar2.getActualMinimum(Calendar.DAY_OF_MONTH); } ``` ### SimpleDateFormat - SimpleDateFormat是一個以與語言環境有關的方式來格式化和解析日期的具體類 - 進行格式化(日期→文字)、解析(文字→日期) - 常用的時間模式字母 | 字母 | 日期或時間 | 示例 | | ---- | ------------------ | ---- | | y | 年 | 2019 | | 08 | 年中月份 | 08 | | d | 月中天數 | 10 | | H | 一天中小時(0-23) | 22 | | m | 分鐘 | 16 | | s | 秒 | 59 | | S | 毫秒 | 356 | ```java psvm(String[] args){ // 1. 建立物件 SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH-mm-ss"); // 2. 建立Date Date date = new Date(); // 格式化date(日期→字串) String str = sdf.format(date); sout(str); // 解析(字串→時間) Date date2 = sdf.parse("1948/03/12"); sout(date2); } ``` ## System類 主要用於獲取系統的屬性資料和其他操作,構造方法私有的 | 方法名 | 說明 | | -------------------------------- | -------------------------------------------------- | | static void arraycopy(...) | 複製陣列 | | static long currentTimeMillis(); | 獲取當前系統時間,返回毫秒值 | | static void gc(); | 建議jvm趕快啟動垃圾回收期器回收垃圾 | | static void exit(int status); | 退出jvm 如果引數是0表示正常退出jvm 非0表示異常退出 | ```java psvm(String[] args){ //arraycopy 複製 //src-原陣列 srcPos-從哪個位置開始複製0 dest-目標陣列 destPos-目標陣列的位置 length-複製的長度 int[] arr = {20, 18, 39, 3}; int[] dest = new int [4]; System.arraycopy(src, srcPos, dest, destPos, length); sout(arr, 4, dest, 4, 4) // Arrays.copyOf(original, newLength