欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java中關于String StringBuffer StringBuilder特性深度解析

 更新時間:2021年09月13日 17:12:23   作者:威斯布魯克.猩猩  
這篇文章主要介紹了Java中關于String StringBuffer StringBuilder特性深度解析,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下

1.String

String類:字符串是常量,使用一對""引起來表示。他們的值在創(chuàng)建之后不能修改。
1.String聲明為final的,不可被繼承
2.String實現(xiàn)了Serializable接口,表示字符串時支持序列化的。
實現(xiàn)了Comparable接口:表示String可以比較大小
3.String內(nèi)部定義了final char[] value用于存儲字符串數(shù)據(jù)
4.String:代表不可變的字符序列。簡稱:不可變性

體現(xiàn):

1.當對字符串重新賦值時,需要重寫指定內(nèi)存區(qū)域賦值,不能使用原有的value進行賦值
2.當對現(xiàn)有的字符串進行連接( + )操作時,也需要重寫指定內(nèi)存區(qū)域賦值,不能使用原有的 value進行賦值
3.當調(diào)用String的replace()方法修改指定字符或字符串時,也需要重新指定內(nèi)存區(qū)域賦值,不能使用原有的value進行賦值
5.通過字面量的方式(區(qū)別于new)給一個字符串賦值,此時的字符串值聲明在字符串常量池中。
6.字符串常量池是不會存儲相同內(nèi)容的字符串的。

    public void test1(){
        //體現(xiàn)1
        String s1 = "abc";//字面量的定義方式
        String s2 = "abc";
        s1 = "hello";
        System.out.println(s1 == s2);//比較s1和s2的地址值
        System.out.println(s1);//hello
        System.out.println(s2);//abc
        System.out.println("********************************");
        //體現(xiàn)2
        String s3 = "abc";
        s3 += "def";
        System.out.println(s3);//abcdef
        System.out.println(s2);//abc
        System.out.println("***********************************");
        //體現(xiàn)3
        String s4 = "abc";
        String s5 = s4.replace('a','m');
        System.out.println(s4);//abc
        System.out.println(s5);//mbc
    }

String的實例化方式:

方式一:通過字面量定義的方式
方式二:通過new + 構(gòu)造器的方式
面試題:String s = new String("abc")的方式創(chuàng)建對象,在內(nèi)存中創(chuàng)建了幾個對象?
兩個:一個是堆空間中new結(jié)構(gòu),另一個是char[]對應的常量池中的數(shù)據(jù):"abc"

 public void Test2(){
        //通過字面量定義的方式:此時的s1和s2的數(shù)據(jù)javaEE聲明在方法區(qū)中的字符串常量池中。
        String s1 = "javaEE";
        String s2 = "javaEE";
        //通過new + 構(gòu)造器的方式:此時的s3和s4保存的地址值,是數(shù)據(jù)在堆空間中開辟空間以后對應的地址值
        String s3 = new String("javaEE");
        String s4 = new String("javaEE");
        System.out.println(s1 == s2);//true
        System.out.println(s1 == s3);//false
        System.out.println(s1 == s4);//false
        System.out.println(s3 == s4);//false
        System.out.println("******************************************");
        Person p1 = new Person("Tom",12);
        Person p2 = new Person("Tom",12);
        System.out.println(p1.name.equals(p2.name));//true
        System.out.println(p1.name == p2.name);//true//通過字面量的方式賦值,所以是true!!!!!!!!!!!!
    }

public void Test3(){
        String s1 = "javaEE";
        String s2 = "hadoop";
        String s3 = "javaEEhadoop";
        String s4 = "javaEE" + "hadoop";
        String s5 = s1 + "hadoop";
        String s6 = "javaEE" + s2;
        String s7 = s1 + s2;
        System.out.println(s3 == s4);//true
        System.out.println(s3 == s5);//false//字面值方式的儲存在常量池,有變量的在堆里
        System.out.println(s3 == s6);//false
        System.out.println(s3 == s7);//false
        System.out.println(s5 == s6);//false
        System.out.println(s5 == s7);//false
        System.out.println(s6 == s7);//false
        String s8 = s5.intern();//返回值得到的s8使用的常量池已經(jīng)存在的"javaEEhadoop"
        System.out.println(s3 == s8);//true
    }
 @Test
    public void test4(){
        String s1 = "javaEEhadoop";
        String s2 = "javaEE";
        String s3 = s2 + "hadoop";
        System.out.println(s1 == s3);//false
        final String s4 = "javaEE";//s4:常量
        String s5 = s4 + "hadoop";
        System.out.println(s1 == s5);//true
    }

