String name = "老馬說編程"; // 常量池
String name2 = new String("老馬說編程"); // 堆對象
name += "說編程"; // 底層用 StringBuilder
String desc = ",探索編程本質";
System.out.println(name + desc); // 老馬說編程,探索編程本質
isEmpty()、length()substring(begin, end)indexOf/lastIndexOf 查找字符/子串contains(CharSequence)startsWith/endsWithequals/equalsIgnoreCasecompareTo/compareToIgnoreCasetoUpperCase/toLowerCaseconcat/replace/trimsplit(regex) 正則分割private final char value[];
構造器會拷貝傳入數組,不直接引用。核心方法均操作此數組。
codePointAt(index), codePointBefore(index), codePointCount(begin, end), offsetByCodePoints(index, offset)
內部用 UTF-16BE。Charset 類處理編碼:
Charset.defaultCharset() // 系統默認編碼
Charset.forName("GB18030") // 指定編碼
// String 轉 byte[]
getBytes(), getBytes(charsetName), getBytes(Charset)
// byte[] 轉 String
new String(bytes, charsetName), new String(bytes, Charset)
final,不可繼承value 數組 final,引用不可變concat() 內部 Arrays.copyOf + new String()優點:線程安全、可共享、Hash 緩存可靠。缺點:頻繁修改性能差,改用 StringBuilder/StringBuffer。
String s1 = "abc";
String s2 = "abc";
System.out.println(s1 == s2); // true,指向常量池同一對象
String s3 = new String("abc");
String s4 = new String("abc");
System.out.println(s3 == s4); // false,堆中兩個對象
System.out.println(s3.equals(s4)); // true,內容相同
常量池保證字面量唯一,new 強制創建新對象。
private int hash; // 默認 0
public int hashCode() {
int h = hash;
if (h == 0 && value.length > 0) {
for (char c : value) h = 31 * h + c;
hash = h;
}
return h;
}
算法:s[0]*31^(n-1) + ... + s[n-1]。31 選擇因:散列均勻、31*h == (h<<5)-h 移位高效。
split(regex)matches(regex)replaceFirst/replaceAll(regex, replacement)複雜正則建議用 Pattern/Matcher。
String 核心:不可變 char 數組封裝、常量池優化、編碼轉換橋樑、Hash 緩存。下期講 StringBuilder/StringBuffer。