day04-String-StringBuffer-StringBuilder

String、StringBuffer、StringBuilder

三者聯繫區別

  • 都是final類,不能再被繼承
  • String長度不可變,StringBuffer、Stringbuilder長度可變
  • StringBuffer是線程安全的、Stringbuilder是線程不安全的,兩個類的方法都是相同的,StringBuffer在方法上加了Synchronized修飾,保證線程安全。
  • StringBuilder有更好的性能相比StringBuffer
  • 如果一個String類型的字符串,在編譯時就可以確定是一個字符串常量,在編譯完成之後,字符串會自動拼接成一個常量,此時String的速度比StringBuffer和StringBuilder性能好的多
  • 在java中,通過使用"+"符號來串聯字符串的時候實際上底層會轉成通過StringBuilder實例的append0方法來實現的。
    當我們在JDK 1.4的環境下編寫代碼時,對於上述這種一次性拼接多個字符串的情況,建議最好使用+號來處理。這樣,當JDK 升級到1.5及以上版本時,編譯器將會自動將其轉換爲StringBuilder來拼接字符串,從而提高字符串拼接效率。
    當然,推薦使用+號拼接字符串也僅限於在一條語句中拼接多個字符串時使用。如果分散在多條語句中拼接一個字符串,仍然建議使用StringBuffer或StringBuilder。https://www.jb51.net/article/84536.htm講的很詳細。

理解String不可變

  • final
    首先原因是因爲String的不可變,如果String不是final,那麼就可以繼承String類,然後覆蓋其方法,是的這些方法可以修改字符串,違背了String不可變性
  • 不可變原因
    提高效率:比如一個字符串Stimngs1=“abc",“abc”被放到常量池裏面去了,我再Strings2 = “abc"並不會複製字符串“abc”,只會多個引用指向原來那個常量,這樣就提高了效率,而這一前提是string不可變,如果可變,那麼多個引用指向同一個字符串常量,我就可以通過一個引用改變字符串,然後其他引用就被影響了安全: string常被用來表示url,文件路徑,如果string可變或存在安全隱患string不可變,那麼他的hashcode就一-樣,不用每次重新計算了
  • 不變性理解

String類是被final進行修飾的,不能被繼承。
在用+號鏈接字符串的時候會創建新的字符串。
String s = new 5tring(“Hello world”);可能創建兩個對象也可能創建一個對象。如果靜態區中有"Hello world"字符串常量對象的話,則僅僅在堆中創建一個對象。 如果靜態區中沒有"Hello world"對象,則堆上和靜態區中都需要創建對象。
在java中,通過使用"+"符號來串聯字符串的時候實際上底層會轉成通過StringBuilder實例的append()方法來實現。

==和equals

= = :比較引用類型比較的是地址值是否相同
equals:比較引用類型默認也是比較地址值是否相同,而String類重寫了equals()方法,比較的是內容是否相同。
對於字符串變量來說,使用“ = = ” 和 “ equals() ”方法比較字符串時,其比較方法不同。
1、“ = = ”比較兩個變量本身的值,即兩個對象在內存中的首地址。
(java中,對象的首地址是它在內存中存放的起始地址,它後面的地址是用來存放它所包含的各個屬性的地址,所以內存中會用多個內存塊來存放對象的各個參數,而通過這個首地址就可以找到該對象,進而可以找到該對象的各個屬性)
2、“equals()”比較字符串中所包含的內容是否相同。(String重寫了Object的equals方法)
3、StringBuffer、Stringbuilder類中沒有重新定義equals這個方法,因此這個方法就來自Object類,
(Object類中的equals方法是用來比較“地址”的,所以等於false)

String s = new String(“hello”)和String s = “hello”;的區別?

// 有。前者會創建2個對象,後者創建1個對象。
String s1 = new String("hello");
String s2 = "hello";
System.out.println(s1 == s2);// false
System.out.println(s1.equals(s2));// true
//相同內容不同地址

//練習
String s1 = new String("hello");
String s2 = new String("hello");
System.out.println(s1 == s2);// false
System.out.println(s1.equals(s2));// true

String s3 = new String("hello");
String s4 = "hello";
System.out.println(s3 == s4);// false
System.out.println(s3.equals(s4));// true

String s5 = "hello";
String s6 = "hello";
System.out.println(s5 == s6);// true
System.out.println(s5.equals(s6));// true

在這裏插入圖片描述

看程序寫結果

字符串如果是變量相加,先開空間,在拼接。
字符串如果是常量相加,是先加,然後在常量池找,如果有就直接返回,否則,就創建。

String s1 = "hello";
String s2 = "world";
String s3 = "helloworld";
System.out.println(s3 == s1 + s2);// false,s1、s2都是變量,所以先開空間,所以一開空間就和s3不一樣了
System.out.println(s3.equals((s1 + s2)));// true,內容相同

System.out.println(s3 == "hello" + "world");// true,就像前面做過的 byte=3+4
System.out.println(s3.equals("hello" + "world"));// true內容相同

// 通過反編譯看源碼,我們知道這裏已經做好了處理。
// System.out.println(s3 == "helloworld");
// System.out.println(s3.equals("helloworld"));
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章