結(jié)論:
1.常量與常量的拼接結(jié)果在常量池。且常量池中不會存在相同內(nèi)容的常量。
2.只要其中有一個是變量,結(jié)果就在堆中。
3.如果拼接的結(jié)果調(diào)用intern()方法,返回值就在常量池中

一道有深度的面試題

public class StringTest {
    String str = new String("good");
    char[] ch = {'t','e','s','t'};
    public void change(String str,char ch[]){
        str = "test ok";
        ch[0] = 'b';
    }
    public static void main(String[] args) {
        StringTest ex = new StringTest();
        ex.change(ex.str,ex.ch);
        System.out.println(ex.str);//good
        System.out.println(ex.ch);//best
    }
}

解析:

1.涉及的知識:

關于變量的賦值:如果變量是基本數(shù)據(jù)類型,此時賦值的是變量所保存的數(shù)據(jù)值。

如果變量是引用數(shù)據(jù)類型,此時賦值的是變量所保存的數(shù)據(jù)的地址值。

Java中的方法的值傳遞機制:所謂的值傳遞,就是將實參值的副本傳入方法里,而參數(shù)本身不受影響。

2.面試題的解析:因為傳值過程中,傳給形參的是地址值,而通過String試圖修改實參是行不通的,因為String有不可變性。而數(shù)組的內(nèi)容是可以修改的,通過形參修改堆空間中的數(shù)組中的內(nèi)容,實參也會改變,因為形參和實參指向?qū)臻g中的同一個內(nèi)容

String的常用方法及其測試

 public void test1(){
        String s1 = "HelloWorld";
        System.out.println(s1.length());//10
        System.out.println(s1.charAt(0));//H
        System.out.println(s1.isEmpty());//false
        String s2 = s1.toLowerCase();
        System.out.println(s1);//HelloWorld//s1是不可變的,仍然為原來的字符串
        System.out.println(s2);//helloworld//改成小寫以后的字符串
        String s3 = "  he  llo  world  ";
        String s4 = s3.trim();
        System.out.println("-----" + s3 + "-----");//-----  he  llo  world  -----
        System.out.println("-----" + s4 + "-----");// -----he  llo  world-----
}
public void test2(){
        String s1 = "HelloWorld";
        String s2 = "helloworld";
        System.out.println(s1.equals(s2));//false
        System.out.println(s1.equalsIgnoreCase(s2));//true
        String s3 = "abc";
        String s4 = s3.concat("def");
        System.out.println(s4);//abcdef
        String s5 = "abc";
        String s6 = new String("abe");
        System.out.println(s5.compareTo(s6));//-2
        String s7 = "開關電源適配器";
        String s8 = s7.substring(2);
        System.out.println(s7);//開關電源適配器
        System.out.println(s8);//電源適配器
        String s9 = s7.substring(2,5);
        System.out.println(s9);//電源適
 }

 public void test3(){
        String str1 = "helloworld";
        boolean b1 = str1.endsWith("rld");
        System.out.println(b1);//true
        boolean b2 = str1.endsWith("He");
        System.out.println(b2);//false
        boolean b3 = str1.startsWith("ll",2);
        System.out.println(b3);//true
        String str2 = "wor";
        System.out.println(str1.contains(str2));//true
        System.out.println(str1.indexOf("lol"));//-1
        System.out.println(str1.indexOf("lo",5));//-1
        String str3 = "hellorworld";
        System.out.println(str3.lastIndexOf("or"));//7
        System.out.println(str3.lastIndexOf("or",6));//4
    }

此方法測試詳見另一篇博客:自動裝箱與自動拆箱

與正則表達式有關的方法的測試

