常用工具類


內部類分類

  • 成員內部類
  • 靜態內部類
  • 局部內部類
  • 匿名內部類

內部類的概念

什么是內部類?

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

特點:

  • 編譯之后會生成獨立的字節碼文件

  • 內部類可直接訪問外部類的私有成員,而不破壞封裝

  • 可為外部類提供必要的內部功能組件

內部類是否會再次生成class文件?

答案是的

例如我自己寫了一個匿名內部類

class生成目錄下找到了

成員內部類

//成員內部類
public class Outer {
    //實例變量
    private String name = "張三";
    private  int age = 23;

    //內部類
    class Inner{
        private String address = "hangzhou";
        private String phone = "120";

        //方法
        public void show(){
            //外部類
            System.out.println(name);
            System.out.println(age);
            //內部類
            System.out.println(address);
            System.out.println(phone);
        }
    }
}

外部類的一個實例部分,創建內部類對象時,必須依賴外部類對象。

public class Test {
    public static void main(String[] args) {
        //創建外部類對象
        Outer outer = new Outer();
        //創建內部類對象
        Outer.Inner inner = outer.new Inner(); 
        //嫌麻煩可以換成這樣
        Outer.Inner inner = new Outer().new Inner();
        inner.show();
    }
}

當外部類、內部類存在重名屬性時,會優先訪問內部類屬性。

//成員內部類
public class Outer {

    //實例變量
    private String name = "張三";

    //內部類
    class Inner{
        private String name ="李四";

        //方法
        public void show(){
            System.out.println(name);
            //如果需要訪問內部類對象,改成這樣
            System.out.println(Outer.this.name);

        }
    }
}

成員內部類不能定義靜態成員的。但是可以定義靜態常量

private static final String country = "中國";

靜態內部類

//靜態內部類
public class Staticc {
    //私有屬性
    private String name = "XXX";
    private int age = 12;
    //靜態內部類
    static class Inner{
        //靜態內部類中的私有屬性
        private String address = "hangzhou";
        private String phone = "120";
        //靜態內部類中靜態的私有屬性
        private static final String country = "中國";
        public void show(){
            Staticc staticc = new Staticc();
            System.out.println(staticc.age);
            System.out.println(Inner.country);
        }
    }
}

只能直接訪問外部類的靜態成員(實例成員需要實例化外部類的對象)

public class TestSt {
    public static void main(String[] args) {
        Staticc.Inner inner = new Staticc.Inner();
        inner.show();
    }
}

局部內部類

定義在外部類的方法中,作用范圍和創建對象范圍僅限於當前方法。

public class part {
    //實例變量
    private String name = "張三";
    private  int age = 23;
    public void show(){
        //定義局部變量
        final String address="sz";
        //局部類-局部內部類前面不能加任何訪問修飾符public
        //局部變量 本身就是 一個訪問權限 的設定啊。 只能在局部調用
        //定義在方法中的變量叫局部變量,局部變量的有效范圍就是方法內,在局部變量中加上public,或者其他修飾符的話(編譯都通不過),就破壞了局部變量的范圍,可以說局部變量是為方法而生的。局部變量中的局部就已經說明了范圍
        class Inner{
            private String address = "hangzhou";
            private String email = "120";
            public void show2(){
                //訪問外部類屬性
                System.out.println(part.this.age);
                System.out.println(part.this.name);
                //訪問內部類屬性
                System.out.println(this.address);
                System.out.println(this.email);
                //調用局部變量
                //在JDK1.7之前,變量必須加上final,JDK1.8后是自動添加的
                System.out.println(address);
            }
        }
        Inner inner = new Inner();
        inner.show2();
    }
}

局部內部類訪問外部類當前方法中的局部變量時,因無法保障變量的聲明周期與自身相同,需要將變量修飾為final

   final String address="sz";

匿名內部類

  • 沒有類名的局部內部類(一切特征都與局部內部類相同)
  • 必須繼承一個父類或者實現一個接口
public class TestUsb {
    public static void main(String[] args) {
        //使用匿名內部類
        //定義類、實現類、創建對象的語法合並,只能創建一個該類的對象。

        Usb usb = new Usb() {
            @Override
            public void Service() {
                System.out.println("開始旋轉");
            }
        };
        usb.Service();
    }
}

優點:減少代碼量

缺點:可讀性太差

以下是不用匿名內部類的樣子

