Java基礎入門語法–String類
今天帶大傢瞭解一下java的基礎法語—String
字符串是我們以後工作中非常常用到的類型. 使用起來都非常簡單方便, 我們一定要使用熟練。
那麼C語言中是否有字符串類型? 答案是 “ 沒有 ” !!
char *p = " hello";
那麼p 的類型是一個字符串類型麼? 不是,p是一個指針!!
而在 Java當中 是有 字符串類型的——String
一、定義方式
創建字符串的方式有很多種,常見的構造 String 的方式如以下:
方式一:直接賦值法
String str1 = "hello";
方式二: new String()
String str2 = new String("hello");
方式三:創建一個字符數組ch,new String ( ch )
char chs[] = {'h','e','l','l','l','o'}; String str3 = new String(chs);
二、內存
在此之前我們要先引入一個概念 字符串常量池
Sting constant pool 字符串常量池 的特性
1.在JDK.7 開始,字符串常量池 被挪到堆裡瞭
2.池內的數據不存在重復
下面我們通過一系列的練習來熟悉 字符串常量池以及 字符串類型數據在內存中的存放。
public static void main(String[] args) { String str1 = "hello"; String str2 = new String("hello"); System.out.println(str1 == str2); String str3 = "hello"; System.out.println(str1 == str3); }
我們來看這樣的代碼,str 代表的是引用\地址,請判斷 兩次打印分別是什麼?
我們來看結果
這個結果說明 str1 和 str2存放的地址是不一樣的, str1 和 str3 存放的地址是一樣的。
好的,為什麼是這樣的結果呢?我們來看一下這幾個字符串類型變量的內存。
“hello”如果存放在常量池當中,就會占用內存,假如這塊空間的地址為111,那麼str1中存放的就是111.
str2 new一個String對象,那麼肯定在堆上開辟內存,假設內存地址是888,在這個String 對象中,存在一個value[] 保存著 orginal傳入的字符串,這個val ==“hello”,因為在字符串常量池中已經有瞭”hello”,所以val 直接指向 常量池中的”hello”.但是str2 指向的依然是 888在堆中的空間。
所以 str1 不等於 str2。
之後呢,str3 也等於”hello”,他也準備把hello放在常量池當中.此時常量池中已經存在”hello”,那麼之後str3 在存放”hello”地址的時候,就指向的是常量池中原來hello的地址。
所以 str1 等於 str3
再看一組練習
public static void main(String[] args) { String str1 = "hello"; String str2 = "hel"+"lo"; System.out.println(str1==str2); String str3 = new String("hel")+"lo"; System.out.println(str1==str3); }
請判斷兩次打印的結果…
結果如下:
下面我們來分析,這組代碼中str變量的內存存放
str1 指向字符串常量池中的 “hello”
str2 是”hel”與”lo” 組合而成的,常量在編譯的時候就已經確定瞭,所以在編譯時,已經被處理為”hello”,所以也指向 常量池中的”hello”。
所以 str1 等於 str2
str3 首先new 瞭一個String(“hel”)對象,在堆中開辟一塊空間,這個對象中的”hel”同時存放在常量池中,之後又在常量池中開辟一塊空間存放 “lo”。兩塊部分之間的”+”,將 String 的對象 與常量池中的 “lo”結合在堆中再次開辟一塊新的空間,這塊內存中的val ==“hello”,str3指向的是合並之後的對象 ,地址為999.
所以 str1 不等於 str3.
再看一組練習
public static void func(String str,char[] array){ str = "abcdef"; array[0] = 'g'; } public static void main(String[] args) { String str1 = "hello"; char[] val = {'a'}; System.out.println(str1); System.out.println(Arrays.toString(val)); func(str1,val); System.out.println("================="); System.out.println(str1); System.out.println(Arrays.toString(val)); }
請看一下,我們將String str 作為參數,改變str 的內容,以及傳入 數組 val 改變 數組元素,其打印結果是什麼?
我們看到 String str 的內容並未改變,但是數組 val 的元素卻改變瞭。
我們從內存的角度來分析。
str1 指向字符串常量區的”hello”,地址為888
val 作為數組引用,指向堆中開辟的數組空間,地址為777
str 作為函數的形參,接收str1實參的值,也就是888,此時str指向常量區的”hello“,但是在方法的內部,str = “abcde”,在字符串常量區中有開辟一塊”abcde”的內存,地址為000,最後 str 存放的地址為000.
array 作為函數的形參,接收val 實參的值,也就是777,此時array 指向堆中 開辟的數組空間,此時通過array 來改變數組元素的內容,最終 改變的也同樣是val 實參的內容.
三、字符串比較相等
如果現在有兩個int型變量,判斷其相等可以使用 == 完成。
str1 = "world"; System.out.println(str2); // 執行結果 //Hello int x = 10 ; int y = 10 ; System.out.println(x == y); // 執行結果 //true
如果說現在在String類對象上使用 == ?
代碼1
String str1 = "Hello"; String str2 = "Hello"; System.out.println(str1 == str2); // 執行結果 //true
看起來貌似沒啥問題, 再換個代碼試試, 發現情況不太妙.
代碼2
String str1 = new String("Hello"); String str2 = new String("Hello"); System.out.println(str1 == str2); // 執行結果 //false
在上面的幾個練習中,我們 用 str1 == str2 比較的是兩個字符串的引用/地址,如果比較字符串裡面的內容,我們需要用到 equals 方法。
public static void main(String[] args) { String str1 = "hello"; String str2 = new String("hello"); System.out.println(str1==str2); //比較的是引用 System.out.println(str1.equals(str2)); //比較 str1 和 str2 字符串的內容 String str3 = "hello"; System.out.println(str1.equals(str3)); //比較 str1 和 str3 字符串的內容 }
最後的打印結果
打印的結果符合字符串的內容比較。
常用的比較方式:
我們再來看一種情況,
public static void main(String[] args) { String str1 = null; String str2 = "hello"; System.out.println(str1.equals(str2)); }
這時候運行程序,就會出現以下情況:
空指針異常,因為 null. 任何方法都會出現異常。
所以一定要保證 str1 不能為null。
那麼如果我們改一下,
public static void main(String[] args) { String str1 = null; String str2 = "hello"; System.out.println(str2.equals(str1)); }
所以我們知道 equals(),括號裡可以是null,但是 點之前一定不能是 null.
public static void main(String[] args) { String str1 = "hello"; System.out.println(str1.equals("hello")); // 方式1 System.out.println("hello".equals(str1)); // 方式2 }
當我們寫代碼遇到以上的情況時,我們應該盡量選方式2,這樣保證 equals之前一定不為null,以防出現異常.
四、字符串常量池
在上面的例子中, String類的兩種實例化操作, 直接賦值和 new 一個新的 String.
(1) 直接賦值
System.out.println("Hello".equals(str)); // 執行結果 false String str1 = "hello" ; String str2 = "hello" ; String str3 = "hello" ; System.out.println(str1 == str2); // true System.out.println(str1 == str3); // true System.out.println(str2 == str3); // true
String類的設計使用瞭共享設計模式
在JVM底層實際上會自動維護一個對象池(字符串常量池)
如果現在采用瞭直接賦值的模式進行String類的對象實例化操作,那麼該實例化對象(字符串內容)將自動保存到這個對象池之中.
如果下次繼續使用直接賦值的模式聲明String類對象,此時對象池之中如若有指定內容,將直接進行引用
如若沒有,則開辟新的字符串對象而後將其保存在對象池之中以供下次使用
理解 “池” (pool)
“池” 是編程中的一種常見的, 重要的提升效率的方式, 我們會在未來的學習中遇到各種 “內存池”, “線程池”, “數據庫連接池” …然而池這樣的概念不是計算機獨有, 也是來自於生活中. 舉個栗子:現實生活中有一種女神, 稱為 “綠茶”, 在和高富帥談著對象的同時, 還可能和別的屌絲搞曖昧. 這時候這個屌絲被稱為 “備胎”. 那麼為啥要有備胎? 因為一旦和高富帥分手瞭, 就可以立刻找備胎接盤, 這樣 效率比較高.如果這個女神, 同時在和很多個屌絲搞曖昧, 那麼這些備胎就稱為 備胎池.
(2)采用構造方法
類對象使用構造方法實例化是標準做法。分析如下程序:
String str = new String("hello");
這樣的做法有兩個缺點:
1. 如果使用String構造方法就會開辟兩塊堆內存空間,並且其中一塊堆內存將成為垃圾空間(字符串常量 “hello” 也是一個匿名對象, 用瞭一次之後就不再使用瞭, 就成為垃圾空間, 會被 JVM 自動回收掉).
2. 字符串共享問題. 同一個字符串可能會被存儲多次, 比較浪費空間.
(3)intern 的使用
String str1 = "hello"; String str2 = new String("hello").intren();
從上面的由 構造方法定義字符串,我們會浪費內存空間,而這裡有一個方法 ,叫做intern(),手動入池。
那這是什麼意思呢?
這是先看一下傳入構造方法的字符串在字符串常量池中是否存在,如果有的話,就把常量池中的引用傳給當前的引用類型變量。
綜上所述,我們一般使用 直接賦值法來 創建 String 對象。
我們再來看這樣一組代碼,來畫一下他的內存結構
在第一步的代碼中,new 瞭兩個字符串”1″,在堆中創建瞭兩個對象,指向常量池中的”1″,拼接在一起,s3.interb(),s3手動入池,“11″在池中沒有,所以就把 堆中的”11″的引用 555 傳入常量池中。s4 指向池中的”11”,而這時池中已經有瞭”11″的引用,所以s4 指向的就是 s3在入池的引用。
所以結果為 true。
所以呢,我們解決瞭一個疑問
在常量池當中,可以放 字符串的字面值常量,也可以放引用。什麼時候放引用,就是類似於上面的那種情況之下,s3.intern(),s3所指向的這個對象在字符串常量池中是不存在的,那麼入池的時候就把堆中s3的引用放入。
五、理解字符串不可變
字符串是一種不可變對象. 它的內容不可改變.這是什麼意思呢?
public static void main(String[] args) { String str = "hello" ; str = str + " world" ; str += "!!!" ; System.out.println(str); }
對於這種代碼,乍一看我們以為成功的將str 每次與其他的字符串拼接,但是這樣是不可以的, str 原來指向的是”hello”,但是 在與” world”拼接之後,又會產生一個新的對象”helll world”,再次拼接一個”!!!”,那麼又會產生一個新的對象”hello world!!!”,在內存中就會產生多個對象。
我們最後需要的是”hello world!!!”,但是卻開辟瞭5塊內存空間。
如果在一個循環中拼接,那麼會開辟更多的內存空間!!
所以這樣的代碼是極為不可取的!!!
那麼如何拼接呢,具體在之後的StringBuff、StringBuilder中介紹。
六、字符、字節、字符串
(1)字符與字符串
字符串內部包含一個字符數組,String 可以和 char[] 相互轉換
1.字符數組轉字符串
public static void main(String[] args) { char[] val = {'h','e','l','l','o'}; String str = new String(val); System.out.println(val); }
此時我們 的 str 結果就是 “hello”,同時他也可以再給兩個參數.
2.將部分字符數組中的內容轉換為字符串
offset–偏移量
count– 轉換幾個
public static void main(String[] args) { char[] val = {'h','e','l','l','o'}; String str = new String(val,1,2); System.out.println(str); }
此時我們將val 中偏移1個,轉換之後的兩個數組元素為字符串
打印結果應該為 el
運行結果如下:
3.將字符串中對應索引轉換為字符
public static void main(String[] args) { String str = "hello"; char ch = str.charAt(1); System.out.println(ch); }
索引從0開始,我們輸入1,所以轉換的為字符串中的e
運行結果如下:
4.將字符串轉換為字符數組
public static void main(String[] args) { String str = "hello"; char[] val = str.toCharArray(); System.out.println(Arrays.toString(val)); }
我們用字符數組接收 str轉換後的字符。
運行結果如下:
好瞭,瞭解瞭這幾種字符與字符串的方法,我們通過幾個練習來繼續熟悉。
練習一
給定字符串一個字符串, 判斷其是否全部由數字所組成.
思路: 將字符串變為字符數組而後判斷每一位字符是否是” 0 “~”‘9′”之間的內容,如果是則為數字.
public static boolean func1(String str){ for (int i = 0; i <str.length() ; i++) { if(str.charAt(i)>'9' || str.charAt(i)<'0'){ return false; } } return true; }
(2)字節與字符串
字節常用於數據傳輸以及編碼轉換的處理之中,String 也能方便的和 byte[] 相互轉換
常用方法:
1.字節數組轉換為字符串
public static void main(String[] args) { byte[] bytes = {97,98,99,100}; String str = new String(bytes); System.out.println(str); }
運行結果: 字符串中的內容是字節數組與Ascii 碼表中對應的字符。
2.部分字節數組的內容轉換為字符串
public static void main(String[] args) { byte[] bytes = {97,98,99,100}; String str = new String(bytes,2,1); System.out.println(str); }
運行結果:
3.字符串轉換為字節數組
public static void main(String[] args) { String str = "abcd"; byte[] bytes = str.getBytes(); System.out.println(Arrays.toString(bytes)); }
運行結果:
(3) 小結
那麼何時使用 byte[], 何時使用 char[] 呢?
byte[] 是把 String 按照一個字節一個字節的方式處理, 這種適合在網絡傳輸, 數據存儲這樣的場景下使用. 更適合針對二進制數據來操作.
char[] 是吧 String 按照一個字符一個字符的方式處理, 更適合針對文本數據來操作, 尤其是包含中文的時候.
七、字符串的常見操作
(1)字符串比較
上面使用過String類提供的equals()方法,該方法本身是可以進行區分大小寫的相等判斷。除瞭這個方法之外,String類還提供有如下的比較操作.
1.區分大小寫比較
public static void main(String[] args) { String str1 = "abcd"; String str2 = "Abcd"; System.out.println(str1.equals(str2)); }
運行結果:
我們常
用的equals 方法 是區分大小寫的,這點要註意。
2.不區分大小寫的比較
public static void main(String[] args) { String str1 = "abcd"; String str2 = "Abcd"; System.out.println(str1.equalsIgnoreCase(str2)); }
運行結果:
這種不區分大小寫的比較還是很常見的,比如應用於驗證碼上,不區分大小寫。
3.比較兩個字符串的大小關系
public static void main(String[] args) { String str1 = "abcd"; String str2 = "Abcd"; System.out.println(str1.compareTo(str2)); }
運行時結果
掌握瞭字符串比較相等的方法,下來我們來做一道練習題
比較字符串是否相等
題解思路:
將word1 字符串數組的內容都在str1 追加,word2 字符串數組的內容在str2 追加,最終equals 比較str1 str2 字符串的內容,相等返回 true,不等返回 false.
註意:參數等問題要考慮全面
(2)字符串查找
從一個完整的字符串之中可以判斷指定內容是否存在,對於查找方法有如下定義:
判斷一個字符串中是否存在子字符串
我們可以先看一下 contains 方法的源碼
contains 方法的使用
public static void main(String[] args) { String str = "bcdabc"; boolean flg = str.contains("abc"); System.out.println(flg); }
運行結果:
所以可判斷在”badabc” 這個字符串中存在 這個 “abc” 的子字符串。
找到子字符串的下標
我們先來看一下一個參數的 index 方法的源碼
帶一個參數的 index 方法的使用
public static void main(String[] args) { String str = "ababcabcdabcde"; int index1 = str.indexOf("abc"); int index2 = str.indexOf("hello"); System.out.println(index1); System.out.println("============"); System.out.println(index2); }
運行結果:
兩個參數的index 方法的使用
在下面我們又看到瞭一個index 方法,這說明 默認情況下,index 是從0下標開始查找的,如果再給他一個下標參數,那麼就從指定的下標位置進行字符串查找。
使用:
public static void main(String[] args) { String str = "abcabcdabcdef"; int index1 = str.indexOf("abc"); int index2 = str.indexOf("abc",6); System.out.println(index1); System.out.println("================="); System.out.println(index2); }
運行結果:
從後往前查找到子字符串的位置
lastIndexOf 是從後向前查找 子字符串的位置
lastIndexOf 方法的使用
public static void main(String[] args) { String str = "abcabcdabcdef"; int index = str.lastIndexOf("abc"); System.out.println(index); }
運行結果:
同時 lastIndexOf 也有兩個參數的方法,從指定下標開始從後向前進行查找。
判斷是否由 參數字符串開頭的
同時也有兩個參數的方法,從指定位置判斷是否由 指定字符串開頭
判斷是否由指定字符串進行結尾的
(3)字符串替換
(1)替換所有的指定內容
replaceAll 的使用
public static void main(String[] args) { String str = "abcabcacbabc"; System.out.println(str); System.out.println("================="); String ret = str.replaceAll("ab","AB"); System.out.println(ret); }
運行結果:
成功的把所有的 “ab” 替換成為 “AB”.
(2)替換首個要替換的內容.
replaceFirst 的使用
public static void main(String[] args) { String str = "abcabcacbabc"; System.out.println(str); System.out.println("================="); String ret = str.replaceFirst("ab","AB"); System.out.println(ret); }
運行結果:
註意說明:
由於字符串是不可變對象, 替換不修改當前字符串, 而是產生一個新的字符串.
(4)字符串拆分
可以將一個完整的字符串按照指定的分隔符劃分為若幹個子字符串。
1.將字符串全部拆分
接收的類型是字符串數組類型,傳參數時,傳一個我們想要分割的符號。
split 的使用
public static void main(String[] args) { String str = "rain7 is cool"; String[] strs = str.split(" "); for (String s:strs) { System.out.println(s); } }
我們在用 split 方法時, 以 空格 為分割符,將我們的str 字符串 進行拆分
我們來看拆分的效果
2.帶兩個參數的split 方法
還是以上面的字符串為例
public static void main(String[] args) { String str = "rain7 is cool"; String[] strs = str.split(" ",2); for (String s:strs) { System.out.println(s); } }
運行結果:
我們除瞭將字符串作為參數,還將limit 設置為2,那麼拆分後的數組長度就為2,所以運行結果就如上所示。
難點:
拆分是特別常用的操作. 一定要重點掌握. 另外有些特殊字符作為分割符可能無法正確切分, 需要加上轉義字符
示例1
拆分 IP 地址
比如說我們要分割IP 地址,192.168.1.1,以 “.” 分割。
當我們運行時會發現 打印為空,這是為什麼呢?
有些符號比較特殊,必須用到轉義字符
“ \. ”才能表示一個真正的 “.” 同時"\"也需要進行轉義,那麼就又要再加一個斜杠。 “\\.”這時字符串才隻能被 “ . ”分割。 1
public static void main(String[] args) { String str = "192.168.1.1"; String[] strs = str.split("\\."); for (String s:strs) { System.out.println(s); } }
運行結果:
1. 字符”|”,”*”,”+”都得加上轉義字符,前面加上”\\”.
2. 而如果是”\”,那麼就得寫成”\\”.
3. 如果一個字符串中有多個分隔符,可以用”|”作為連字符.
連字符 “ | ” 的使用
public static void main(String[] args) { String str = "[email protected]"; String[] ret = str.split("@|\\."); for (String s:ret) { System.out.println(s); } }
運行結果:
我們來一道練習題:
代碼題解:
public static void main(String[] args) { Scanner scanner = new Scanner(System.in); while(scanner.hasNext()){ String ret =""; String str = scanner.nextLine(); String[] strs = str.split(" "); for (String s:strs) { ret += s; } System.out.println(ret); } }
運行結果:
註意:
1.註意多組輸入 2.不建議在for循環中拼接字符串,在之後講到的StringBuilder StringBuffer 之後可以知道如何拼接。
(5)字符串截取
從一個完整的字符串之中截取出部分內容。可用方法如下:
1.從指定下標截取到字符串結束
方法的使用
public static void main(String[] args) { String str = "ilikeBeijing"; String ret = str.substring(4); System.out.println(ret); }
運行結果:
2.帶有兩個參數的subString 方法,截取指定下標范圍內的字符串內容
方法的使用
public static String reverse(String s){ if(s==null){ return null; } int begun = 0; int end = s.length()-1; char[] chars = s.toCharArray(); while(begun<end){ char tmp = chars[begun] ; chars [begun] = chars [end]; chars[end] = tmp; begun++; end--; } return new String(chars); } public static void main(String[] args) { String str = "Hello World!"; String ret = reverse(str); System.out.println(ret); }
運行結果
註
意:
1.指定下標范圍 是 左閉右開的區間
2.截取後的字符串是一個新的對象
(6)其他操作方法
字符串操作還有很多其他的方法,在這裡我們隻進行簡單介紹。
(7)字符串操作練習題
1.逆置字符串
題目要求
將字符串進行整體逆置
代碼題解:
public static String reverse(String s){ if(s==null){ return null; } int begun = 0; int end = s.length()-1; char[] chars = s.toCharArray(); while(begun<end){ char tmp = chars[begun] ; chars [begun] = chars [end]; chars[end] = tmp; begun++; end--; } return new String(chars); } public static void main(String[] args) { String str = "Hello World!"; String ret = reverse(str); System.out.println(ret); }
運行結果:
成功的將字符串進行逆置
2.翻轉字符串
我們首先對題目進行一下解讀,我們要實現一個方法,給這個方法傳入 一個字符串和一個 整數 size 。將大小為 size 的左半區 翻轉到 右半區。如圖所示:
思路實現:
1.首先將size 左半區進行單獨逆置。
2.再將 size的右半區單獨逆置。
3.整體字符串進行逆置。
代碼展示:
public static String reverse(String s,int begun,int end){ if(s==null){ return null; } char[] chars = s.toCharArray(); while(begun<end){ char tmp = chars[begun] ; chars [begun] = chars [end]; chars[end] = tmp; begun++; end--; } return new String(chars); } public static String reversSentence(String str,int k){ str = reverse(str,0,k-1); str = reverse(str,k,str.length()-1); str = reverse(str,0,str.length()-1); return str; } public static void main(String[] args) { Scanner scanner = new Scanner(System.in); String str = scanner.next(); int n = scanner.nextInt(); String ret = reversSentence(str,n); System.out.println(ret); }
運行結果:
八、StringBuffer 和 StringBuilder
StringBuffer 和 StringBuilder 又是一種新的字符串類型。
通常來講String的操作比較簡單,但是由於String的不可更改特性,為瞭方便字符串的修改,提供 StringBuffer 和 StringBuilder 類。
StringBuffer 和 StringBuilder 在功能上大部分是相同的,在這裡我們著重介紹 StringBuffer.
(1)append 方法
public static void main(String[] args) { StringBuffer sb = new StringBuffer(); sb.append("a"); sb.append("b"); sb.append("c"); System.out.println(sb); }
在String中使用”+”來進行字符串連接,但是這個操作在StringBuffer類中需要更改為append()方法。
String和StringBuffer最大的區別在於:String的內容無法修改,而StringBuffer的內容可以修改。頻繁修改字符串的情況考慮使用 StingBuffer。
運行結果:
我們來看一下 StringBuffer 的 append 方法的源碼
最後返回的是 this,在字符串本身拼接字符串。同時StringBuffer 有自己重寫的 toString 方法,可以直接進行打印。
我們來看一下 以下的代碼:
public static void main(String[] args) { String str1 = "abc"; String str2 = "def"; String str3 = str1+str2; System.out.println(str3); }
我們對以上代碼進行編譯一下:
在編譯的過程中,我們發現StringBuilder.append 方法的出現;
我們將這個過程用 StringBuilder 寫一下:
public static void main(String[] args) { String str1 ="abc"; String str2 = "def"; StringBuilder sb = new StringBuilder(); sb.append(str1); sb.append(str2); String str3 = sb.toString(); System.out.println(str3); }
說明:
String 的“+” 拼接,會被底層優化為一個 StringBuilder ,拼接的時候會用到 append 方法
(2)註意
註意: String和StringBuffer類不能直接轉換。如果要想互相轉換,可以采用如下原則:
String變為StringBuffer:利用StringBuffer的構造方法或append()方法 StringBuffer變為String:調用toString()方法。
除瞭append()方法外,StringBuffer也有一些String類沒有的方法:
字符串反轉:
public synchronized StringBuffer reverse();
(3)區別
String 和 StringBuilder 及 StringBuffer 的區別
String 進行拼接時,底層會被優化為StringBuilder
String的拼接會產生臨時對象,但是後兩者每次都隻是返回當前對象的引用。
String的內容不可修改,StringBuffer與StringBuilder的內容可以修改.
StringBuilder 和 StringBuffer 的區別
我們來看一下這兩個類的 append 方法
所以 StringBuffer 和 StringBuilder 的區別主要體現在線程安全上 。
1.StringBuffer與StringBuilder大部分功能是相似的
2.StringBuffer采用同步處理,屬於線程安全操作;而StringBuilder未采用同步處理,屬於線程不安全操作
九.總結
字符串操作是我們以後工作中非常常用的操作. 使用起來都非常簡單方便, 我們一定要使用熟練.
好瞭今天的知識就分享到這裡,希望大傢多多關註WalkonNet的其他內容!
推薦閱讀:
- 詳解Java中String類的各種用法
- 詳解Java中String,StringBuffer和StringBuilder的使用
- Java-String類最全匯總(上篇)
- JAVA多種方法實現字符串反轉
- Java面試題沖刺第一天–基礎篇1