1. 程式人生 > >JAVA String方法中public int indexOf(int ch)問題

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>
舉個例子:
<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>
我們總是很習以為常的取用這個函式,傳入一個字元去尋找這個字元首次出現的位置,但是我們仔細的看下JDK的函式宣告public int indexOf(int ch),請注意這裡的函式的區域性引數是資料型別是int,而不是我們認為是char,在JAVA中int型別定義為4個位元組,而char型別定義為2個位元組,雖然我們可以將char 自動轉換為int,但是JDK為什麼不直接宣告為public int indexOf(char ch),這就是我們今天要討論的問題。

  首先JAVA使用的Unicode編碼長度是是4個位元組,也就是說一個int大小為是可以容納一個Unicode的編碼的長度的。Unicode的編碼中第一位元組稱為組,第二位元組稱為面,第三位元組稱為行,第四位元組稱為點。第0

組第0面裡的字元可以只用2個位元組表示,且涵蓋了絕大部分的常用字。為了方便稱呼,Unicode給它了一個名稱——基本多文種平面BMP  Basic Multilingual Plane)。基本多文種平面值域和上域都是0FFFF,共計65535個碼點。並且ASCII中有的字元Unicode中都有,並且對應相同的編碼數字,並不是我們簡單的認為Unicode編碼一個char就可以存下資料。

我們看下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