public class TestUsb {
    public static void main(String[] args) {
        //創建接口類型的變量
        Usb usb = new Mouse();
        usb.Service();
        局部內部類
        class Fan implements Usb{

            @Override
            public void Service() {
                System.out.println("連接電腦成功!");
            }
        }
        //使用局部內部類開始創建對象
        Usb usb = new Fan();
        usb.Service();      
    }
}
public interface Usb {
    void Service();
}
public class Mouse implements Usb{
    @Override
    public void Service() {}
}

Object類

Object又叫超類、基類,所有類的直接或間接父類,位於繼承樹的最頂層,任何類,如沒有書寫extends顯示繼承某個類,都默認直接繼承Object類,否則為間接繼承,Object類中所定義的方法,是所有對象都具備的方法

Object類型可以存儲任何對象

  • 作為參數,可以接受任何對象

  • 作為返回值,可返回任何對象

getClass()方法

定義: public final Class <T> getClass(){}
作用:返回引用中存儲的實際對象類型,通常判斷兩個引用中實際 存儲對象類型是否一致。
public class TestStudent {
    public static void main(String[] args) {
        Student s1 = new Student("li",11);
        Student s2 = new Student("wang",23);
        //判斷S1和S2是否是同意類型
        Class class1 = s1.getClass();
        Class class2 = s2.getClass();
        if (class1==class2){
            System.out.println("same");
        }else {
            System.out.println("no same");
        }
    }
}

hashCode()方法

定義:public int hashCode(){}
作用:返回該對象的哈希碼值,哈希值根據對象的地址或字符串或數字使用hash算法計算出來的int類型的數值
package commonclass.getclas;

public class TestStudent {
    public static void main(String[] args) {
        Student s1 = new Student("li",11);
        Student s2 = new Student("li",11);
        //打印哈希值
        System.out.println("====================");
        System.out.println(s1.hashCode());
        System.out.println(s2.hashCode());

		//賦值給到新的變量時,哈希值也會被賦值過去
        Student s3 = s1;
        System.out.println(s3.hashCode());
        System.out.println("====================");
    }
}

輸出

====================
1956725890
356573597
1956725890
====================

toString()方法

定義:public boolean equals(Object obj){}
作用:比較兩個對象的內容是否相同

思考:equals未重寫時,比較的是內容還是內存地址?

equal是object類的方法,所有沒有重寫這個類的方法;比較的都是內存地址,和==是一樣的,重寫后該方法是按照重寫的方法來進行比較,比如String類就重寫了這個方法,比較的是內容。

如何將equals()方法進行覆蓋?

  1. 比較兩個引用是否指向同一個對象

  2. 判斷obj是否為null

  3. 判斷兩個引用指向的實際對象類型是否一致、

  4. 強制類型轉換

  5. 依次比較各個屬性值是否相同。

    @Override
    public boolean equals(Object o) {
        //1、判斷兩個對象是否是同一引用
        if (this==o){
            return true;
        }
        //2、判斷o是否為null
        if (o==null){
            return false;
        }
        //3、判斷是否是同一類型
        //第一種
//        if(this.getClass()==o.getClass()){
//
//        }
        //第二種
        if(o instanceof Student){
            //4、強制類型轉換
            Student s=(Student) o;
            //5、比較各個屬性值是否相同
            if (this.name.equals(s.getName())&&this.age==s.getAge()){
                return true;
            }
         }
        return false;
    }

這是手寫的,可能存在bug,可以直接使用idea的快捷鍵alt+insert自動重寫equals

finalize()方法

作用:當對象被判定為垃圾對象時,由JVM自動調用此方法,用以標記垃圾對象,進入回收隊列。

思考:什么樣的對象會被判定為垃圾對象?

public class TestStudent2 {
    public static void main(String[] args) {
        //已經有指定的,無法直接回收
//        Student s1 = new Student("a",1);
//        Student s2 = new Student("b",1);

        //無指定
        new Student("c",1);
        new Student("d",1);
        //垃圾回收
        System.gc();
        System.out.println("已回收");
    }
}

//重寫finalize方法
    @Override
    protected void finalize() throws Throwable {
        System.out.println(this.name+"銷毀");
    }

垃圾對象:沒有有效引用指向此對象時,為垃圾對象。

垃圾回收:由GC銷毀垃圾對象,釋放數據內存空間

自動回收機制:JVM的內存耗盡,一次性回收所有垃圾對象。

手動回收機制:使用System.gc();通知JVM執行垃圾回收。

包裝類

什么是包裝類?

基本數據類型所對應的引用數據類型

裝箱和拆箱

基本數據類型存儲在棧中,引用數據類型是存儲在堆中

將棧中的數據放到堆中,就是裝箱