public void test4(){
        String str1 = "北京尚硅谷教育北京";
        String str2 = str1.replace('北','東');
        System.out.println(str1);//北京尚硅谷教育北京
        System.out.println(str2);//  東京尚硅谷教育東京
        String str3 = str1.replace("北京","上海");
        System.out.println(str3);//上海尚硅谷教育上海
        String str = "12hello34world5java7891mysql456";
        //把字符串中的數(shù)字替換成,,如果結(jié)果中開頭和結(jié)尾有,的話去掉
        String string = str.replaceAll("\\d+",",").replaceAll("^,|,$","");
        System.out.println(string);//hello,world,java,mysql
        str = "12345";
        //判斷str字符串中是否全部由數(shù)字組成,既由1-n個數(shù)字組成
        boolean matches = str.matches("\\d+");
        System.out.println(matches);//true
        String tel = "0571-4534289";
        //判斷這是否是一個杭州的固定電話
        boolean result = tel.matches("0571-\\d{7,8}");
        System.out.println(result);//true
        str = "hello|world|java";
        String[] strs = str.split("\\|");
        for(int i = 0;i < strs.length;i++){
            System.out.print(strs[i]);//hello world java
        }
    }

 /*
    String 與 char[]之間的轉(zhuǎn)換
    String --> char[]:調(diào)用String的toCharArray()
    char[] --> String:調(diào)用String的構(gòu)造器
    */
    @Test
    public void test2(){
        String str1 = "abc123";
        char[] charArray = str1.toCharArray();
        for(int i = 0;i < charArray.length;i++){
            System.out.println(charArray[i]);
        }
        char[] arr = new char[]{'h','e','l','l','o'};
        String str2 = new String(arr);
        System.out.println(str2);
    }

/*
    String 與 byte[]之間的轉(zhuǎn)換
    編碼:String --> byte[]:調(diào)用String的getBytes()
    解碼: byte[] --> String:調(diào)用String的構(gòu)造器
    編碼:字符串 --> 字節(jié)(看得懂 --> 看不懂的二進制數(shù)據(jù))
    解碼:編碼的逆過程,字節(jié) --> 字符串 (看不懂的二進制數(shù)據(jù) --> 看的懂)
    說明:解碼時,要求解碼使用的字符集必須與編碼時使用的編碼集一致,否則會出現(xiàn)亂碼。
     */
    @Test
    public void test3() throws UnsupportedEncodingException {
        String str1 = "abc123中國";
        byte[] bytes = str1.getBytes();//使用默認的字符集,進行轉(zhuǎn)換
        System.out.println(Arrays.toString(bytes));//[97, 98, 99, 49, 50, 51, -28, -72, -83, -27, -101, -67]
        byte[] gbks = str1.getBytes("gbk");//使用了gbk字符集進行編碼
        System.out.println(Arrays.toString(gbks));//[97, 98, 99, 49, 50, 51, -42, -48, -71, -6]
        String str2 = new String(bytes);//使用默認的字符集,進行解碼
        System.out.println(str2);//abc123中國
        String str3 = new String(gbks);//abc123�й�//亂碼
        System.out.println(str3);//出現(xiàn)亂碼,原因:編碼集和解碼集不一致!
        String str4 = new String(gbks,"gbk");
        System.out.println(str4);//abc123中國
    }

String、StringBuffer、StringBuilder三者的異同?
String:不可變的字符序列:底層使用char[]存儲
StringBuffer:可變的字符序列:線程安全的,效率低;底層使用char[]存儲
StringBuilder:可變的字符序列:JDK5.0新增的,線程不安全的,效率高;底層使用char[]存儲

源碼分析:

String str = new String();//char[] value = new char[0];
String str1 = new String("abc");//char[] value = new char[]{'a','b','c'};
StringBuffer sb1 = new StringBuffer();//char[] value = new char[16];底層創(chuàng)建了一個長度是16的數(shù)組。
sb1.append('a');//value[0] = 'a';
sb1.append('b');//value[1] = 'b';
StringBuffer sb2 = new StringBuffer("abc");//char[] value = new char["abc".length() + 16];

