java新手入門——String類詳解
一、創(chuàng)建字符串
創(chuàng)建字符串的方式有很多種,當是常見的一般就三種
1. 直接賦值(常用)
String str = "hello world !";
2. new String
String str = new String("hello world !");
3. 字符數(shù)組轉String
char[] array = {'a', 'b', 'c'}; String str = new String(array);
但以后一般都是用第一種創(chuàng)建方式
注意事項:
"hello" 這樣的字符串字面值常量, 類型也是 String.String 也屬于引用類型. String str ="Hello"
4.String類中兩種對象實例化的區(qū)別
直接賦值:只會開辟一塊堆內存空間,并且該字符串對象可以自動保存在對象池中以供下次使用。構造方法:會開辟兩塊堆內存空間,不會自動保存在對象池中,可以使用intern()方法手工入池。
二、字符串比較相等
1.直接比較字符串
我們知道兩個整形可以直接用 == 比較相等,那如果用 == 比較String類相等會發(fā)生什么呢?
代碼:
public static void main(String[] args) { String str1 = "hello"; String str2 = new String("hello"); System.out.println(str1 == str2); String str3 = "he"+"llo";//編譯的時候這個地方相當于 String str3 = "hello"; System.out.println(str1 == str3); String str4 = "he"; String str5 = "llo"; String str6 = str4+str5; System.out.println(str1 == str6); String str7 = "he"+new String("llo"); System.out.println(str1 == str7); }
運行結果:
我們知道String屬于引用類型,所以str存的是地址。那么比較的就是地址。
只要new了就會在堆上開辟內存,所以不相等。直接說可能有點抽象,下面簡單通過內存圖來判斷字符串是否相等。
2.字符串在內存中的存儲
接上面的例子我們來看一下字符串在內存中的存儲來判斷相等
注意:
1.只要new了就會在堆上開辟內存,那么必定不會相等。
2.相同的字符串在字符串常量池里只會存一份。
3.字符串常量池
String類的設計使用了共享設計模式
在JVM底層實際上會自動維護一個對象池(字符串常量池)
如果現(xiàn)在采用了直接賦值的模式進行String類的對象實例化操作,那么該實例化對象(字符串內容)將自動保存到這個對象池之中.如果下次繼續(xù)使用直接賦值的模式聲明String類對象,此時對象池之中如若有指定內容,將直接進行引用如若沒有,則開辟新的字符串對象而后將其保存在對象池之中以供下次使用
4.字符串比較equals
Java 中要想比較字符串是否相等的話,就需要使用String提供的equals方法
String str1 = new String("Hello"); String str2 = new String("Hello"); System.out.println(str1.equals(str2)); // System.out.println(str2.equals(str1)); // 或者這樣寫也行 // 執(zhí)行結果 true
equals使用的注意事項:
現(xiàn)在需要比較 str 和 “Hello” 兩個字符串是否相等, 我們該如何來寫呢?
String str = new String("Hello"); // 方式一 System.out.println(str.equals("Hello")); // 方式二 System.out.println("Hello".equals(str));
在上面的代碼中, 哪種方式更好呢?
更推薦使用 “方式二”. 一旦 str 是 null, 方式一的代碼會拋出異常, 而方式二不會
String str = null; // 方式一 System.out.println(str.equals("Hello")); // 執(zhí)行結果 拋出 java.lang.NullPointerException 異 常 // 方式二 System.out.println("Hello".equals(str)); // 執(zhí)行結果 false
注意事項: “Hello” 這樣的字面值常量, 本質上也是一個 String 對象, 完全可以使用 equals 等 String 對象的方法
5.理解字符串的不可變
字符串是一種不可變對象. 它的內容不可改變.
String 類的內部實現(xiàn)也是基于 char[] 來實現(xiàn)的, 但是 String 類并沒有提供 set 方法之類的來修改內部的字符數(shù)組.
代碼示例:
String str = "hello" ; str = str + " world" ; str += "!!!" ; System.out.println(str); // 執(zhí)行結果 hello world!!!
形如 += 這樣的操作, 表面上好像是修改了字符串, 其實不是. 內存變化如下:
+= 之后 str 打印的結果卻是變了, 但是不是 String 對象本身發(fā)生改變, 而是 str 引用到了其他的對象.
回顧引用:
引用相當于一個指針, 里面存的內容是一個地址. 我們要區(qū)分清楚當前修改到底是修改了地址對應內存的內容發(fā)生改變了, 還是引用中存的地址改變了.
6.手動入池 intern()
我們知道字符串常量是存在字符串常量池當中的,而new的是在堆上開辟內存。
而String的 intern()方法可以把String對象手動入到字符串常量池中
// 該字符串常量并沒有保存在對象池之中 String str1 = "hello" ; String str2 = new String("hello") ; System.out.println(str1 == str2); // 執(zhí)行結果 false String str1 = "hello" ; String str2 = new String("hello").intern() ; System.out.println(str1 == str2); // 執(zhí)行結果 true
如果str2沒有
intern()方法的時候,它是指向堆上的new的String對象的,而使用了intern()方法后,就會直接指向字符串常量池的
”hello“,如果調用intern()方法的時候字符串常量池中沒有 "hello"這個字符串,則會把它放入池中。
三、字符字節(jié)與字符串
1.字符轉字符串
代碼示例 :
char[] array = {'h','e','l','l','o'}; String str1 = new String(array); String str2 = new String(array,1,2); System.out.println(str1); System.out.println(str2); //運行結果 //hello //el
注意:第一個參數(shù)是偏移量,偏移量是從0開始的,第二個是參數(shù)是往后從偏移量開始的位置走幾步。且下標不能越界!
2.字符串轉字符
指定獲取字符串里的某一個字符:
String str = "hello"; char ch = str.charAt(4); System.out.println(ch); //運行結果 //o
字符串轉字符數(shù)組代碼示例:
String str = "hello"; char[] array = str.toCharArray(); for (char s : array) { System.out.print(s+" "); }
運行結果
3.字節(jié)與字符串
用法和上面的類似
代碼示例:
byte[] bytes = {97,98,99,100}; String str = new String(bytes,1,3); System.out.println(str); String str2 = "abcd"; byte[] bytes1 = str2.getBytes(); System.out.println(Arrays.toString(bytes1));
運行結果
4.編碼方式
運行結果 :
常見的編碼方式有 utf-8 和 GBK ,不過編碼方式一般只對漢字有影響。
5.小結
那么何時使用 byte[], 何時使用 char[] 呢?
byte[] 是把 String 按照一個字節(jié)一個字節(jié)的方式處理, 這種適合在網(wǎng)絡傳輸, 數(shù)據(jù)存儲這樣的場景下使用. 更適合 針對二進制數(shù)據(jù)來操作.char[] 是吧 String 按照一個字符一個字符的方式處理, 更適合針對文本數(shù)據(jù)來操作, 尤其是包含中文的時候
回憶概念: 文本數(shù)據(jù) vs 二進制數(shù)據(jù)
一個簡單粗暴的區(qū)分方式就是用記事本打開能不能看懂里面的內容.
如果看的懂, 就是文本數(shù)據(jù)(例如 .java 文件), 如果看不懂, 就是二進制數(shù)據(jù)(例如 .class 文件).
四、字符串常見操作
1.字符串比較
上面使用過String類提供的equals()方法,該方法本身是可以進行區(qū)分大小寫的相等判斷。除了這個方法之外,String類還提供有如下的比較操作:
代碼示例:
String str = "abcd"; System.out.println("abcd".equals(str)); System.out.println("Abcd".equalsIgnoreCase(str));//不區(qū)分大小寫 //運行結果 //true //true
**compareTo()**方法前面博客有詳細介紹,這里就不多說了。可以看看—>compareTo方法
在String類中compareTo()方法是一個非常重要的方法,該方法返回一個整型,該數(shù)據(jù)會根據(jù)大小關系返回三類內
容:
相等:返回0.小于:返回內容小于0.大于:返回內容大于0。
2.字符串查找
從一個完整的字符串之中可以判斷指定內容是否存在,對于查找方法有如下定義:
代碼示例 :
String str = "abcdefg"; 找子串 System.out.println(str.contains("efg")); 從頭開始找指定字符串,找到返回下標,找不到返回 -1 System.out.println(str.indexOf("d")); 指定位置開始找指定字符串 System.out.println(str.indexOf("d",2)); 從后向前找指定字符串 System.out.println(str.lastIndexOf("fg")); 判斷是否以指定字符串開頭 System.out.println(str.startsWith("abc")); 從指定位置判斷是否以該字符串開頭 System.out.println(str.startsWith("de", 3));
用法都是通過 String類點出方法名,注意就收放回值就好了。
3.字符串替換
使用一個指定的新的字符串替換掉已有的字符串數(shù)據(jù),可用的方法如下:
代碼示例:
String str = "helloworld" ; System.out.println(str.replaceAll("l", "!")); System.out.println(str.replaceFirst("l", "!"));
運行結果
注意如果替換的是特殊字符,則需要使用轉義字符。
代碼示例:
String str1 = "192\\168\\1\\1" ; System.out.println(str1.replaceAll("\\\\", "+")); String str2 = "www.baidu.com"; System.out.println(str2.replaceAll("\\.", "%20"));
運行結果
注意事項: 由于字符串是不可變對象, 替換不修改當前字符串, 而是產(chǎn)生一個新的字符串.
4.字符串拆分
可以將一個完整的字符串按照指定的分隔符劃分為若干個子字符串。
代碼示例:
String str1 = "192.168.1.1" ; String[] array = str1.split("\\."); for (String s : array) { System.out.println(s); }
運行結果
注意:下面的的這段代碼是不能被拆分的
String str1 = "192\168\1\1" ; String[] array = str1.split("\\\\"); for (String s : array) { System.out.println(s); }
運行結果:
因為 \ 后面跟兩到三個數(shù)字會被轉義成一個八進制數(shù)字。
注意事項:
字符"|","*","+“都得加上轉義字符,前面加上”".而如果是"",那么就得寫成"\".如果一個字符串中有多個分隔符,可以用"|"作為連字符.
多次拆分代碼示例:
String str = "name=zhangsan&age=18"; String[] result = str.split("&|=") ; for (String s : result) { System.out.println(s); }
運行結果:
5.字符串截取
從一個完整的字符串之中截取出部分內容。
代碼示例:
String str = "abcdef"; System.out.println(str.substring(3)); System.out.println(str.substring(2, 4));//左閉右開 運行結果 def cd
注意事項:
索引從0開始注意前閉后開區(qū)間的寫法, substring(0, 5) 表示包含 0 號下標的字符, 不包含 5 號下標 6.其他操作方法
這些都比較簡單,用的時候查就好了。
五、StringBuffer 和 StringBuilder
首先來回顧下String類的特點:
任何的字符串常量都是String對象,而且String的常量一旦聲明不可改變,如果改變對象內容,改變的是其引用的指向而已。
通常來講String的操作比較簡單,但是由于String的不可更改特性,為了方便字符串的修改,提供StringBuffer和StringBuilder類。
StringBuffer 和 StringBuilder 大部分功能是相同的,只有較小的區(qū)別。
1.append()方法
在String中使用"+"來進行字符串連接,但是這個操作在StringBuffer類中需要更改為append()方法:
public synchronized StringBuffer append(各種數(shù)據(jù)類型 b)
代碼示例:
StringBuffer str1 = new StringBuffer("abcd"); StringBuilder str2 = new StringBuilder("abcd"); str1.append(123); str2.append("hij"); System.out.println(str1); System.out.println(str2);
運行結果:
StringBuffer 和 StringBuilder 大部分功能是相同的,它們的append()方法的方法可以拼接各種數(shù)據(jù)類型。
注意:
String和StringBuffer最大的區(qū)別在于:String的內容無法修改,而StringBuffer的內容可以修改。頻繁修改字符串的情況考慮使用StingBuffer。
因為 String通過+拼接會產(chǎn)生臨時對象,而 StringBuffer 和 StringBuilder 只會在當前對象上進行拼接。
2.字符串反轉 reverse( )
代碼示例:
StringBuffer str1 = new StringBuffer("abcdefg"); StringBuilder str2 = new StringBuilder("654321"); System.out.println(str1.reverse()); System.out.println(str2.reverse());
運行結果:
3.刪除指定范圍的數(shù)據(jù) delete( )
代碼示例:
StringBuffer str1 = new StringBuffer("abcdefg"); StringBuilder str2 = new StringBuilder("654321"); System.out.println(str1.delete(2, 5)); System.out.println(str2.delete(4, 6));
運行結果:
4.插入數(shù)據(jù) insert( )
代碼示例:
StringBuffer str1 = new StringBuffer("abcdefg"); StringBuilder str2 = new StringBuilder("654321"); str1.insert(0,"你好嗎").delete(0,1); System.out.println(str1); System.out.println(str2.delete(0, 3).insert(0, "你好世界"));
運行結果:
5.StringBuffer 和 StringBuilder的區(qū)別
來看一下 StringBuffer 和 StringBuilder 的 append 方法
1.String的拼接會產(chǎn)生臨時對象,但是后兩者每次都只是返回當前對象的引用
2.String的加號拼接,會被底層優(yōu)化為一個StringBuilder
3.StringBuilder和String,一般如果不涉及到多線程的情況下才會使用
4.StringBuffer(創(chuàng)建鎖、銷毀鎖、都是耗費資源的)
總結
1.如果以后涉及到字符串的拼接,一定要使用 StringBuffer 和 StringBuilder 的 append()方法
2.注意String類中兩種對象實例化的區(qū)別
3.相同的字符串在字符串常量池中只會存一份
一、創(chuàng)建字符串
創(chuàng)建字符串的方式有很多種,當是常見的一般就三種
1. 直接賦值(常用)
String str = "hello world !";
2. new String
String str = new String("hello world !");
3. 字符數(shù)組轉String
char[] array = {'a', 'b', 'c'}; String str = new String(array);
但以后一般都是用第一種創(chuàng)建方式
注意事項:
"hello" 這樣的字符串字面值常量, 類型也是 String.String 也屬于引用類型. String str ="Hello"
4.String類中兩種對象實例化的區(qū)別
直接賦值:只會開辟一塊堆內存空間,并且該字符串對象可以自動保存在對象池中以供下次使用。構造方法:會開辟兩塊堆內存空間,不會自動保存在對象池中,可以使用intern()方法手工入池。
二、字符串比較相等
1.直接比較字符串
我們知道兩個整形可以直接用 == 比較相等,那如果用 == 比較String類相等會發(fā)生什么呢?
代碼:
public static void main(String[] args) { String str1 = "hello"; String str2 = new String("hello"); System.out.println(str1 == str2); String str3 = "he"+"llo";//編譯的時候這個地方相當于 String str3 = "hello"; System.out.println(str1 == str3); String str4 = "he"; String str5 = "llo"; String str6 = str4+str5; System.out.println(str1 == str6); String str7 = "he"+new String("llo"); System.out.println(str1 == str7); }
運行結果:
我們知道String屬于引用類型,所以str存的是地址。那么比較的就是地址。
只要new了就會在堆上開辟內存,所以不相等。直接說可能有點抽象,下面簡單通過內存圖來判斷字符串是否相等。
2.字符串在內存中的存儲
接上面的例子我們來看一下字符串在內存中的存儲來判斷相等
注意:
1.只要new了就會在堆上開辟內存,那么必定不會相等。
2.相同的字符串在字符串常量池里只會存一份。
3.字符串常量池
String類的設計使用了共享設計模式
在JVM底層實際上會自動維護一個對象池(字符串常量池)
如果現(xiàn)在采用了直接賦值的模式進行String類的對象實例化操作,那么該實例化對象(字符串內容)將自動保存到這個對象池之中.如果下次繼續(xù)使用直接賦值的模式聲明String類對象,此時對象池之中如若有指定內容,將直接進行引用如若沒有,則開辟新的字符串對象而后將其保存在對象池之中以供下次使用
4.字符串比較equals
Java 中要想比較字符串是否相等的話,就需要使用String提供的equals方法
String str1 = new String("Hello"); String str2 = new String("Hello"); System.out.println(str1.equals(str2)); // System.out.println(str2.equals(str1)); // 或者這樣寫也行 // 執(zhí)行結果 true
equals使用的注意事項:
現(xiàn)在需要比較 str 和 “Hello” 兩個字符串是否相等, 我們該如何來寫呢?
String str = new String("Hello"); // 方式一 System.out.println(str.equals("Hello")); // 方式二 System.out.println("Hello".equals(str));
在上面的代碼中, 哪種方式更好呢?
更推薦使用 “方式二”. 一旦 str 是 null, 方式一的代碼會拋出異常, 而方式二不會
String str = null; // 方式一 System.out.println(str.equals("Hello")); // 執(zhí)行結果 拋出 java.lang.NullPointerException 異 常 // 方式二 System.out.println("Hello".equals(str)); // 執(zhí)行結果 false
注意事項: “Hello” 這樣的字面值常量, 本質上也是一個 String 對象, 完全可以使用 equals 等 String 對象的方法
5.理解字符串的不可變
字符串是一種不可變對象. 它的內容不可改變.
String 類的內部實現(xiàn)也是基于 char[] 來實現(xiàn)的, 但是 String 類并沒有提供 set 方法之類的來修改內部的字符數(shù)組.
代碼示例:
String str = "hello" ; str = str + " world" ; str += "!!!" ; System.out.println(str); // 執(zhí)行結果 hello world!!!
形如 += 這樣的操作, 表面上好像是修改了字符串, 其實不是. 內存變化如下:
+= 之后 str 打印的結果卻是變了, 但是不是 String 對象本身發(fā)生改變, 而是 str 引用到了其他的對象.
回顧引用:
引用相當于一個指針, 里面存的內容是一個地址. 我們要區(qū)分清楚當前修改到底是修改了地址對應內存的內容發(fā)生改變了, 還是引用中存的地址改變了.
6.手動入池 intern()
我們知道字符串常量是存在字符串常量池當中的,而new的是在堆上開辟內存。
而String的 intern()方法可以把String對象手動入到字符串常量池中
// 該字符串常量并沒有保存在對象池之中 String str1 = "hello" ; String str2 = new String("hello") ; System.out.println(str1 == str2); // 執(zhí)行結果 false String str1 = "hello" ; String str2 = new String("hello").intern() ; System.out.println(str1 == str2); // 執(zhí)行結果 true
如果str2沒有
intern()方法的時候,它是指向堆上的new的String對象的,而使用了intern()方法后,就會直接指向字符串常量池的
”hello“,如果調用intern()方法的時候字符串常量池中沒有 "hello"這個字符串,則會把它放入池中。
三、字符字節(jié)與字符串
1.字符轉字符串
代碼示例 :
char[] array = {'h','e','l','l','o'}; String str1 = new String(array); String str2 = new String(array,1,2); System.out.println(str1); System.out.println(str2); //運行結果 //hello //el
注意:第一個參數(shù)是偏移量,偏移量是從0開始的,第二個是參數(shù)是往后從偏移量開始的位置走幾步。且下標不能越界!
2.字符串轉字符
指定獲取字符串里的某一個字符:
String str = "hello"; char ch = str.charAt(4); System.out.println(ch); //運行結果 //o
字符串轉字符數(shù)組代碼示例:
String str = "hello"; char[] array = str.toCharArray(); for (char s : array) { System.out.print(s+" "); }
運行結果
3.字節(jié)與字符串
用法和上面的類似
代碼示例:
byte[] bytes = {97,98,99,100}; String str = new String(bytes,1,3); System.out.println(str); String str2 = "abcd"; byte[] bytes1 = str2.getBytes(); System.out.println(Arrays.toString(bytes1));
運行結果
4.編碼方式
運行結果 :
常見的編碼方式有 utf-8 和 GBK ,不過編碼方式一般只對漢字有影響。
5.小結
那么何時使用 byte[], 何時使用 char[] 呢?
byte[] 是把 String 按照一個字節(jié)一個字節(jié)的方式處理, 這種適合在網(wǎng)絡傳輸, 數(shù)據(jù)存儲這樣的場景下使用. 更適合 針對二進制數(shù)據(jù)來操作.char[] 是吧 String 按照一個字符一個字符的方式處理, 更適合針對文本數(shù)據(jù)來操作, 尤其是包含中文的時候
回憶概念: 文本數(shù)據(jù) vs 二進制數(shù)據(jù)
一個簡單粗暴的區(qū)分方式就是用記事本打開能不能看懂里面的內容.
如果看的懂, 就是文本數(shù)據(jù)(例如 .java 文件), 如果看不懂, 就是二進制數(shù)據(jù)(例如 .class 文件).
四、字符串常見操作
1.字符串比較
上面使用過String類提供的equals()方法,該方法本身是可以進行區(qū)分大小寫的相等判斷。除了這個方法之外,String類還提供有如下的比較操作:
代碼示例:
String str = "abcd"; System.out.println("abcd".equals(str)); System.out.println("Abcd".equalsIgnoreCase(str));//不區(qū)分大小寫 //運行結果 //true //true
**compareTo()**方法前面博客有詳細介紹,這里就不多說了。可以看看—>compareTo方法
在String類中compareTo()方法是一個非常重要的方法,該方法返回一個整型,該數(shù)據(jù)會根據(jù)大小關系返回三類內
容:
相等:返回0.小于:返回內容小于0.大于:返回內容大于0。
2.字符串查找
從一個完整的字符串之中可以判斷指定內容是否存在,對于查找方法有如下定義:
代碼示例 :
String str = "abcdefg"; 找子串 System.out.println(str.contains("efg")); 從頭開始找指定字符串,找到返回下標,找不到返回 -1 System.out.println(str.indexOf("d")); 指定位置開始找指定字符串 System.out.println(str.indexOf("d",2)); 從后向前找指定字符串 System.out.println(str.lastIndexOf("fg")); 判斷是否以指定字符串開頭 System.out.println(str.startsWith("abc")); 從指定位置判斷是否以該字符串開頭 System.out.println(str.startsWith("de", 3));
用法都是通過 String類點出方法名,注意就收放回值就好了。
3.字符串替換
使用一個指定的新的字符串替換掉已有的字符串數(shù)據(jù),可用的方法如下:
代碼示例:
String str = "helloworld" ; System.out.println(str.replaceAll("l", "!")); System.out.println(str.replaceFirst("l", "!"));
運行結果
注意如果替換的是特殊字符,則需要使用轉義字符。
代碼示例:
String str1 = "192\\168\\1\\1" ; System.out.println(str1.replaceAll("\\\\", "+")); String str2 = "www.baidu.com"; System.out.println(str2.replaceAll("\\.", "%20"));
運行結果
注意事項: 由于字符串是不可變對象, 替換不修改當前字符串, 而是產(chǎn)生一個新的字符串.
4.字符串拆分
可以將一個完整的字符串按照指定的分隔符劃分為若干個子字符串。
代碼示例:
String str1 = "192.168.1.1" ; String[] array = str1.split("\\."); for (String s : array) { System.out.println(s); }
運行結果
注意:下面的的這段代碼是不能被拆分的
String str1 = "192\168\1\1" ; String[] array = str1.split("\\\\"); for (String s : array) { System.out.println(s); }
運行結果:
因為 \ 后面跟兩到三個數(shù)字會被轉義成一個八進制數(shù)字。
注意事項:
字符"|","*","+“都得加上轉義字符,前面加上”".而如果是"",那么就得寫成"\".如果一個字符串中有多個分隔符,可以用"|"作為連字符.
多次拆分代碼示例:
String str = "name=zhangsan&age=18"; String[] result = str.split("&|=") ; for (String s : result) { System.out.println(s); }
運行結果:
5.字符串截取
從一個完整的字符串之中截取出部分內容。
代碼示例:
String str = "abcdef"; System.out.println(str.substring(3)); System.out.println(str.substring(2, 4));//左閉右開 運行結果 def cd
注意事項:
索引從0開始注意前閉后開區(qū)間的寫法, substring(0, 5) 表示包含 0 號下標的字符, 不包含 5 號下標 6.其他操作方法
這些都比較簡單,用的時候查就好了。
五、StringBuffer 和 StringBuilder
首先來回顧下String類的特點:
任何的字符串常量都是String對象,而且String的常量一旦聲明不可改變,如果改變對象內容,改變的是其引用的指向而已。
通常來講String的操作比較簡單,但是由于String的不可更改特性,為了方便字符串的修改,提供StringBuffer和StringBuilder類。
StringBuffer 和 StringBuilder 大部分功能是相同的,只有較小的區(qū)別。
1.append()方法
在String中使用"+"來進行字符串連接,但是這個操作在StringBuffer類中需要更改為append()方法:
public synchronized StringBuffer append(各種數(shù)據(jù)類型 b)
代碼示例:
StringBuffer str1 = new StringBuffer("abcd"); StringBuilder str2 = new StringBuilder("abcd"); str1.append(123); str2.append("hij"); System.out.println(str1); System.out.println(str2);
運行結果:
StringBuffer 和 StringBuilder 大部分功能是相同的,它們的append()方法的方法可以拼接各種數(shù)據(jù)類型。
注意:
String和StringBuffer最大的區(qū)別在于:String的內容無法修改,而StringBuffer的內容可以修改。頻繁修改字符串的情況考慮使用StingBuffer。
因為 String通過+拼接會產(chǎn)生臨時對象,而 StringBuffer 和 StringBuilder 只會在當前對象上進行拼接。
2.字符串反轉 reverse( )
代碼示例:
StringBuffer str1 = new StringBuffer("abcdefg"); StringBuilder str2 = new StringBuilder("654321"); System.out.println(str1.reverse()); System.out.println(str2.reverse());
運行結果:
3.刪除指定范圍的數(shù)據(jù) delete( )
代碼示例:
StringBuffer str1 = new StringBuffer("abcdefg"); StringBuilder str2 = new StringBuilder("654321"); System.out.println(str1.delete(2, 5)); System.out.println(str2.delete(4, 6));
運行結果:
4.插入數(shù)據(jù) insert( )
代碼示例:
StringBuffer str1 = new StringBuffer("abcdefg"); StringBuilder str2 = new StringBuilder("654321"); str1.insert(0,"你好嗎").delete(0,1); System.out.println(str1); System.out.println(str2.delete(0, 3).insert(0, "你好世界"));
運行結果:
5.StringBuffer 和 StringBuilder的區(qū)別
來看一下 StringBuffer 和 StringBuilder 的 append 方法
1.String的拼接會產(chǎn)生臨時對象,但是后兩者每次都只是返回當前對象的引用
2.String的加號拼接,會被底層優(yōu)化為一個StringBuilder
3.StringBuilder和String,一般如果不涉及到多線程的情況下才會使用
4.StringBuffer(創(chuàng)建鎖、銷毀鎖、都是耗費資源的)
六、總結
1.如果以后涉及到字符串的拼接,一定要使用 StringBuffer 和 StringBuilder 的 append()方法
2.注意String類中兩種對象實例化的區(qū)別
3.相同的字符串在字符串常量池中只會存一份
希望大家可以多多關注腳本之家的其他文章!
一、創(chuàng)建字符串
創(chuàng)建字符串的方式有很多種,當是常見的一般就三種
1. 直接賦值(常用)
String str = "hello world !";
2. new String
String str = new String("hello world !");
3. 字符數(shù)組轉String
char[] array = {'a', 'b', 'c'}; String str = new String(array);
但以后一般都是用第一種創(chuàng)建方式
注意事項:
"hello" 這樣的字符串字面值常量, 類型也是 String.String 也屬于引用類型. String str ="Hello"
4.String類中兩種對象實例化的區(qū)別
直接賦值:只會開辟一塊堆內存空間,并且該字符串對象可以自動保存在對象池中以供下次使用。構造方法:會開辟兩塊堆內存空間,不會自動保存在對象池中,可以使用intern()方法手工入池。
二、字符串比較相等
1.直接比較字符串
我們知道兩個整形可以直接用 == 比較相等,那如果用 == 比較String類相等會發(fā)生什么呢?
代碼:
public static void main(String[] args) { String str1 = "hello"; String str2 = new String("hello"); System.out.println(str1 == str2); String str3 = "he"+"llo";//編譯的時候這個地方相當于 String str3 = "hello"; System.out.println(str1 == str3); String str4 = "he"; String str5 = "llo"; String str6 = str4+str5; System.out.println(str1 == str6); String str7 = "he"+new String("llo"); System.out.println(str1 == str7); }
運行結果:
我們知道String屬于引用類型,所以str存的是地址。那么比較的就是地址。
只要new了就會在堆上開辟內存,所以不相等。直接說可能有點抽象,下面簡單通過內存圖來判斷字符串是否相等。
2.字符串在內存中的存儲
接上面的例子我們來看一下字符串在內存中的存儲來判斷相等
注意:
1.只要new了就會在堆上開辟內存,那么必定不會相等。
2.相同的字符串在字符串常量池里只會存一份。
3.字符串常量池
String類的設計使用了共享設計模式
在JVM底層實際上會自動維護一個對象池(字符串常量池)
如果現(xiàn)在采用了直接賦值的模式進行String類的對象實例化操作,那么該實例化對象(字符串內容)將自動保存到這個對象池之中.如果下次繼續(xù)使用直接賦值的模式聲明String類對象,此時對象池之中如若有指定內容,將直接進行引用如若沒有,則開辟新的字符串對象而后將其保存在對象池之中以供下次使用
4.字符串比較equals
Java 中要想比較字符串是否相等的話,就需要使用String提供的equals方法
String str1 = new String("Hello"); String str2 = new String("Hello"); System.out.println(str1.equals(str2)); // System.out.println(str2.equals(str1)); // 或者這樣寫也行 // 執(zhí)行結果 true
equals使用的注意事項:
現(xiàn)在需要比較 str 和 “Hello” 兩個字符串是否相等, 我們該如何來寫呢?
String str = new String("Hello"); // 方式一 System.out.println(str.equals("Hello")); // 方式二 System.out.println("Hello".equals(str));
在上面的代碼中, 哪種方式更好呢?
更推薦使用 “方式二”. 一旦 str 是 null, 方式一的代碼會拋出異常, 而方式二不會
String str = null; // 方式一 System.out.println(str.equals("Hello")); // 執(zhí)行結果 拋出 java.lang.NullPointerException 異 常 // 方式二 System.out.println("Hello".equals(str)); // 執(zhí)行結果 false
注意事項: “Hello” 這樣的字面值常量, 本質上也是一個 String 對象, 完全可以使用 equals 等 String 對象的方法
5.理解字符串的不可變
字符串是一種不可變對象. 它的內容不可改變.
String 類的內部實現(xiàn)也是基于 char[] 來實現(xiàn)的, 但是 String 類并沒有提供 set 方法之類的來修改內部的字符數(shù)組.
代碼示例:
String str = "hello" ; str = str + " world" ; str += "!!!" ; System.out.println(str); // 執(zhí)行結果 hello world!!!
形如 += 這樣的操作, 表面上好像是修改了字符串, 其實不是. 內存變化如下:
+= 之后 str 打印的結果卻是變了, 但是不是 String 對象本身發(fā)生改變, 而是 str 引用到了其他的對象.
回顧引用:
引用相當于一個指針, 里面存的內容是一個地址. 我們要區(qū)分清楚當前修改到底是修改了地址對應內存的內容發(fā)生改變了, 還是引用中存的地址改變了.
6.手動入池 intern()
我們知道字符串常量是存在字符串常量池當中的,而new的是在堆上開辟內存。
而String的 intern()方法可以把String對象手動入到字符串常量池中
// 該字符串常量并沒有保存在對象池之中 String str1 = "hello" ; String str2 = new String("hello") ; System.out.println(str1 == str2); // 執(zhí)行結果 false String str1 = "hello" ; String str2 = new String("hello").intern() ; System.out.println(str1 == str2); // 執(zhí)行結果 true
如果str2沒有
intern()方法的時候,它是指向堆上的new的String對象的,而使用了intern()方法后,就會直接指向字符串常量池的
”hello“,如果調用intern()方法的時候字符串常量池中沒有 "hello"這個字符串,則會把它放入池中。
三、字符字節(jié)與字符串
1.字符轉字符串
代碼示例 :
char[] array = {'h','e','l','l','o'}; String str1 = new String(array); String str2 = new String(array,1,2); System.out.println(str1); System.out.println(str2); //運行結果 //hello //el
注意:第一個參數(shù)是偏移量,偏移量是從0開始的,第二個是參數(shù)是往后從偏移量開始的位置走幾步。且下標不能越界!
2.字符串轉字符
指定獲取字符串里的某一個字符:
String str = "hello"; char ch = str.charAt(4); System.out.println(ch); //運行結果 //o
字符串轉字符數(shù)組代碼示例:
String str = "hello"; char[] array = str.toCharArray(); for (char s : array) { System.out.print(s+" "); }
運行結果
3.字節(jié)與字符串
用法和上面的類似
代碼示例:
byte[] bytes = {97,98,99,100}; String str = new String(bytes,1,3); System.out.println(str); String str2 = "abcd"; byte[] bytes1 = str2.getBytes(); System.out.println(Arrays.toString(bytes1));
運行結果
4.編碼方式
運行結果 :
常見的編碼方式有 utf-8 和 GBK ,不過編碼方式一般只對漢字有影響。
5.小結
那么何時使用 byte[], 何時使用 char[] 呢?
byte[] 是把 String 按照一個字節(jié)一個字節(jié)的方式處理, 這種適合在網(wǎng)絡傳輸, 數(shù)據(jù)存儲這樣的場景下使用. 更適合 針對二進制數(shù)據(jù)來操作.char[] 是吧 String 按照一個字符一個字符的方式處理, 更適合針對文本數(shù)據(jù)來操作, 尤其是包含中文的時候
回憶概念: 文本數(shù)據(jù) vs 二進制數(shù)據(jù)
一個簡單粗暴的區(qū)分方式就是用記事本打開能不能看懂里面的內容.
如果看的懂, 就是文本數(shù)據(jù)(例如 .java 文件), 如果看不懂, 就是二進制數(shù)據(jù)(例如 .class 文件).
四、字符串常見操作
1.字符串比較
上面使用過String類提供的equals()方法,該方法本身是可以進行區(qū)分大小寫的相等判斷。除了這個方法之外,String類還提供有如下的比較操作:
代碼示例:
String str = "abcd"; System.out.println("abcd".equals(str)); System.out.println("Abcd".equalsIgnoreCase(str));//不區(qū)分大小寫 //運行結果 //true //true
**compareTo()**方法前面博客有詳細介紹,這里就不多說了??梢钥纯础?gt;compareTo方法
在String類中compareTo()方法是一個非常重要的方法,該方法返回一個整型,該數(shù)據(jù)會根據(jù)大小關系返回三類內
容:
相等:返回0.小于:返回內容小于0.大于:返回內容大于0。
2.字符串查找
從一個完整的字符串之中可以判斷指定內容是否存在,對于查找方法有如下定義:
代碼示例 :
String str = "abcdefg"; 找子串 System.out.println(str.contains("efg")); 從頭開始找指定字符串,找到返回下標,找不到返回 -1 System.out.println(str.indexOf("d")); 指定位置開始找指定字符串 System.out.println(str.indexOf("d",2)); 從后向前找指定字符串 System.out.println(str.lastIndexOf("fg")); 判斷是否以指定字符串開頭 System.out.println(str.startsWith("abc")); 從指定位置判斷是否以該字符串開頭 System.out.println(str.startsWith("de", 3));
用法都是通過 String類點出方法名,注意就收放回值就好了。
3.字符串替換
使用一個指定的新的字符串替換掉已有的字符串數(shù)據(jù),可用的方法如下:
代碼示例:
String str = "helloworld" ; System.out.println(str.replaceAll("l", "!")); System.out.println(str.replaceFirst("l", "!"));
運行結果
注意如果替換的是特殊字符,則需要使用轉義字符。
代碼示例:
String str1 = "192\\168\\1\\1" ; System.out.println(str1.replaceAll("\\\\", "+")); String str2 = "www.baidu.com"; System.out.println(str2.replaceAll("\\.", "%20"));
運行結果
注意事項: 由于字符串是不可變對象, 替換不修改當前字符串, 而是產(chǎn)生一個新的字符串.
4.字符串拆分
可以將一個完整的字符串按照指定的分隔符劃分為若干個子字符串。
代碼示例:
String str1 = "192.168.1.1" ; String[] array = str1.split("\\."); for (String s : array) { System.out.println(s); }
運行結果
注意:下面的的這段代碼是不能被拆分的
String str1 = "192\168\1\1" ; String[] array = str1.split("\\\\"); for (String s : array) { System.out.println(s); }
運行結果:
因為 \ 后面跟兩到三個數(shù)字會被轉義成一個八進制數(shù)字。
注意事項:
字符"|","*","+“都得加上轉義字符,前面加上”".而如果是"",那么就得寫成"\".如果一個字符串中有多個分隔符,可以用"|"作為連字符.
多次拆分代碼示例:
String str = "name=zhangsan&age=18"; String[] result = str.split("&|=") ; for (String s : result) { System.out.println(s); }
運行結果:
5.字符串截取
從一個完整的字符串之中截取出部分內容。
代碼示例:
String str = "abcdef"; System.out.println(str.substring(3)); System.out.println(str.substring(2, 4));//左閉右開 運行結果 def cd
注意事項:
索引從0開始注意前閉后開區(qū)間的寫法, substring(0, 5) 表示包含 0 號下標的字符, 不包含 5 號下標 6.其他操作方法
這些都比較簡單,用的時候查就好了。
五、StringBuffer 和 StringBuilder
首先來回顧下String類的特點:
任何的字符串常量都是String對象,而且String的常量一旦聲明不可改變,如果改變對象內容,改變的是其引用的指向而已。
通常來講String的操作比較簡單,但是由于String的不可更改特性,為了方便字符串的修改,提供StringBuffer和StringBuilder類。
StringBuffer 和 StringBuilder 大部分功能是相同的,只有較小的區(qū)別。
1.append()方法
在String中使用"+"來進行字符串連接,但是這個操作在StringBuffer類中需要更改為append()方法:
public synchronized StringBuffer append(各種數(shù)據(jù)類型 b)
代碼示例:
StringBuffer str1 = new StringBuffer("abcd"); StringBuilder str2 = new StringBuilder("abcd"); str1.append(123); str2.append("hij"); System.out.println(str1); System.out.println(str2);
運行結果:
StringBuffer 和 StringBuilder 大部分功能是相同的,它們的append()方法的方法可以拼接各種數(shù)據(jù)類型。
注意:
String和StringBuffer最大的區(qū)別在于:String的內容無法修改,而StringBuffer的內容可以修改。頻繁修改字符串的情況考慮使用StingBuffer。
因為 String通過+拼接會產(chǎn)生臨時對象,而 StringBuffer 和 StringBuilder 只會在當前對象上進行拼接。
2.字符串反轉 reverse( )
代碼示例:
StringBuffer str1 = new StringBuffer("abcdefg"); StringBuilder str2 = new StringBuilder("654321"); System.out.println(str1.reverse()); System.out.println(str2.reverse());
運行結果:
3.刪除指定范圍的數(shù)據(jù) delete( )
代碼示例:
StringBuffer str1 = new StringBuffer("abcdefg"); StringBuilder str2 = new StringBuilder("654321"); System.out.println(str1.delete(2, 5)); System.out.println(str2.delete(4, 6));
運行結果:
4.插入數(shù)據(jù) insert( )
代碼示例:
StringBuffer str1 = new StringBuffer("abcdefg"); StringBuilder str2 = new StringBuilder("654321"); str1.insert(0,"你好嗎").delete(0,1); System.out.println(str1); System.out.println(str2.delete(0, 3).insert(0, "你好世界"));
運行結果:
5.StringBuffer 和 StringBuilder的區(qū)別
來看一下 StringBuffer 和 StringBuilder 的 append 方法
1.String的拼接會產(chǎn)生臨時對象,但是后兩者每次都只是返回當前對象的引用
2.String的加號拼接,會被底層優(yōu)化為一個StringBuilder
3.StringBuilder和String,一般如果不涉及到多線程的情況下才會使用
4.StringBuffer(創(chuàng)建鎖、銷毀鎖、都是耗費資源的)
總結
1.如果以后涉及到字符串的拼接,一定要使用 StringBuffer 和 StringBuilder 的 append()方法
2.注意String類中兩種對象實例化的區(qū)別
3.相同的字符串在字符串常量池中只會存一份
一、創(chuàng)建字符串
創(chuàng)建字符串的方式有很多種,當是常見的一般就三種
1. 直接賦值(常用)
String str = "hello world !";
2. new String
String str = new String("hello world !");
3. 字符數(shù)組轉String
char[] array = {'a', 'b', 'c'}; String str = new String(array);
但以后一般都是用第一種創(chuàng)建方式
注意事項:
"hello" 這樣的字符串字面值常量, 類型也是 String.String 也屬于引用類型. String str ="Hello"
4.String類中兩種對象實例化的區(qū)別
直接賦值:只會開辟一塊堆內存空間,并且該字符串對象可以自動保存在對象池中以供下次使用。構造方法:會開辟兩塊堆內存空間,不會自動保存在對象池中,可以使用intern()方法手工入池。
二、字符串比較相等
1.直接比較字符串
我們知道兩個整形可以直接用 == 比較相等,那如果用 == 比較String類相等會發(fā)生什么呢?
代碼:
public static void main(String[] args) { String str1 = "hello"; String str2 = new String("hello"); System.out.println(str1 == str2); String str3 = "he"+"llo";//編譯的時候這個地方相當于 String str3 = "hello"; System.out.println(str1 == str3); String str4 = "he"; String str5 = "llo"; String str6 = str4+str5; System.out.println(str1 == str6); String str7 = "he"+new String("llo"); System.out.println(str1 == str7); }
運行結果:
我們知道String屬于引用類型,所以str存的是地址。那么比較的就是地址。
只要new了就會在堆上開辟內存,所以不相等。直接說可能有點抽象,下面簡單通過內存圖來判斷字符串是否相等。
2.字符串在內存中的存儲
接上面的例子我們來看一下字符串在內存中的存儲來判斷相等
注意:
1.只要new了就會在堆上開辟內存,那么必定不會相等。
2.相同的字符串在字符串常量池里只會存一份。
3.字符串常量池
String類的設計使用了共享設計模式
在JVM底層實際上會自動維護一個對象池(字符串常量池)
如果現(xiàn)在采用了直接賦值的模式進行String類的對象實例化操作,那么該實例化對象(字符串內容)將自動保存到這個對象池之中.如果下次繼續(xù)使用直接賦值的模式聲明String類對象,此時對象池之中如若有指定內容,將直接進行引用如若沒有,則開辟新的字符串對象而后將其保存在對象池之中以供下次使用
4.字符串比較equals
Java 中要想比較字符串是否相等的話,就需要使用String提供的equals方法
String str1 = new String("Hello"); String str2 = new String("Hello"); System.out.println(str1.equals(str2)); // System.out.println(str2.equals(str1)); // 或者這樣寫也行 // 執(zhí)行結果 true
equals使用的注意事項:
現(xiàn)在需要比較 str 和 “Hello” 兩個字符串是否相等, 我們該如何來寫呢?
String str = new String("Hello"); // 方式一 System.out.println(str.equals("Hello")); // 方式二 System.out.println("Hello".equals(str));
在上面的代碼中, 哪種方式更好呢?
更推薦使用 “方式二”. 一旦 str 是 null, 方式一的代碼會拋出異常, 而方式二不會
String str = null; // 方式一 System.out.println(str.equals("Hello")); // 執(zhí)行結果 拋出 java.lang.NullPointerException 異 常 // 方式二 System.out.println("Hello".equals(str)); // 執(zhí)行結果 false
注意事項: “Hello” 這樣的字面值常量, 本質上也是一個 String 對象, 完全可以使用 equals 等 String 對象的方法
5.理解字符串的不可變
字符串是一種不可變對象. 它的內容不可改變.
String 類的內部實現(xiàn)也是基于 char[] 來實現(xiàn)的, 但是 String 類并沒有提供 set 方法之類的來修改內部的字符數(shù)組.
代碼示例:
String str = "hello" ; str = str + " world" ; str += "!!!" ; System.out.println(str); // 執(zhí)行結果 hello world!!!
形如 += 這樣的操作, 表面上好像是修改了字符串, 其實不是. 內存變化如下:
+= 之后 str 打印的結果卻是變了, 但是不是 String 對象本身發(fā)生改變, 而是 str 引用到了其他的對象.
回顧引用:
引用相當于一個指針, 里面存的內容是一個地址. 我們要區(qū)分清楚當前修改到底是修改了地址對應內存的內容發(fā)生改變了, 還是引用中存的地址改變了.
6.手動入池 intern()
我們知道字符串常量是存在字符串常量池當中的,而new的是在堆上開辟內存。
而String的 intern()方法可以把String對象手動入到字符串常量池中
// 該字符串常量并沒有保存在對象池之中 String str1 = "hello" ; String str2 = new String("hello") ; System.out.println(str1 == str2); // 執(zhí)行結果 false String str1 = "hello" ; String str2 = new String("hello").intern() ; System.out.println(str1 == str2); // 執(zhí)行結果 true
如果str2沒有
intern()方法的時候,它是指向堆上的new的String對象的,而使用了intern()方法后,就會直接指向字符串常量池的
”hello“,如果調用intern()方法的時候字符串常量池中沒有 "hello"這個字符串,則會把它放入池中。
三、字符字節(jié)與字符串
1.字符轉字符串
代碼示例 :
char[] array = {'h','e','l','l','o'}; String str1 = new String(array); String str2 = new String(array,1,2); System.out.println(str1); System.out.println(str2); //運行結果 //hello //el
注意:第一個參數(shù)是偏移量,偏移量是從0開始的,第二個是參數(shù)是往后從偏移量開始的位置走幾步。且下標不能越界!
2.字符串轉字符
指定獲取字符串里的某一個字符:
String str = "hello"; char ch = str.charAt(4); System.out.println(ch); //運行結果 //o
字符串轉字符數(shù)組代碼示例:
String str = "hello"; char[] array = str.toCharArray(); for (char s : array) { System.out.print(s+" "); }
運行結果
3.字節(jié)與字符串
用法和上面的類似
代碼示例:
byte[] bytes = {97,98,99,100}; String str = new String(bytes,1,3); System.out.println(str); String str2 = "abcd"; byte[] bytes1 = str2.getBytes(); System.out.println(Arrays.toString(bytes1));
運行結果
4.編碼方式
運行結果 :
常見的編碼方式有 utf-8 和 GBK ,不過編碼方式一般只對漢字有影響。
5.小結
那么何時使用 byte[], 何時使用 char[] 呢?
byte[] 是把 String 按照一個字節(jié)一個字節(jié)的方式處理, 這種適合在網(wǎng)絡傳輸, 數(shù)據(jù)存儲這樣的場景下使用. 更適合 針對二進制數(shù)據(jù)來操作.char[] 是吧 String 按照一個字符一個字符的方式處理, 更適合針對文本數(shù)據(jù)來操作, 尤其是包含中文的時候
回憶概念: 文本數(shù)據(jù) vs 二進制數(shù)據(jù)
一個簡單粗暴的區(qū)分方式就是用記事本打開能不能看懂里面的內容.
如果看的懂, 就是文本數(shù)據(jù)(例如 .java 文件), 如果看不懂, 就是二進制數(shù)據(jù)(例如 .class 文件).
四、字符串常見操作
1.字符串比較
上面使用過String類提供的equals()方法,該方法本身是可以進行區(qū)分大小寫的相等判斷。除了這個方法之外,String類還提供有如下的比較操作:
代碼示例:
String str = "abcd"; System.out.println("abcd".equals(str)); System.out.println("Abcd".equalsIgnoreCase(str));//不區(qū)分大小寫 //運行結果 //true //true
**compareTo()**方法前面博客有詳細介紹,這里就不多說了??梢钥纯础?gt;compareTo方法
在String類中compareTo()方法是一個非常重要的方法,該方法返回一個整型,該數(shù)據(jù)會根據(jù)大小關系返回三類內
容:
相等:返回0.小于:返回內容小于0.大于:返回內容大于0。
2.字符串查找
從一個完整的字符串之中可以判斷指定內容是否存在,對于查找方法有如下定義:
代碼示例 :
String str = "abcdefg"; 找子串 System.out.println(str.contains("efg")); 從頭開始找指定字符串,找到返回下標,找不到返回 -1 System.out.println(str.indexOf("d")); 指定位置開始找指定字符串 System.out.println(str.indexOf("d",2)); 從后向前找指定字符串 System.out.println(str.lastIndexOf("fg")); 判斷是否以指定字符串開頭 System.out.println(str.startsWith("abc")); 從指定位置判斷是否以該字符串開頭 System.out.println(str.startsWith("de", 3));
用法都是通過 String類點出方法名,注意就收放回值就好了。
3.字符串替換
使用一個指定的新的字符串替換掉已有的字符串數(shù)據(jù),可用的方法如下:
代碼示例:
String str = "helloworld" ; System.out.println(str.replaceAll("l", "!")); System.out.println(str.replaceFirst("l", "!"));
運行結果
注意如果替換的是特殊字符,則需要使用轉義字符。
代碼示例:
String str1 = "192\\168\\1\\1" ; System.out.println(str1.replaceAll("\\\\", "+")); String str2 = "www.baidu.com"; System.out.println(str2.replaceAll("\\.", "%20"));
運行結果
注意事項: 由于字符串是不可變對象, 替換不修改當前字符串, 而是產(chǎn)生一個新的字符串.
4.字符串拆分
可以將一個完整的字符串按照指定的分隔符劃分為若干個子字符串。
代碼示例:
String str1 = "192.168.1.1" ; String[] array = str1.split("\\."); for (String s : array) { System.out.println(s); }
運行結果
注意:下面的的這段代碼是不能被拆分的
String str1 = "192\168\1\1" ; String[] array = str1.split("\\\\"); for (String s : array) { System.out.println(s); }
運行結果:
因為 \ 后面跟兩到三個數(shù)字會被轉義成一個八進制數(shù)字。
注意事項:
字符"|","*","+“都得加上轉義字符,前面加上”".而如果是"",那么就得寫成"\".如果一個字符串中有多個分隔符,可以用"|"作為連字符.
多次拆分代碼示例:
String str = "name=zhangsan&age=18"; String[] result = str.split("&|=") ; for (String s : result) { System.out.println(s); }
運行結果:
5.字符串截取
從一個完整的字符串之中截取出部分內容。
代碼示例:
String str = "abcdef"; System.out.println(str.substring(3)); System.out.println(str.substring(2, 4));//左閉右開 運行結果 def cd
注意事項:
索引從0開始注意前閉后開區(qū)間的寫法, substring(0, 5) 表示包含 0 號下標的字符, 不包含 5 號下標 6.其他操作方法
這些都比較簡單,用的時候查就好了。
五、StringBuffer 和 StringBuilder
首先來回顧下String類的特點:
任何的字符串常量都是String對象,而且String的常量一旦聲明不可改變,如果改變對象內容,改變的是其引用的指向而已。
通常來講String的操作比較簡單,但是由于String的不可更改特性,為了方便字符串的修改,提供StringBuffer和StringBuilder類。
StringBuffer 和 StringBuilder 大部分功能是相同的,只有較小的區(qū)別。
1.append()方法
在String中使用"+"來進行字符串連接,但是這個操作在StringBuffer類中需要更改為append()方法:
public synchronized StringBuffer append(各種數(shù)據(jù)類型 b)
代碼示例:
StringBuffer str1 = new StringBuffer("abcd"); StringBuilder str2 = new StringBuilder("abcd"); str1.append(123); str2.append("hij"); System.out.println(str1); System.out.println(str2);
運行結果:
StringBuffer 和 StringBuilder 大部分功能是相同的,它們的append()方法的方法可以拼接各種數(shù)據(jù)類型。
注意:
String和StringBuffer最大的區(qū)別在于:String的內容無法修改,而StringBuffer的內容可以修改。頻繁修改字符串的情況考慮使用StingBuffer。
因為 String通過+拼接會產(chǎn)生臨時對象,而 StringBuffer 和 StringBuilder 只會在當前對象上進行拼接。
2.字符串反轉 reverse( )
代碼示例:
StringBuffer str1 = new StringBuffer("abcdefg"); StringBuilder str2 = new StringBuilder("654321"); System.out.println(str1.reverse()); System.out.println(str2.reverse());
運行結果:
3.刪除指定范圍的數(shù)據(jù) delete( )
代碼示例:
StringBuffer str1 = new StringBuffer("abcdefg"); StringBuilder str2 = new StringBuilder("654321"); System.out.println(str1.delete(2, 5)); System.out.println(str2.delete(4, 6));
運行結果:
4.插入數(shù)據(jù) insert( )
代碼示例:
StringBuffer str1 = new StringBuffer("abcdefg"); StringBuilder str2 = new StringBuilder("654321"); str1.insert(0,"你好嗎").delete(0,1); System.out.println(str1); System.out.println(str2.delete(0, 3).insert(0, "你好世界"));
運行結果:
5.StringBuffer 和 StringBuilder的區(qū)別
來看一下 StringBuffer 和 StringBuilder 的 append 方法
1.String的拼接會產(chǎn)生臨時對象,但是后兩者每次都只是返回當前對象的引用
2.String的加號拼接,會被底層優(yōu)化為一個StringBuilder
3.StringBuilder和String,一般如果不涉及到多線程的情況下才會使用
4.StringBuffer(創(chuàng)建鎖、銷毀鎖、都是耗費資源的)
六、總結
1.如果以后涉及到字符串的拼接,一定要使用 StringBuffer 和 StringBuilder 的 append()方法
2.注意String類中兩種對象實例化的區(qū)別
3.相同的字符串在字符串常量池中只會存一份
希望大家可以多多關注腳本之家的其他文章!
相關文章
git stash 和unstash的使用操作,git unstash failed
這篇文章主要介紹了git stash 和unstash的使用操作,git unstash failed,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-02-02Spring Boot如何使用Spring Security進行安全控制
要實現(xiàn)訪問控制的方法多種多樣,可以通過Aop、攔截器實現(xiàn),也可以通過框架實現(xiàn),本文將具體介紹在Spring Boot中如何使用Spring Security進行安全控制。2017-04-04elasticsearch bucket 之rare terms聚合使用詳解
這篇文章主要為大家介紹了elasticsearch bucket 之rare terms聚合使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-11-11Spring boot中PropertySource注解的使用方法詳解
這篇文章主要給大家介紹了關于Spring boot中PropertySource注解的使用方法,文中通過示例代碼介紹的非常詳細,對大家學習或者使用Spring boot具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧。2017-12-12java 較大數(shù)據(jù)量取差集,list.removeAll性能優(yōu)化詳解
這篇文章主要介紹了java 較大數(shù)據(jù)量取差集,list.removeAll性能優(yōu)化詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-09-09