將堆中的對象放到棧中,就是拆箱

//自動裝箱和拆箱
public class Demo01 {
    public static void main(String[] args) {
        //JDK1.5之前的寫法
        //裝箱操作、基本類型轉換引用類型
        int num1 = 100;
        //使用Integer創建對象,裝箱的兩種方法
        Integer integer1 = new Integer(num1);
        Integer integer2 = Integer.valueOf(num1);
        System.out.println("裝箱");
        System.out.println(integer1);
        System.out.println(integer2);
        //拆箱操作、引用類型轉換基本類型
        Integer integer3 = new Integer(100);
        int num2 = integer3.intValue();
        System.out.println(num2);
        System.out.println("===================");
        //JDK1.5之后的寫法
        //java提供了自動裝箱和拆箱
        //自動裝箱
        int age = 200;
        Integer integer4 = age;
        System.out.println(integer4);
        //自動拆箱
        int num3 = integer4;
        System.out.println(num3);
    }
}

基本類型和字符串轉換

8中包裝類提供不同類型間的轉換方式:

Number父類提供的6個共性方法

parseXXX()靜態方法---將字符串轉換成基本類型

valueOf靜態方法---裝箱操作,基本類型轉換成引用類型

注意:需保證類型兼容,否則容易拋出NumberFormatException異常

//字符串與基本類型的轉換
//基本類型轉換成字符串
int n1 = 20;
//1、使用+
String s1 = n1+"";
//2使用Integer的toString()方法
//radix轉換的進制
String s2 = Integer.toString(n1,16);
System.out.println(s1);
System.out.println(s2);

//字符串轉換成基本類型
String str = "100";
//使用Integer的parseXXX方法
int n2 = Integer.parseInt(str);
System.out.println(n2);

//boolean字符串轉換成基本類型
String str2 = "true";
boolean b1 = Boolean.parseBoolean(str2);
System.out.println(str2);

Interger緩沖區

Java預先創建了256個常用的整數包裝類型對象;在實際應用中,對已創建的對象進行復用。

//關於Integer緩沖區的面試題
public class Demo02 {
    public static void main(String[] args) {

        //思考?是否相等
        //不相等,==比較的是內存地址,
        // Integer是引用類型在堆中,所以內存地址不同
        Integer integer1 = new Integer(20);
        Integer integer2 = new Integer(20);
        System.out.println(integer1==integer2);

        //思考?是否相等
        //相等,相當於自動裝箱
        //實際完整代碼:Integer integer3 = Integer.valueOf(30);
        //對於valueOf是有在堆中提前設計的緩存區間,可以存儲-128-127之間的數字
        Integer integer3 = 30;
        Integer integer4 = 30;
        System.out.println(integer3==integer4);

        //思考?是否相等
        //不相等。當范圍超出設計的緩存區間,會自動另外開辟新的空間,則為false
        Integer integer5 = 300;
        Integer integer6 = 300;
        System.out.println(integer5==integer6);

    }
}

String類

字符串是常量,創建之后不可改變;字符串字面存儲在字符串池中,可以共享。

String s1 = "Hello";產生一個對象,字符串池中存儲

String s2 = new String("Hello");產生兩個對象,堆,池各存儲一個

public class Demo03 {
    public static void main(String[] args) {
       //注意這里修改的不是s1,而是在常量池中重新開辟了一個空間,叫wang
        //s1也指向wang
        String s1 = "lee";
        s1 = "Wang";

        //面試題
        //思考:為什么是false?
        //new是在堆中開辟新的空間,同時又指向常量池,相當於兩個地址
        //==比較的是內存地址,所以返回false
        String s2 = new String("Zhang");
        String s3 = new String("Zhang");
        System.out.println(s2==s3);
    }
}

常用方法

//String方法
//1、length;返回字符串長度
//2、CharAt;返回某個位置的字符
//3、contain;判斷是否包含某個子字符串
String str1 = "王冰冰最美";
System.out.println(str1.length());
System.out.println(str1.charAt(str1.length()-1));
System.out.println(str1.contains("王"));

//4、toCharArray;返回字符串對應的數組
//5、iNdexOf;返回子字符串首次出現的位置
//6、lastIndexOf;返回字符串最后一次出現的位置
System.out.println(Arrays.toString(str1.toCharArray()));
System.out.println(str1.indexOf("冰"));
System.out.println(str1.lastIndexOf("冰"));