​​​​問題1. System.out.println(sb2.length());//3
問題2. 擴容問題:如果要添加的數(shù)據(jù)底層數(shù)組盛不下了,那就需要擴容底層的數(shù)組。
默認情況下,擴容為原來容量的2倍 + 2,同時將原有的數(shù)組中的元素復制到新的數(shù)組中
指導意義:開發(fā)中建議大家使用:StringBuffer(int capacity)或StringBuilder(int capacity),
傳入預知的參數(shù)長度,可以避免擴容,如果沒涉及到多線程,或者涉及到多線程,但String不是共享數(shù)據(jù)的時候,建議使用StringBuffer,因為效率高

public void test1(){
        StringBuffer sb1 = new StringBuffer("abc");
        sb1.setCharAt(0,'m');
        System.out.println(sb1);//mbc
    }

對比String、StringBuffer、StringBuilder三者的效率:

從高到低排列:StringBuilder > StringBuffer > String

到此這篇關于Java中關于String StringBuffer StringBuilder特性深度解析的文章就介紹到這了,更多相關Java String StringBuffer StringBuilder內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • ?java簡介及環(huán)境搭建

    ?java簡介及環(huán)境搭建

    這篇文章主要介紹了java簡介及環(huán)境搭建,文章主要介紹Java的發(fā)展史及環(huán)境搭建,對正在學Java的你有一定的參考價值,需要的小伙伴可以參考一下
    2022-03-03
  • Java模擬撲克牌洗牌實現(xiàn)生成52張撲克的方法示例

    Java模擬撲克牌洗牌實現(xiàn)生成52張撲克的方法示例

    這篇文章主要介紹了Java模擬撲克牌洗牌實現(xiàn)生成52張撲克的方法,涉及Java數(shù)組遍歷、重排及輸出等相關操作技巧,需要的朋友可以參考下
    2018-01-01
  • java中HashMap的7種遍歷方式與性能分析

    java中HashMap的7種遍歷方式與性能分析

    本文主要介紹了java中HashMap的7種遍歷方式與性能分析,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • dubbo服務引用之創(chuàng)建Invoker流程詳解

    dubbo服務引用之創(chuàng)建Invoker流程詳解

    這篇文章主要為大家介紹了dubbo服務引用二之創(chuàng)建Invoker流程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-08-08
  • Mybatis查詢返回Map<String,Object>類型的實現(xiàn)

    Mybatis查詢返回Map<String,Object>類型的實現(xiàn)

    本文主要介紹了Mybatis查詢返回Map<String,Object>類型的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-07-07
  • springmvc4+hibernate4分頁查詢功能實現(xiàn)

    springmvc4+hibernate4分頁查詢功能實現(xiàn)

    本篇文章主要介紹了springmvc4+hibernate4分頁查詢功能實現(xiàn),Springmvc+hibernate成為現(xiàn)在很多人用的框架整合,有興趣的可以了解一下。
    2017-01-01
  • Spring中@Lazy注解的使用示例教程

    Spring中@Lazy注解的使用示例教程

    Spring在應用程序上下文啟動時去創(chuàng)建所有的單例bean對象, 而@Lazy注解可以延遲加載bean對象,即在使用時才去初始化,這篇文章主要介紹了Spring中@Lazy注解的使用,需要的朋友可以參考下
    2023-06-06
  • JAVA項目如何打包部署到Linux服務器上

    JAVA項目如何打包部署到Linux服務器上

    本文詳細介紹了在服務器上部署環(huán)境包括JDK、MySQL、Tomcat的設置,以及使用Idea-Maven-SpringBoot進行jar包打包部署的流程,內(nèi)容涵蓋了MySQL配置注意事項、pom.xml配置、打包命令等關鍵步驟,同時,也提供了如何將jar包上傳到Linux服務器并運行的具體方法
    2024-10-10
  • Java inputstream和outputstream使用詳解

    Java inputstream和outputstream使用詳解

    這篇文章主要介紹了Java inputstream和outputstream使用詳解,本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • SpringSecurity自定義登錄界面

    SpringSecurity自定義登錄界面

    這篇文章主要為大家詳細介紹了SpringSecurity自定義登錄界面,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-09-09

最新評論