一、基本用法
字串是Java中特殊的類,使用方法像基本資料型別,被廣泛應用在Java程式設計中。Java沒有內建的字串型別,而是在標準Java類庫中提供了一個String類來建立和操作字串。String是不可變的,因為該類中使用final關鍵字修飾字符陣列來儲存字串,即private final char value[]。
常用方法 |
功能 |
indexOf() |
返回指定字元的索引 |
charAt() |
返回指定索引的字元 |
subString() |
擷取字串 |
split() |
分割字元,返回字元陣列 |
length() |
返回字串長度 |
getByte() |
返回字串的byte型別陣列 |
toLowerCase |
轉為小寫字母 |
toUpperCase |
轉為大寫字母 |
trim() |
去除字串兩端空白 |
equal() |
字串比較 |
(一) 字串定義
// 1.直接定義字串 String s1 = "fuxing"; // 2.使用String類定義 String s2 = new String("fuxing");
1. 區別
第一種方式是先檢驗字串常量中有沒有"fuxing",如果字串常量池中沒有,則建立一個,然後用s1指向常量池中的物件,有則直接指向。
第二種方式是直接在堆記憶體空間建立一個新的物件。
且s1和s2並不相等,一個是堆記憶體的String物件,一個是常量池中的String物件
(二) new String("fuxing")到底建立了幾個物件?
透過 new 建立字串的方式可能會建立 1 個或 2 個物件,如果常量池中已經存在此字串只會在堆上建立一個變數,並指向字串常量池中的值,如果字串常量池中沒有相關的字元,會先建立字串在返回此字串的引用給堆空間的變數
(三) String和int相互轉換
【String轉int】
在 String轉換int時,String的值一定是整數,否則會報數字轉換異常(java.lang.NumberFormatException)。
public static void main(String[] args) { String str = "123"; int n = 0; // 第一種轉換方法:Integer.parseInt(str) n = Integer.parseInt(str); System.out.println(n); // 123 // 第二種轉換方法:Integer.valueOf(str).intValue() n = 0; n = Integer.valueOf(str).intValue(); System.out.println(n); // 123 }
【int轉String】
public static void main(String[] args) { int num = 10; // 第一種方法:String.valueOf(i); 注意:引數i不能為空,否則會報空指標異常(NullPointerException) num = 10; String str = String.valueOf(num); System.out.println("str:" + str); // 第二種方法:Integer.toString(i); num = 10; String str2 = Integer.toString(num); System.out.println("str2:" + str2); // 第三種方法:"" + i; String str3 = num + ""; System.out.println("str3:" + str3); }
(四) 去除字串中的空格
String str = " hello "; //hello兩邊時空格 System.out.println(str.length()); // 輸出 7 System.out.println(str.trim().length()); // 輸出 5
(五) 擷取字串
【從索引位置開始至結尾】
public static void main(String[] args) { String str = "12345"; String result = str.substring(3); System.out.println(result); // 輸出:45 }
【擷取指定範圍】
public static void main(String[] args) { String str = "12345"; // 起始索引從0開始,終止索引從1開始 String result = str.substring(1,3); System.out.println(result); // 輸出:23 }
(六) 分割字串
public static void main(String[] args) { String Colors = "Red,Black,White,Yellow,Blue"; String[] arr1 = Colors.split(","); // 不限制元素個數 String[] arr2 = Colors.split(",", 3); // 限制元素個數為3 System.out.println("所有顏色為:"); for (int i = 0; i < arr1.length; i++) { System.out.println(arr1[i]); } System.out.println("前三個顏色為:"); for (int j = 0; j < arr2.length; j++) { System.out.println(arr2[j]); } }
二、StringBuffer & StringBuilder
(一) StringBuffer
【建立方式】
// 1.定義一個空的字串緩衝區,含有16個字元的容量 StringBuffer str1 = new StringBuffer(); // 2.定義一個含有10個字元容量的字串緩衝區 StringBuffer str2 = new StringBuffer(10); // 3.定義一個含有(16+4)的字串緩衝區,"福星高照"為4個字元 StringBuffer str3 = new StringBuffer("福星高照"); // capacity()方法返回字串的容量大小 System.out.println(str1.capacity()); // 輸出 16 System.out.println(str2.capacity()); // 輸出 10 System.out.println(str3.capacity()); // 輸出 20
【追加字串】
StringBuffer buffer = new StringBuffer("hello"); // 建立一個 StringBuffer 物件 String str = "World"; buffer.append(str); // 向StringBuffer物件追加str字串到末尾,類似於字串的連線 System.out.println(buffer.substring(0)); // HelloWorld
【其他常用方法】
StringBuffer sb = new StringBuffer("hello"); // 1.替換字元 sb.setCharAt(1,'E'); System.out.println(sb); // 輸出:hEllo // 2.反轉字串 sb.reverse(); System.out.println(sb); // 輸出:olleh // 3.刪除字串 sb.deleteCharAt(2); System.out.println(sb); // 輸出:helo
(二) String、StringBuffer和StringBuilder的對比
【StringBuilder】
StringBuilder類是 JDK 1.5 新增的類,它也代表可變字串物件。實際上,StringBuilder和StringBuffer功能基本相似,方法也差不多。不同的是,StringBuffer是執行緒安全的,而StringBuilder則沒有實現執行緒安全功能,所以效能略高。因此在通常情況下,如果需要建立一個內容可變的字串物件,則應該優先考慮使用StringBuilder類。
【三者關聯】
三者都實現 CharSequence介面。CharSequence是一個定義字串操作的介面,它只包括length()、charAt(int index)、subSequence(int start, int end) 這幾個 API。
【三者區別】
對比方向 |
String |
StringBuffer |
StringBuilder |
執行緒安全性 |
安全(可理解為常量) |
安全(對方法或呼叫的方法加了同步鎖) |
非執行緒安全 |
效能 |
最低(每次改變生成新的物件) |
正常(僅對本身進行操作,不會建立) |
較快 |
適用場景 |
操作少量的資料 |
多執行緒下操作大量字串 |
單執行緒下操作大量字串 |
三、注意事項
(一) String 有長度限制嗎?是多少?
https://blog.csdn.net/weixin_59624686/article/details/131560058
1. 編譯時限制:65534
我們知道字串常量會被放入方法區的常量池中,JVM 規範對常量池有所限制。常量池中的每一種資料項都有自己的型別。Java 中的 UTF-8 編碼的 Unicode 字串在常量池中以CONSTANT_Utf8 型別表示。
CONSTANT_Utf8的數據結構如下:
CONSTANT_Utf8_info { u1 tag; u2 length; u1 bytes[length]; }
我們重點關注下長度為 length 的那個 bytes 陣列,這個陣列就是真正儲存常量資料的地方,而 length 就是陣列可以儲存的最大位元組數。length 的型別是 u2,u2 是無符號的 16 位整數,因此理論上允許的的最大長度是 2^16-1=65535。但是由於 JVM 需要 1 個位元組表示結束指令,所以編譯時 String 最大長度不能超過 65534。
2. 執行時限制:231-1
字串的內容是由一個字元陣列 char[] 來儲存的,由於陣列的長度及索引是整數,且 String 類中返回字串長度的方法 length() 的返回值也是 int ,所以透過檢視 java 原始碼中的類 Integer 我們可以看到 Integer 的最大長度不能超過 2^31 -1。
但是這個也是理論上的長度,實際的長度還要看你JVM的記憶體。最大的字串會佔用多大的記憶體為 4GB。計算方式如下:
(2^31-1)*2*16/8/1024/1024/1024 = 4GB
所以在最壞的情況下,一個最大的字串要佔用4GB的記憶體。如果你的虛擬機器不能分配這麼多記憶體的話,會直接報錯的。
JDK9 以後對 String 的儲存進行了最佳化。底層不再使用 char 陣列儲存字串,而是使用 byte 陣列。對於 LATIN1 字元的字串可以節省一倍的記憶體空間。