//7、trim();去電字符串前面的空格
//8、toUpperCase()/toLowerCase();把小寫轉換成大寫,大寫轉小寫
//9、endWith()/startsWith();是否是以str結尾;或開頭
String str2 = " wangbingBingzuimei ";
System.out.println(str2.trim());
System.out.println(str2.toUpperCase());
System.out.println(str2.toLowerCase());
String str3 = "wangbingbing";
System.out.println(str3.endsWith("bing"));
System.out.println(str3.startsWith("wang"));

//10、replace();用新的字符串替換舊的字符或字符串
//11、split();對字符串拆分
String str4 = "[wangbingbing shi ,zui mei de]";
System.out.println(str4.replace("wang","li"));

//加上[] 意味着,可以同時分離空格和逗號(正則表達式)
//+ 意味着出現多個空格和逗號都可以去除
String[] arr = str4.split("[ ,]+");
System.out.println(arr.length);
for (String s:arr
     ) {
    System.out.print(s);

}


//12、補充兩個方法equals()、compareTo();
String str5 = "hello";
String str6 = "HELLO";
//equalsIgnoreCase()忽視字母大小進行比較
System.out.println(str5.equalsIgnoreCase(str6));

//compareTo()長度一樣,依次比較的是字符
String str7 = "abc";
String str8 = "xyz";
System.out.println(str7.compareTo(str8));

//長度不一樣,就比長度
String str9 = "abc";
String str10 = "abcbnm";
System.out.println(str9.compareTo(str10));

StringBuffer和StringBuilder

StringBuffer:可變長字符串,JDK1.0提供,運行效率低,線程安全,用於多線程

StringBuilder:可變長字符串,JDK1.5提供,運行效率高,線程不安全,用於單線程

/**
 * StringBuffer和StringBuilder
 * 和String區別
 * 1、效率比String更高
 * 2、比String更節省內存
 */
public class Demo04 {
    public static void main(String[] args) {
        StringBuffer sb = new StringBuffer();
        //1、append()、追加
        sb.append("wangbingbing");
        System.out.println(sb);
        sb.append("zuimei");
        System.out.println(sb.toString());
        //2、insert()、插入
        sb.insert(0,"woshuo");
        System.out.println(sb.toString());
        //3、replace()、替換
        sb.replace(0,2,"ni");
        System.out.println(sb.toString());
        //4、delete()、刪除
        sb.delete(0,6);
        System.out.println(sb.toString());

        sb.delete(0,sb.length());
        System.out.println(sb.length());
    }
}
/**
 * 證明StringBuilder效率高於String
 *差距是真的大
 */
public class Demo05 {
    public static void main(String[] args) {
        //開始時間
        long start = System.currentTimeMillis();
//        String string = "";
//        //String的用時
//        for (int i = 0; i < 99999; i++) {
//            string+=i;
//        }
//        System.out.println(string);

        //StringBuilder的用時
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 99999; i++) {
            sb.append(i);
        }
        System.out.println(sb);
        //結束時間
        long end = System.currentTimeMillis();
        System.out.println("用時"+(end-start));
    }
}

輸出結果:

StringBuilder:用時19

StringBuffer:用時22036

BigDecimal的使用

作用:精確計算浮點數

/**
 * BigDecimal的作用
 */
public class Demo06 {
    public static void main(String[] args) {
        //思考?為什么結果不是准確的
        //double是近似值存儲,不符合要求,需要借助BigDecimal
        double d1 = 1.0;
        double d2 = 0.9;
        System.out.println(d1-d2);

        BigDecimal bd1 = new BigDecimal("1.0");
        BigDecimal bd2 = new BigDecimal("0.9");

        //減法
        BigDecimal r1 = bd1.subtract(bd2);
        System.out.println(r1);

        //加法
        BigDecimal r2 = bd1.add(bd2);
        System.out.println(r2);

        //乘法
        BigDecimal r3 = bd1.multiply(bd2);
        System.out.println(r3);

        //除法
        //1.4-0.5/0.9
        BigDecimal r4 = new BigDecimal("1.4")
                .subtract(new BigDecimal("0.5"))
                .divide(new BigDecimal("0.9"));
        System.out.println(r4);

        //除法涉及到的近似值
        BigDecimal r5 = new BigDecimal("10").divide(new BigDecimal("3"),3,BigDecimal.ROUND_HALF_UP);
        System.out.println(r5);
    }

}

在計算除法時

除法:.divide(new BigDecimal("3"),scal,RoundingMode mode);

參數

scal:指定小數點精確到小數點后幾位

mode:指定小數部分的取舍模式,通常采用四舍五入的模式(.ROUND_HALF_UP)

Date類

Date表示特定的瞬間,精確到毫秒;Date類中大部分方法都已經被Calendar類中的方法所取代。

