面向物件-字串
字串本質及分類
什麼是字串?
把多個字串連在一起
字串分類
1.可變字串(StringBuffer,StringBuilder): 定義好之後,還可以進行修改, 修改是,不會建立新的記憶體地址 (記憶體地址不可變)
2.不可變字串(String): 定義好了,就不能再去改變, 在記憶體當中不能再去修改了,修改就會建立新的記憶體地址
字串的本質 其實它是一個 chat[ ] 型別的陣列 private final char value[ ];
String, StringBuffer, StringBuilder 都實現了:CharSequence介面 ,遵守了規範可以使用裡面的方法
字串的兩種比較
不可變字串(String) String str = "ABC";在記憶體當中不能再去修改了,修改就會建立新的地址 str = "cd";
字串是放到方法區常量池當中,這裡還沒講常量池,先放到堆當中
String建立 1.直接賦值 String str = "ABC"; 2.通過構造器來建立String str = new String("ABC");
字串物件為空
1.表示引用為空String str = null;還沒初始化,沒有分配記憶體空間 2.表示空字串String str = " ";已經建立了物件,已經分配了記憶體,內容為空
字串的比較
比較兩個字串相不相等
- == 比較兩個記憶體地址是否相等
String str = "ABC"; String str2 = new String("ABC"); if (str == str2) {比的是物件的地址 System.out.println("相等"); }else { System.out.println("不相等"); } 不相等
- 使用在object中的一個方法 equals 和 == 相同
因為 String 類覆蓋了 equals 方法 1.先去比較物件地址是否相等 2.如果不相等,再去判斷是否為String, 是的話再去逐個判斷兩者的長度相不相等,在判斷每一個字元相不相等 if (str.equals(str2)) {相等 System.out.println("相等"); }else { System.out.println("不相等"); }
String類覆蓋了 equals 方法
建議子類,自己去覆蓋此方法,自己在內部當中去根據自己的需求去判斷兩個值是否相等
字串建立以及常量池記憶體分析
常量--->方法區當中有一個常量池
String str = "ABC"; String str3 = "ABC"; System.out.println(str==str3);true String str2 = new String("ABC"); 1.String str = "ABCD";區域性變數 使用String str = "ABCD";建立字串 要麼建立一個物件,要麼不建立 會先到常量池當中看一下有沒有該字串常量 如果說已經有了,就直接使用,不會建立新的字串常量池地址 如果常量池當中沒有的話,就會在常量池當中建立一個物件 2.String str2 = new String("ABCD");建立物件 至少得要建立一個物件,因為使用了new 在堆當中,至少得要建立一個物件 看一下,常量池當中,有沒有傳入的字串常量 如果沒有的話,會建立一個字串常量,放到常量池當中 System.out.println(str2);ABCD會在堆中找到它的建立地址,這個地址會有一個常量引用,所以就把ABCD打印出來了
字串工具類設計
給一個字串,判斷是否為空,如果為空返回false 不為空就返回一個true 一個方法當中有return 所在的方法 會立即停止執行 定義一個方法 static boolean hasLength(String str) { if (str != null && !"".equals(str.replace(" ", ""))) {// 不為空 return true; } // 為空 return false;//一個方法當中有return 所在的方法 會立即停止執行 } 可以直接簡寫成 static boolean hasLength(String str) { return str != null && !"".equals(str.replace(" ", "")); } 在main方法中執行 boolean res = hasLength(s); System.out.println(res);
把方法抽成一個工具類 public class StringUtils { private StringUtils() {}; 工具類有兩種情況:1.單例模式,2.全部方法搞成靜態 static boolean hasLength(String str) { return str != null && !"".equals(str.replace(" ", "")); } } System.out.println(StringUtils.hasLength(s));
字串拼接效能演示
1.可變字串(StringBuffer,StringBuilder): 定義好之後,還可以進行修改, 修改是,不會建立新的記憶體地址(記憶體地址不可變) 2.不可變字串(String): 定義好了,就不能再去改變,在記憶體當中不能再去修改了 ,修改就會建立新的記憶體地址
StringBuilder:方法前面是沒有synchronized的效率 高一些 StringBuffer:方法前面多了一個synchronized加鎖 更安全 兩種方法使用str.append("傳入字串") 速度上:String>StringBuffer>StringBuilder 可變字串效能高一些,因為記憶體地址不會改變 做10000字串拼接測試 public class SystemMethod { static void testString() { long begin = System.currentTimeMillis(); String str = ""; for (int i = 0; i <= 10000; i++) { str += i; } long last = System.currentTimeMillis(); System.out.println(last - begin);//10000次String的花費250毫秒 } static void testBuilder() { long begin = System.currentTimeMillis(); StringBuilder str = new StringBuilder(); for (int i = 0; i <= 100000; i++) { //str += i;StringBuilder 不是用這種方式拼接的 str.append(i); } long last = System.currentTimeMillis(); System.out.println(last - begin);//改為10萬次才花費10毫秒 }; static void testBuffer() { long begin = System.currentTimeMillis(); StringBuffer str = new StringBuffer(); for (int i = 0; i <= 100000; i++) { str.append(i); } long last = System.currentTimeMillis(); System.out.println(last - begin);//改為10萬次才花費10毫秒 }; public static void main(String[] args) { testString(); testBuilder(); testBuffer(); } }
可變字串StringBuilder
public static void main(String[] args) { 建立的可變字串,初始容量是16 如果超過了,會自動擴容擴容是 原來容量 * 2 + 2 sb = sb2 因為它的構造器裡傳了個16public StringBuilder() { super(16); } 可變字串,本質還是一個char型別的陣列 StringBuilder sb = new StringBuilder(); StringBuilder sb2 = new StringBuilder(16); System.out.println(sb.capacity());//獲取sb裡面的容量大小 鏈式變成append 裡面返回的是一個this 返回自身 sb.append("abcdefg").append("123"); sb.append("123"); System.out.println(sb);//abcdefg123123在原來字串的基礎上進行拼接 刪除指定位置的字元 sb.deleteCharAt(1); System.out.println(sb);//acdefg123123把b刪除了 可變字元轉成不可變 String s = sb.toString(); 把不可變型別轉成可變型別,直接傳入字串到構造器 StringBuilder sb2 = new StringBuilder(s); 字串的反轉 System.out.println(sb2.reverse());//321321gfedca }
字串總結








