JAVA String方法中public int indexOf(int ch)問題
在JAVA中返回一個字元在字串的位置首次出現的位置時候,String 給我們提供幾個有效的API。
舉個例子:<span style="font-family:SimSun;font-size:18px;"> int indexOf(int ch) //返回指定字元在此字串中第一次出現處的索引。 int indexOf(int ch, int fromIndex) //返回在此字串中第一次出現指定字元處的索引,從指定的索引開始搜尋。 int indexOf(String str) //返回指定子字串在此字串中第一次出現處的索引。 int indexOf(String str, int fromIndex) //返回指定子字串在此字串中第一次出現處的索引,從指定的索引開始。</span>
我們總是很習以為常的取用這個函式,傳入一個字元去尋找這個字元首次出現的位置,但是我們仔細的看下JDK的函式宣告public int indexOf(int ch),請注意這裡的函式的區域性引數是資料型別是int,而不是我們認為是char,在JAVA中int型別定義為4個位元組,而char型別定義為2個位元組,雖然我們可以將char 自動轉換為int,但是JDK為什麼不直接宣告為public int indexOf(char ch),這就是我們今天要討論的問題。<span style="font-family:SimSun;font-size:18px;">class Demo1 { public static void main(String[] args){ System.out.println("hello world".indexOf('l')); //返回值為2 System.out.println("hello world".indexOf('o',5)); //返回值為7 } }</span><span style="font-family:SimSun;font-size:24px;"> </span>
首先JAVA使用的Unicode編碼長度是是4個位元組,也就是說一個int大小為是可以容納一個Unicode的編碼的長度的。Unicode的編碼中第一位元組稱為組,第二位元組稱為面,第三位元組稱為行,第四位元組稱為點。第0
我們看下String的indexOf(int ch)的原始碼:
<span style="font-family:SimSun;font-size:18px;"> public int indexOf(int ch, int fromIndex) {
final int max = value.length;
if (fromIndex < 0) {
fromIndex = 0;
} else if (fromIndex >= max) {
// Note: fromIndex might be near -1>>>1.
return -1;
}
if (ch < Character.MIN_SUPPLEMENTARY_CODE_POINT) {
// handle most cases here (ch is a BMP code point or a
// negative value (invalid code point))
final char[] value = this.value;
for (int i = fromIndex; i < max; i++) {
if (value[i] == ch) {
return i;
}
}
return -1;
} else {
return indexOfSupplementary(ch, fromIndex);
}
}</span>
@param ch character (Unicode code point) 引數ch 是一個Unicode的程式碼點
什麼是程式碼點?程式碼點 Code Point:與一個Unicode編碼表中的某個字元對應的程式碼值。Java中用char來表示Unicode字元,由於剛開始Unicode最多使用16bit表示。因此char能夠表示全部的Unicode字元。後來由於Unicode4.0規定Unicode支援的字元遠遠超過65536個字元。因此char現在不能表示所有的unicode字元。僅僅能表示0x000000到0x00FFFF(00 代表的就是拉丁文及其符號)之間的字元。也就是說,char不能表示增補字元。
Java中用int表示所有Unicode程式碼點。int的21個低位(最低有效位)用於表示Unicode程式碼點,並且11個高位(最高有效位)必須為零。也就是說,int能表示出char不能表示的增補字元。我們還可以看到,indexOf()有一個if{}else{}語句當超過Unicode的程式碼補充範圍時候,就會呼叫indexOfSupplementartary()方法。他是處理超過範圍的問題的。這裡其實我們就可以記住indexOf(int ch)其實是傳入的Unicode的程式碼點,不是傳入的真正的字元,而且Java中的程式碼點是用32為資料表示的,因次是用int而不是char