在正式介紹String以前,咱們先介紹下CharSequencephp
char + sequence 就是字符的序列的意思css
Java中萬事萬物都是對象類型vue
而對於字符的序列,也就是多個char, 這麼一種東西, 使用CharSequence這個接口來描述ios
既然是接口,天然規定了做爲字符序列的基本協議c++
char charAt(int index); | 返回指定索引的char |
int length() | 返回字符序列的長度 |
CharSequence subSequence(int start, int end) | 返回子序列 |
String toString() | 返回一個包含此序列中字符的字符串該字符串與此序列的順序相同 |
default IntStream chars() | 返回此序列的int stream,每一個char零位擴展爲int |
default IntStream codePoints() | 返回此序列的代碼點的stream |
字符到字節,是一個編碼的過程
字節到字符是一個解碼的過程
|
一樣的一個字符,在不一樣的字符集和編碼方式下,實際存儲的值,將是不一樣的
好比前面說的Unicode字符集,UTF8 和UTF16編碼後的數據是不一樣的
這個編碼後的數據,也就是字節 , 他們是不同的
|
一樣的一個編碼值,在不一樣的字符集中,可能表明着不一樣的字符 |
因此字符與字節之間,必然有編碼參與其中
這個編碼環節是必然存在的,不然,你就沒辦法把字節與字符聯繫起來
|
一個字符能夠根據 字符集編碼 進行多種方式的編碼 一個字節數組也能夠根據 字符集編碼 進行多種方式的解碼 對於同一個字符,無論進行何種編碼,當他們按照當初編碼的方式進行解碼時,必然對應的仍是一樣的那個字符 |
操做系統的文件都是以字節序列的形式存儲的,因此任何一個文件都是有編碼的 好比你在txt文件中輸入了一個字符 這個字符 底層就會使用指定的編碼存儲到字節中 軟件自己又把這個編碼以字符的形式呈現出來 因此你纔看獲得是一個字符 好比這個文件中11111.txt中,存儲了一個漢字春天的 " 春" 編碼方式是UTF8 二進制軟件查看是E6 98 A5 與咱們進行UTF8 編碼計算的結果是對應的 |
ANSI編碼 不一樣的國家和地區制定了不一樣的標準 由此產生了 GB23十二、GBK、Big五、Shift_JIS 等各自的編碼標準 這些使用 1 至 4 個字節來表明一個字符的各類漢字延伸編碼方式,稱爲 ANSI 編碼 在簡體中文Windows操做系統中,ANSI 編碼表明 GBK 編碼; 在日文Windows操做系統中,ANSI 編碼表明 Shift_JIS 編碼 再看下面一個例子 使用ultraedit 新建了一個文件,裏面寫了一個漢字 "春", 其實這個默認格式就是操做系統的編碼,也就是ANSI 也就是GBK 查看二進制編碼爲 B4 BA 而後咱們再去對照GBK的碼錶,你會發現徹底對的上 |
任何一個文件,他其實有自帶或者說默認的一個編碼 凡是呈現字符的地方,都有一個編碼在默默地支撐,纔可以讓你看得見,看得清楚字符 這個字符的保存 , 就是字符按照編碼表 編碼 成字節序列的過程 這個字符的呈現 , 就是字節序列按照編碼表 解碼 成字符的過程 當你使用計算機,進行字符處理工做的時候,無時無刻都在進行着編碼與解碼 |
String是經常使用類之一,因此提供了很是豐富的方法
String是字符序列 內部是char[] char就是一個十六進制的數 16位表示
因此char[] 能夠用來構造String
|
char是16位數可以表示代碼單元, int天然能夠直接表示一個代碼點了,因此也可使用int來構造String |
另外再加上咱們剛纔關於字節數組與字符關係的介紹,也可使用字節數組構造String |
String() | 空String ,沒啥必要由於String是不可變的 |
String(char[])
String(char[], int, int)
|
藉助於字符數組或者字符數組的一部分建立對象 內部原本就是字符數組 char[] 因此天然可使用char[]構造 直接進行拷貝,因此對原有字符數組的修改不影響String對象 |
String(int[], int, int) | 使用代碼點構造String public String(int[] codePoints, int offset, int count) offset 和 count爲範圍限制 |
String(String) | |
String(StringBuffer) | |
String(StringBuilder) |
先提一下另一個方法,getBytes
使用指定的字符集將此 String 編碼爲 byte 序列
個人編輯器環境是UTF8編碼的
"春" 的UTF8編碼上面已經分析了
也就是說我這邊有一個UTF8的字符"春" 源文件中保存的是 E6 98 A5
對於下面全部的getBytes來講,"春" 這個字符形狀符號是不變的
得到的字節數組就是 這個字符形狀符號 根據不一樣字符集編碼方式, 編碼而獲得的字節數組
下面的各類轉換換一個描述就是:UTF8的字符"春" ,在其餘的字符集下面,編碼都是多少啊?
|
爲何UTF-8 是-26 -104 -91 ? 而不是e6 98 a5?進制問題 |
getBytes總共三種形式 指定編碼或者使用默認
getBytes(String)
getBytes(Charset)
getBytes()
還有一種已經棄用 了
|
使用byte[] 字節數組構造String的過程是下圖這樣子的 字節數組,根據指定字符編碼轉換爲那個字符 而後在把字符按照UTF16 進行編碼 存儲到String中的char[] 上面的例子能夠很好地印證這一點,字節數組是[-76, -70] 也就是 : ffffffb4 ffffffba 也就是 B4 BA 明明是GBK的"春" 根本就不是6625 對應關係就是他們表示的是同一個字符 |
既然字節數組與字符的轉換離不開編碼,因此天然經過byte[] 構造String對象時,必需要有編碼
不設定並非沒有,而是使用默認的
既然使用字節數組,那麼有的時候可能須要指定範圍,因此有兩個根本的構造方法
|
而後還有默認字符編碼的簡化形式 |
再而後就是長度爲整個字節數組的簡化形式 |
這幾個構造方法根本在於理解 字節數組與字符的轉換 以及必須的byte[] 字節數組 以及 編碼 |
copyValueOf方法內部就是直接調用的兩個構造方法 還不如直接使用new建立來的直接,只不過使用這個方法有更好的可讀性 |
charAt(int) 返回指定索引處的 char 值 索引範圍爲從 0 到 length() - 1 簡單粗暴, 無論三七二十一就是代碼單元 若是是輔助平面,那就多是代理項 |
codePointAt(int) 返回指定索引處的代碼點, 範圍從 0 到 length() - 1 他跟Character中的codePointAt方法邏輯含義是同樣的 若是是高代理,若是下一個也在掌控範圍內,若是下一個是低代理,那麼返回代碼點 不然,返回代碼單元 也就是一個char |
codePointBefore(int) 返回指定索引以前的字符(Unicode 代碼點) 其範圍從 1 到 length 他跟Character中的codePointBefore方法邏輯含義是同樣的 若是index-1 是低代理,若是在往前一個index-2 也是有效範圍內,若是他還剛好是一個高代理,返回代碼點 不然,返回代碼單元,也就是一個char |
codePointCount(int, int) 此 String 的指定文本範圍中的 Unicode 代碼點數 文本範圍始於指定的 beginIndex,一直到索引 endIndex - 1 處的 char, 包含頭不包含尾 該文本範圍的長度(用 char 表示)是 endIndex-beginIndex 因爲一個代碼點的代碼單元個數多是1個多是2個,因此代碼點的個數須要計算,就不直觀了 他跟Character中的codePointCount方法邏輯含義是同樣的 |
offsetByCodePoints(int, int) 他跟Character中的offsetByCodePoints方法邏輯含義是同樣的 返回此 String 中從給定的 index 處偏移 codePointOffset 個代碼點的索引 根本緣由仍是一個代碼點的代碼單元個數多是1個多是2個 因此 偏移codePointOffset個代碼點的 代碼單元的個數不肯定,須要調用方法計算 |
實例方法 就是一個複製方法,名字不太規範 複製String中指定索引開始的srcBegin 和 srcEnd 包含頭不包含尾 到另外一個字節數組 char dst[]中, 存放的起始位置爲dstBegin public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) |
須要注意的是,複製的是char 代碼單元 就是String 內部char[] 的下標索引 |
startsWith(String, int)
startsWith(String)
|
實例方法 測試String是否以指定的前綴開始 還能夠指定起始位置處開始比較 從源代碼看得出來,挨個比較內部的char 從頭開始,所有一致才返回true 單參數是雙參數的簡化版本 |
endsWith(String) | endwith就是從最後的指定參數長度的位置開始比較 |
int indexOf(int ch)
int indexOf(int ch, int fromIndex)
|
返回 指定字符 在此字符串中第一次出現處的索引 返回的匹配的第一個 也能夠指定檢索的起始位置, 若是指定了索引 那麼返回的值將 大於等於 指定的索引 換個說法: 若是是0號平面返回的是那個代碼單元也就是代碼點的索引
charAt(k) == ch 爲 true 的最小 k 值
若是是輔助平面返回的是高代理位的代碼單元的索引 codePointAt(k) == ch 爲 true 的最小 k 值 |
int indexOf(String str)
int indexOf(String str, int fromIndex)
|
返回 指定子字符串 在此字符串中第一次出現處的索引
返回匹配的第一個
也能夠指定檢索的起始位置,若是指定了索引
那麼返回值須要大於等於 指定的索引
匹配的含義爲startsWith(str) 爲true
若是指定檢索開始的位置, 那麼
不只僅startsWith(str) 爲true 還須要索引知足指定的下標範圍
不然仍舊是返回-1
|
lastIndexOf(int)
lastIndexOf(int, int)
|
返回指定字符在此字符串中最後一次出現處的索引 返回匹配的最後一個 也能夠指定檢索位置,可是這個檢索位置與indexOf不一樣 indexOf中指定的索引,是從索引處日後 lastIndexOf指定的索引, 是反向,從索引處往前 指定了索引就要求 返回值 小於等於 指定索引 換個說法
若是是0號平面返回的是那個代碼單元也就是代碼點的索引
charAt(k) == ch 爲 true 的最大 k 值
若是是輔助平面返回的是高代理位的代碼單元的索引
codePointAt(k) == ch 爲 true 的最大 k 值 而且 k 小於等於 指定的索引
|
lastIndexOf(String)
lastIndexOf(String, int)
|
返回指定 子字符串 在此字符串中最後一次出現處的索引
返回匹配的最後一個
也能夠指定檢索位置,檢索索引的位置也是反向搜索
匹配的含義爲startsWith(str) 爲true
指定了索引就要求返回值 小於等於 指定索引
|