1. 程式人生 > >Java基礎16-String類(Buffer和Builder)

Java基礎16-String類(Buffer和Builder)

操作 char build 什麽 相同 first 沒有 gin 大寫

一、String類的本質是什麽?

技術分享圖片技術分享圖片

上邊代碼竟然輸出的是一樣的,我們進到String類的源碼中

技術分享圖片

其實,字符串的本質就是字符數組, String 其實就是char數組的封裝

二、字符串的分類

1.不可變得字符串String:當前對象創建完畢之後,該對象的內容是不能改變的,一旦內容改變就是一個新的類
2.可變的字符串:StringBuffer/StringBuilder,當前內容創建完畢之後,該對象的內容可以發生改變,內容改變時對象不變

技術分享圖片技術分享圖片

我們輸出上邊兩段代碼,雖然引用名稱相同,但是當我們重新賦值時,它的hashcode發生了變化,也就是說,str在內存中的地址發生了變化,str="索隆"雖然與str="路飛"名稱相同,但實則是兩個變量,也就是重新在內存中(常量池)開辟了一塊空間

三、String對象的創建

1.直接賦一個字面量:
String str1="abcd";
2.通過構造器
String str2=new String("abcd");

這兩者有什麽區別呢?別著急,請看下文

要說這個問題,那就必須要來了解一個內存中的區域,常量池

常量池:專門存儲常量的地方,都指的方法區中
* 編譯常量池:把字節碼加載進jvm時,存儲的是字節碼的相關信息(不研究)
* 運行常量池:存儲常量數據(研究)

通過這個問題我們就來揭曉

String str4="abcd"和String str5=new String("abcd")的區別?

技術分享圖片

以上代碼創建了幾個String對象呢?

str4最多創建一個,最少不創建,如果常量池中已經存在abcd,直接引用不創建
str5最多創建兩個String對象,至少創建一個,new關鍵字絕對會在堆空間創建內存區域,所以至少創建一個

我們再回頭看第二種的hashcode不同的問題,實際上就是不同的值在常量池中開辟的空間其地址不同,當值變了。也就是這個引用指向的地址發生了變化

技術分享圖片技術分享圖片

str和str10的hashcode竟然是一樣的! 這下我們就明白了吧,只要是值相同,不管叫什麽名字都指向的是同一個地址。

技術分享圖片

四、String對象的空值
1.表示引用為空(null):沒有初始化,沒有分配內存空間
String str3=null;
2.內容為空,已經初始化,分配了內存空間,不過沒有內容
五、判斷字符串非空


1.引用不能為空(null)
2.字符內容不能為空字符串
六、字符串的比較操作
1.使用==運算符,只能比較引用的內存地址是否相同
2.使用equals方法:在object類中和==相同,建議子類覆蓋equals方法去比較內容
七、字符串的比較

技術分享圖片技術分享圖片

1.單獨使用""創建的字符串都是直接量,編譯器已經確定存儲到常量池中
2.使用new String("")創建的對象會存儲到堆內存中,運行時期才創建
3.使用只包含直接量的字符串連接符如"aa"+"bb"創建的也是直接量,編譯器就能確定,已經存儲到常量池中
4.使用包含String直接量(無final修飾符)的字符串表達式(如"aa"+s1)創建的對象是運行期才創建的,存儲在堆中

技術分享圖片

八、常用方法聯系

    //一、String練習,獲取hello開頭的文件名的後綴名
    String filename="abc.java;hello.java";
    //1.一份好來分割字符串,獲取每個的名稱和拓展名
    String[] name=filename.split(";");
    for (String names : name) {
        System.out.println(names);
        //2.判斷每個名稱是否以hello開頭
        if(names.startsWith("hello")) {
            //3.獲取文件名的後綴名,最後一個點的後半截
            names.lastIndexOf(".");
            //截取字符串
            System.out.println(names.substring(names.lastIndexOf(".")));
        }
    }
    //二、單詞首字母大寫
    String str7="willabcad";
    //1.獲取第一個字符,轉換為大寫
    String first=str.substring(0, 1).toUpperCase();
    //2.截取字符串從1到最後
    String last=str.substring(1);
    System.out.println(first+last);
    //trim方法消除前後空格
    System.out.println(" ab cd ".trim().length());
    System.out.println(" ab cd ".length());

九、StringBuilder和StringBuffer

先來看一個小例子

    //使用String/StringBuilder和StringBuffer拼接3萬次
    long begin=System.currentTimeMillis();
    String str8="";
        for(int i=0;i<30000;i++) {
            str8+=i;
        }
        long end=System.currentTimeMillis();
        System.out.println(end-begin);
        //string做字符串拼接性能很低,原因是每次都要new新的對象
        StringBuffer sb=new StringBuffer("");
        long begin2=System.currentTimeMillis();
            for(int i=0;i<30000;i++) {
                sb.append(i);
            }
            long end2=System.currentTimeMillis();
        System.out.println(end2-begin2);
        StringBuilder sbr=new StringBuilder("");
        long begin3=System.currentTimeMillis();
        for(int i=0;i<30000;i++) {
            sbr.append(i);
        }
        long end3=System.currentTimeMillis();
    System.out.println(end3-begin3);
        }

技術分享圖片

經過測試,sbr耗時最短,sb次之,所以拼接字符串使用stringbuffer或者stringbuilder

StringBuilder和StringBuffer都表示可變的字符串,功能方法相同
唯一的區別;
stringbuffer:使用了synchronized修飾符,表示同步,再多錢程並發時保證線程安全
stringbuilder:沒有synchronized,不安全
常用操作
鏈式編程
append,deleteCharAt

Java基礎16-String類(Buffer和Builder)