一文帶你吃透Java中的String類
Java語言中的String對象是一個(gè)非常常見的數(shù)據(jù)類型,大多數(shù)情況下我們都是在使用String對象來表示字符串類型的數(shù)據(jù)。Java中的String類是一個(gè)final class,它是不可被繼承的。本文將對Java中的String對象進(jìn)行詳細(xì)全面的描述,包括以下幾個(gè)方面:
一、String類的概述
在 Java 中,字符串是一種常見的數(shù)據(jù)類型,經(jīng)常用于存儲(chǔ)一些文本信息。而String類則是Java提供的專門用于字符串操作的類,在Java標(biāo)準(zhǔn)庫中,它位于java.lang包中。
String類是不可被繼承的final類,即它不能被其他類所繼承,也就是說它不能被修改。String類是通過使用Unicode字符集來表示字符串的,這使得Java支持多語言字符集。由于String類的不可變性(immutable),所以它可以作為安全的參數(shù)發(fā)送給諸如網(wǎng)絡(luò)連接或數(shù)據(jù)庫鏈接之類的方法,而不必?fù)?dān)心其被篡改。String對象可以用來存儲(chǔ)任何字符串類型的數(shù)據(jù),包括HTML、XML等格式的字符串。
二、String類的構(gòu)造函數(shù)
在 Java 中,String類提供了多種構(gòu)造函數(shù),可以用于創(chuàng)建字符串對象。下面是String類的一些常用構(gòu)造函數(shù):
- String(char[] value):根據(jù)字符數(shù)組value來創(chuàng)建String對象。
- String(char[] value, int offset, int count):根據(jù)字符數(shù)組value的指定部分(offset開始的count個(gè)字符)來創(chuàng)建String對象。
- String(byte[] bytes):根據(jù)字節(jié)數(shù)組bytes來創(chuàng)建String對象,使用平臺(tái)默認(rèn)的字符集。
- String(byte[] bytes, Charset charset):根據(jù)字節(jié)數(shù)組bytes來創(chuàng)建String對象,使用指定的字符集charset。
- String(String original):根據(jù)原始字符串original來創(chuàng)建String對象。
例如:
String str1 = new String("Hello World!"); char[] charArray = {'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', '!'}; String str2 = new String(charArray);
三、String類的常用方法
在Java中,String類還提供了很多常用的方法,下面我們來介紹一些常用的方法:
3.1、字符串拼接
String concat(String str):連接指定的字符串參數(shù)到此字符串的末尾。
例如:
String s1 = "Hello"; String s2 = "World"; String s3 = s1.concat(s2); // s3 = "HelloWorld"
3.2、字符串截取
- char charAt(int index):返回指定索引處的 char 值。
- int indexOf(int ch):返回指定字符在此字符串中第一次出現(xiàn)處的索引。
- int indexOf(int ch, int fromIndex):返回指定字符在此字符串中從指定位置后第一次出現(xiàn)處的索引。
- int indexOf(String str):返回指定子字符串在此字符串中第一次出現(xiàn)處的索引。
- int lastIndexOf(int ch):返回指定字符在此字符串中最后一次出現(xiàn)處的索引。
- int lastIndexOf(int ch, int fromIndex):返回指定字符在此字符串中從指定位置前最后一次出現(xiàn)處的索引。
- int lastIndexOf(String str):返回指定子字符串在此字符串中最后一次出現(xiàn)處的索引。
- String substring(int beginIndex):返回一個(gè)新的字符串,它是此字符串的一個(gè)子字符串。
- String substring(int beginIndex, int endIndex):返回一個(gè)新的字符串,它是此字符串的一個(gè)子字符串。
例如:
String str = "Java is the best programming language!"; System.out.println(str.charAt(5)); // out: 'i' System.out.println(str.indexOf("the")); // out: 8 System.out.println(str.substring(0, 4)); // out: "Java"
3.3、字符串替換
- String replace(char oldChar, char newChar):返回一個(gè)新的字符串,它是通過用 newChar 替換此字符串中出現(xiàn)的所有 oldChar 得到的。
- String replace(CharSequence target, CharSequence replacement):使用指定的 replacement 替換此字符串所有匹配給定的正則表達(dá)式的子字符串。
例如:
String str = "Java is the best programming language!"; System.out.println(str.replace('a', 'A')); // out: "JAvA is the best progrAmming lAnguAge!" System.out.println(str.replace("the", "a")); // out: "Java is a best programming language!"
3.4、字符串分割
- String[] split(String regex):根據(jù)指定的正則表達(dá)式拆分此字符串。
- String[] split(String regex, int limit):根據(jù)指定的正則表達(dá)式拆分此字符串,最多拆分出limit個(gè)子字符串。
例如:
String str = "Java is the best programming language!"; String[] words1 = str.split(" "); System.out.println(Arrays.toString(words1)); // out: ["Java", "is", "the", "best", "programming", "language!"] String[] words2 = str.split(" ", 3); System.out.println(Arrays.toString(words2)); // out: ["Java", "is", "the best programming language!"]
3.5、大小寫轉(zhuǎn)換
- String toLowerCase():使用默認(rèn)語言環(huán)境的規(guī)則將此 String 所有字符都轉(zhuǎn)換為小寫。
- String toUpperCase():使用默認(rèn)語言環(huán)境的規(guī)則將此 String 所有字符都轉(zhuǎn)換為大寫。
例如:
String str = "Java is the best programming language!"; System.out.println(str.toUpperCase()); // out: "JAVA IS THE BEST PROGRAMMING LANGUAGE!"
3.6、字符串比較
- boolean equals(Object anObject):將此字符串與指定對象進(jìn)行比較。如果兩個(gè)對象相等,則返回 true;否則返回 false。
- boolean equalsIgnoreCase(String anotherString):將此 String 與另一個(gè) String 進(jìn)行比較,不考慮大小寫。
- boolean startsWith(String prefix):測試此字符串是否以指定的前綴開始。
- boolean endsWith(String suffix):測試此字符串是否以指定的后綴結(jié)束。
- int compareTo(String anotherString):按字典順序比較兩個(gè)字符串。
例如:
String str1 = "Java is awesome!"; String str2 = "Java is great!"; System.out.println(str1.equals(str2)); // out: false System.out.println(str1.startsWith("Java")); // out: true System.out.println(str2.endsWith("great!")); // out: true System.out.println(str1.compareTo(str2)); // out: -6
四、String類的不可變性原理及優(yōu)缺點(diǎn)
String類在Java中是不可變的(immutable)的,這意味著一旦創(chuàng)建了一個(gè)String對象,它的值就不能被修改。String類的不可變性主要由以下兩個(gè)方面造成:
4.1、String類的存儲(chǔ)結(jié)構(gòu)
在Java中,String對象實(shí)際上是一個(gè)包含字符數(shù)組的引用和一個(gè)表示字符串長度的整數(shù)。因此,在進(jìn)行字符串操作時(shí),String對象的引用和長度是不會(huì)變化的,只有字符數(shù)組才會(huì)被修改。而由于Java數(shù)組是一個(gè)固定長度的數(shù)據(jù)結(jié)構(gòu),因此String對象的不可變性就被保證了。
4.2、String類的操作方法
在Java中,String對象提供了很多用于字符串操作的方法(例如substring、concat等)。這些方法都是返回一個(gè)新的String對象,而不會(huì)在原有的String對象上進(jìn)行修改,這也保證了String對象的不可變性。
String對象的不可變性帶來了下面的優(yōu)點(diǎn):
- 線程安全:由于String對象的不可變性,多個(gè)線程可以對同一個(gè)String對象進(jìn)行訪問操作,而不必?fù)?dān)心數(shù)據(jù)的安全問題。
- 安全性:由于String對象不可變,它不能被篡改,從而可以避免一些惡意攻擊。
- 性能優(yōu)化:由于String對象是不可變的,因此可以進(jìn)行一些性能方面的優(yōu)化。例如,String類實(shí)現(xiàn)了字符串池這個(gè)概念。
同時(shí)也存在以下缺點(diǎn):
- 內(nèi)存占用:由于每次使用String類進(jìn)行字符串操作時(shí),都會(huì)創(chuàng)建一個(gè)新的String對象,并且原有的String對象不會(huì)被修改,這樣就會(huì)占用更多的內(nèi)存空間。
- 創(chuàng)建大量垃圾對象:由于String對象的不可變性,每進(jìn)行一次字符串操作就會(huì)創(chuàng)建一個(gè)新的String對象,如果進(jìn)行大量的字符串操作,就會(huì)創(chuàng)建大量的垃圾對象,導(dǎo)致垃圾回收器的頻繁運(yùn)行。
- 字符串拼接效率低:由于每進(jìn)行一次字符串拼接操作,就會(huì)創(chuàng)建一個(gè)新的String對象,效率較低。
五、String類的實(shí)現(xiàn)原理及性能問題
在 Java 中,String對象是通過char[]字符數(shù)組來存儲(chǔ)字符串的。StringBuilder和StringBuffer也是通過char[]數(shù)組來存儲(chǔ)字符串的,只不過它們在進(jìn)行字符串操作時(shí),會(huì)在原有的char[]數(shù)組上進(jìn)行修改,而不是每次都創(chuàng)建一個(gè)新的char[]數(shù)組。
由于String對象的不可變性,每次對String對象進(jìn)行字符串操作時(shí)都會(huì)創(chuàng)建一個(gè)新的String對象,這樣會(huì)導(dǎo)致大量的內(nèi)存開銷和垃圾對象的產(chǎn)生,因此在進(jìn)行大量的字符串操作時(shí),應(yīng)該盡量使用StringBuilder或StringBuffer來避免這些問題。
StringBuilder和StringBuffer都繼承了AbstractStringBuilder類,它們之間的區(qū)別在于StringBuilder是線程不安全的,而StringBuffer是線程安全的。如果多個(gè)線程需要對同一個(gè)字符串進(jìn)行操作時(shí),應(yīng)該使用StringBuffer來保證線程安全性。
在進(jìn)行字符串操作時(shí),如果需要?jiǎng)?chuàng)建一個(gè)新的String對象,可以使用靜態(tài)方法String.valueOf()或者直接將字符數(shù)組傳遞給String類的構(gòu)造函數(shù)來創(chuàng)建新的String對象,這樣可以避免產(chǎn)生大量的垃圾對象。
六、字符串池的工作原理
Java中有一種稱為字符串池(String Pool)的機(jī)制,它的主要作用是避免創(chuàng)建重復(fù)的String對象,從而節(jié)省內(nèi)存空間。
當(dāng)創(chuàng)建一個(gè)字符串時(shí),JVM首先會(huì)在字符串池中查找該字符串是否已經(jīng)存在。如果存在,則返回該字符串在字符串池中的引用;否則,在字符串池中創(chuàng)建該字符串,并返回該字符串在字符串池中的引用。
下面是一個(gè)示例代碼:
String str1 = "Hello"; String str2 = "Hello"; String str3 = new String("Hello"); System.out.println(str1 == str2); // true,因?yàn)閟tr1和str2都指向字符串池中的同一個(gè)對象 System.out.println(str1 == str3); // false,因?yàn)閟tr3指向堆內(nèi)存中新創(chuàng)建的String對象
因此,如果需要?jiǎng)?chuàng)建多個(gè)相同的字符串對象,可以直接使用字符串池中已有的對象,這樣可以節(jié)省內(nèi)存空間。
七、String類與StringBuilder、StringBuffer的比較
在進(jìn)行字符串操作時(shí),Java中常用的有String、StringBuilder和StringBuffer三種類。
- String:String類是不可變的,每次進(jìn)行字符串操作時(shí)都會(huì)創(chuàng)建一個(gè)新的String對象。因此,在需要大量字符串操作時(shí),使用String類效率較低。
- StringBuilder:StringBuilder是可變的,它可以在原有的字符數(shù)組上進(jìn)行修改,而不用每次都創(chuàng)建一個(gè)新的字符數(shù)組。因此,在需要大量字符串操作時(shí),使用StringBuilder類可以提高效率。
- StringBuffer:StringBuffer也是可變的,并且是線程安全的,因此適用于多個(gè)線程對同一字符串進(jìn)行操作的場景。
下面是一個(gè)比較字符串拼接效率的示例代碼:
String s = ""; for (int i = 0; i < 10000; i++) { s += "a"; }
上述代碼中使用了String來進(jìn)行字符串拼接操作,每次都會(huì)創(chuàng)建一個(gè)新的String對象,因此效率較低。下面是使用StringBuilder進(jìn)行字符串拼接的代碼示例:
StringBuilder sb = new StringBuilder(); for (int i = 0; i < 10000; i++) { sb.append("a"); } String s = sb.toString();
由于StringBuilder是可變的,因此在進(jìn)行字符串操作時(shí)效率較高。
總之,在進(jìn)行大量的字符串操作時(shí),應(yīng)該盡量使用StringBuilder或StringBuffer,避免使用String類導(dǎo)致效率低下。
以上就是一文帶你吃透Java中的String類的詳細(xì)內(nèi)容,更多關(guān)于Java String類的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
MyBatis-Plus攔截器對敏感數(shù)據(jù)實(shí)現(xiàn)加密
做課程項(xiàng)目petstore時(shí)遇到需要加密屬性的問題,而MyBatis-Plus為開發(fā)者提供了攔截器的相關(guān)接口,本文主要介紹通過MyBatis-Plus的攔截器接口自定義一個(gè)攔截器類實(shí)現(xiàn)敏感數(shù)據(jù)如用戶密碼的加密功能,感興趣的可以了解一下2021-11-11linux的shell命令檢測某個(gè)java程序是否執(zhí)行
ps -ef |grep java|grep2016-04-04SpringBoot根據(jù)目錄結(jié)構(gòu)自動(dòng)配置Url前綴方式
這篇文章主要介紹了SpringBoot根據(jù)目錄結(jié)構(gòu)自動(dòng)配置Url前綴方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-11-11java使用java.io.File類和java.nio.file.Path類對文件重命名
這篇文章主要給大家介紹了關(guān)于java使用java.io.File類和java.nio.file.Path類對文件重命名的相關(guān)資料,本文僅為日常操作記錄,方便后期使用查找本地電腦文件太多了,又不想一個(gè)一個(gè)重命名,改名字什么的很麻煩,需要的朋友可以參考下2024-02-02SpringBoot的@Value注解如何設(shè)置默認(rèn)值
這篇文章主要介紹了SpringBoot的@Value注解如何設(shè)置默認(rèn)值問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-02-02mybatis group by substr函數(shù)傳參報(bào)錯(cuò)的解決
這篇文章主要介紹了mybatis group by substr函數(shù)傳參報(bào)錯(cuò)的解決方案,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-01-01