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

CoderZjz發表於2020-09-03

常用類

內部類

成員內部類、靜態內部類、區域性內部類、匿名內部類

概念:在一個類的內部再定義一個完整的類

特點:

  • 編譯之後可生成獨立的位元組碼檔案
  • 內部類可直接訪問外部類私有成員,而不破壞封裝
  • 可為外部類提供必要的內部功能元件

Outer$Inner.class Outer.class

// 身體
class Body{
  // 頭部
  class Header{
    // 也會生成class檔案
  }
}

成員內部類

  • 在類的內部定義,與例項變數、例項方法同級別的類
  • 外部類的一個例項部分,建立內部類物件時,必須依賴外部類物件
  • 當外部類、內部類存在重名屬性時,會優先訪問內部類屬性
  • 成員內部類裡不能定義靜態成員、可以包含靜態常量(final)
// 外部類
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();
  }
}

靜態內部類

  • 不依賴外部類物件,可直接建立或通過類名訪問,可宣告靜態成員
// 外部類
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
  • 限制類的使用範圍
// 外部類
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 = "ldh@qq.com";
      
      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();
  }
}

匿名內部類

  • 沒有類名的區域性內部類(一切特徵都與區域性內部類相同)
  • 必須繼承一個父類或者實現一個介面
  • 定義類、實現類、建立物件的語法合併,只能建立一個該類的物件
  • 優點:減少程式碼量
  • 缺點可讀性較差
// 使用匿名內部類優化(相當於建立了一個區域性內部類)
Usb usb = new Usb(){ // Usb為一個介面
  @Override
  public void service(){
    sout("連線電腦成功,fan開始工作")
  }
};
usb.service();

Object 類

  • 超類、基類,所有類的直接或間接父類,位於繼承樹的最頂層
  • 任何類,如沒有書寫extends顯示繼承某個類,都預設直接繼承Object類,否則為間接繼承
  • Object類中所定義的方法,是所有物件都具備的方法
  • Object型別可以儲存任何物件
    • 作為引數,可接受任何物件
    • 作為返回值,可返回任何物件

getClass() 方法

  • public final Class<?> getClass(){}
  • 返回引用中儲存的實際物件型別
  • 應用:通常用於判斷兩個引用中實際儲存物件型別是否一致
// 判斷s1 和 s2是不是同一個型別
Class class1 = s1.getClass();
Class class2 = s2.getClass();
// getClass返回 class型別

hashCode()方法

  • public int hashCode(){}
  • 返回該物件的雜湊碼值
  • 雜湊值根據物件的地址或字串或數字使用hash演算法計算出來的int型別的值
  • 一般情況下相同物件返回相同雜湊碼
s1.hashCode();
s2.hashCode();
// 自然不同
Student s3 = s1; // 此時s3的hashCode與s1相同

toString()方法

  • public String toSring(){}
  • 返回該物件的字串表示(表現形式)
  • 可以根據程式需求覆蓋該方法,如:展示物件各個屬性值
sout(s1.toString()); // 直接列印包+類名+雜湊值
// 重寫 alt + enter + s
@override
public String toString(){
  return "Student [name = " + name + ", age = " + age + "]";
}

equals()方法

  • public boolean equals(Object obj){}
  • 預設實現為(this == obj), 比較兩個物件地址是否相同
  • 可進行覆蓋,比較兩個物件的內容是否相同
// 判斷兩個物件是否相等
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執行垃圾回收
@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異常
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個常用的證照包裝型別物件
  • 在實際應用當中,對已建立的物件進行復用
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"); 產生兩個物件,堆、池各一個

常用方法

// 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. 將每個單詞的首字母改為大寫
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高且節省記憶體

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");
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

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() 毫秒為單位返回該日曆的時間值
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
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表示異常退出
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)
}

相關文章