本文主要介紹一些關于Java字元串的易錯易忘的知識點,并非系統完整介紹,如有在意,還請見諒。
一、字元串的概念
1.字元串到底是什麼
💭:字元串的概念有什麼好說的?😪
💬:這裡不是的簡單重複其一般性概念哦,而是專門指明Java中字元串的本質
在Java中,其實Java字元串就是Unicode字元序列。String 并不是Java内置的基本類型,而是由标準Java類庫中提供的一個預定義類。
2.差別 碼點 和 代碼單元
🔔概念解釋:
碼點是指 一個編碼表 中的 某個字元 對應的 代碼值。
Unicode的碼點分為17個代碼級别,第一個級别是基本的多語言級别,碼點從U+0000——U+FFFF,其餘的16個級别從U+10000——U+10FFFF,其中包括一些輔助字元。
代碼單元則是指在基本的多語言級别中,每個字元用16位表示代碼單元。而輔助字元則采用一對連續的代碼單元進行編碼。
總之,一個碼點既可以表示一個一般字元也可以表示一個輔助字元;而一個代碼單元則隻能表示一個一般字元,要兩個代碼單元才能表示一個輔助字元。
🚬 我的個人了解是:代碼單元其實是一種抽象的機關1,為了友善周遊字元串中的一般字元和表示char類型字元的。
⭕️補充:如果想要了解更多關于編碼的細節問題請看:
編碼格式簡介(ANSI、GBK、GB2312、UTF-8、GB18030和 UNICODE)
二、字元串的有趣方法
1.像切片一樣擷取子串
用過Python的應該知道Python有一個好用的處理字元串的方式叫做 切片,而在Java中同樣有類似方法,并且規律相同,都是左閉右開。
🕑方法如下:
🕒代碼實作如下:
🕓代碼運作結果如下:
⭕️補充:從以上結果可以看出,substring(m,n) 方法------當m與n相等時,截取到的子串為空,并不會報錯
2.拼接字元串
🔔解釋:
在Java中,當一個字元串與一個非字元串的值進行拼接時,後者會被轉換為字元串(其實任何一個Java對象都能轉換為字元串,重寫toString方法即可)而使用 + (加号)就可以拼接啦。
⭕️補充:在拼接多個字元串時,如果想要用一個界定符分隔它們,則可以使用String類的 靜态join 方法
🕑方法如下:
🕒代碼實作如下:
🕓代碼運作結果如下:
3.處理碼點和代碼單元
經常使用的是擷取代碼單元,因為擷取到代碼單元經常與char字元進行比較或者其他處理,本文最後會給出一道算法題,其中就可以利用這個。
3.1擷取長度
🕒代碼實作如下:
public class Article {
public static void main(String[] args) {
String str = "hi\uD835\uDD46"; //hi後面的其實是輔助字元:𝕆
//擷取字元串的代碼單元長度
int unit_len = str.length();
//擷取字元串的碼點長度/碼點數量
int cpCount = str.codePointCount(0,unit_len);
System.out.println("代碼單元長度:"+unit_len);
System.out.println("碼點長度/數量:"+cpCount);
}
}
🕓代碼運作結果如下:
怎麼樣,是不是很有趣?😄
3.2擷取索引為n處的值
🕒代碼實作如下:
public class Article {
public static void main(String[] args) {
String str = "hi\uD835\uDD46";
//擷取索引為1處的代碼單元
char first = str.charAt(1);
//擷取索引為1處的碼點
int cp = str.codePointAt(1);
//有意思的是碼點長度為3,但卻可以取到索引3處的值;這是為什麼呢?
System.out.println("代碼單元:"+first);
System.out.println("碼點:"+cp);
}
}
🕓代碼運作結果如下:
4.将字元串轉為字元數組
🕑方法如下:
🕒代碼實作如下:
public class Article {
public static void main(String[] args) {
String str = "hi,windx";
char[] c = str.toCharArray();
for (int i = 0; i < c.length; i++) {
System.out.print(c[i]+" ");
}
}
}
🕓代碼運作結果如下:
5.其它方法(判别前字尾、去除空白符)
5.1 判别前字尾
有時我們通常會對一個字元串的字首或字尾進行判斷,看是否滿足篩選條件,此時這個方法就能夠派上用處了(如果用substring()的話有時會有意想不到的Bug)。
🕑方法如下:
①字首:
②字尾:
分别判斷是否以某字元串開頭、以某字元串結尾,均傳回boolean類型值。
5.2 去除空白符
該方法可以删除原始字元串頭部和尾部小于等于U+0020的字元或空格,同樣用于對字元串進行處理。
🕑方法如下:
三、判斷字元串是否相等
👉 首先要注意的是字元串是不可變的,當簡單複制一個字元串時,其實是共享了同一處空間,隻是複制了引用而已。
是以,
- 使用 == 運算符判斷兩字元串是否相等,比較的隻是兩字元串的位址。
- 如果要比較内容,需要使用equals()方法!而不區分大小寫比較,則使用equalsIgnoreCase()方法。
⭕️補充:不論是使用 + 連接配接空字元串還是substring()擷取子串或者進行大小寫轉換,都會改變字元串的位址
🕒代碼測試如下:
public static void main(String[] args) {
String a = "aaa";
String b = a;
System.out.println("初始a的位址:");
System.out.println("a:"+String.class.getName() + "@" + Integer.toHexString(System.identityHashCode(a)));
a+="";
if(b==a){
System.out.println("b==a");
}
if(b.equals(a)){
System.out.println("b.equals(a)");
}
System.out.println("與空串拼接後a的位址:");
System.out.println("a:"+String.class.getName() + "@" + Integer.toHexString(System.identityHashCode(a)));
System.out.println("b的位址:");
System.out.println("b:"+String.class.getName() + "@" + Integer.toHexString(System.identityHashCode(b)));
}
🕓代碼運作結果如下:
可以看到由初始的a字元串複制的b字元串的位址與其初始位址是相等的,而a在拼接空串後,其位址發生了變化,但内容值不變。