時間單位

  • 1秒=1000毫秒

  • 1毫秒=1000微秒

  • 1微秒=1000納秒

/**
 * Date方法
 *
 */
public class Demo07 {
    public static void main(String[] args) {
        //創建對象
        Date date1 = new Date();
        //當前時間
        System.out.println(date1.toString());
        System.out.println(date1.toLocaleString());
        //昨天時間
        Date date2 = new Date(date1.getTime()-60*60*24*1000);
        System.out.println(date2.toLocaleString());

        //方法after before
        boolean b1 = date1.after(date2);
        System.out.println(b1);
        boolean b2 = date1.before(date2);
        System.out.println(b2);

        //比較CompareTo()
        int d = date2.compareTo(date1);
        System.out.println(d);

        //比較是否相等equals()
        boolean b3 = date1.equals(date2);
        System.out.println(b3);
    }
}

Calendar類

作用:Calendar提供了獲取或設置各種日歷字段的方法

/**
 * Calendar類
 */
public class Demo08 {
    public static void main(String[] args) {
        //因為Calendar修飾符是protected,所以無法new
        //1、創建對象
        Calendar calendar = Calendar.getInstance();
        System.out.println(calendar.getTime().toLocaleString());
        System.out.println(calendar.getTimeInMillis());

        //查看時間
        //年
        int year = calendar.get(Calendar.YEAR);
        //月
        int month = calendar.get(Calendar.MONTH);
        //日
        int day = calendar.get(Calendar.DAY_OF_MONTH);
        //HOUR_OF_DAY代表24小時制
        int hour = calendar.get(Calendar.HOUR_OF_DAY);
        //分
        int minute = calendar.get(Calendar.MINUTE);
        //秒
        int second = calendar.get(Calendar.SECOND);
        System.out.println("年" + year +
                "月" + month +
                "日" + day +
                "時" + hour +
                "分" + minute +
                "秒" + second);

        //3、set方法修改時間
        Calendar calendar1 = Calendar.getInstance();
        calendar1.set(Calendar.DAY_OF_MONTH,5);
        System.out.println(calendar1.getTime().toLocaleString());

        //4、add方法修改時間
        calendar1.add(Calendar.HOUR_OF_DAY,-1);
        System.out.println(calendar1.getTime().toLocaleString());

        //5、補充方法,查看參數的最大值
        int max = calendar1.getActualMaximum(Calendar.DAY_OF_MONTH);
        int min = calendar1.getActualMinimum(Calendar.DAY_OF_MONTH);
        System.out.println(max);
        System.out.println(min);

    }
}

SimpleDateFormat類

SimpleDateFormat是一個以語言環境有關的方式來格式化和解析日期的具體類

進行格式化(日期->文本)、解析(文本->日期)

public class Demo09 {
    public static void main(String[] args) throws ParseException {
        //1、創建SimpleDateFormat對象
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss");
        //創建Date
        Date date = new Date();
        //格式化date 把日期轉換成字符串
        String s1 = simpleDateFormat.format(date);
        System.out.println(s1);
        //解析,格式要與simpleDateFormat規定的格式相同
            Date date1 = simpleDateFormat.parse("2002-02-02 10-11-11");
        System.out.println(date1);
    }
}

System類

system系統類,主要用於獲取系統的屬性數據和其他操作,構造方法私有的。

/**
 * System類
 */
public class Demo10 {
    public static void main(String[] args) {

        //1、arraycopy:數組的復制
        //src:原數組
        //srcPos:從原數組哪個位置開始復制
        //dest:目標數組
        //destPos:從目標數組的哪個位置開始粘貼
        //length:復制的長度
        int[] arr1 = {1,2,3,4,56,6};
        int[] arr2 = new int[8];
        System.arraycopy(arr1,0,arr2,0,6);

        for (int i = 0; i < arr2.length; i++) {
            System.out.println(arr2[i]);
        }

//        Arrays.copyOf();還是使用的System.arraycopy,

        //2、復制當前系統時間
        long start = System.currentTimeMillis();
        for (int i = 0; i < 99999999; i++) {
            for (int j = 0; j < 99999999; j++) {
                int result = i+j;
            }
        }
        long end = System.currentTimeMillis();
        System.out.println("用時:"+(end-start));

        //3、建議JVM啟動垃圾回收器回收垃圾
        System.gc();

        //4、退出JVM如果參數為0,正常退出,非0表示異常退出
        System.exit(0);
        System.out.println("上面喊收工了,后面就不執行了");
    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM