JavaRush /Java Blog /Random-TW /Java 中的 charAt() 方法

Java 中的 charAt() 方法

在 Random-TW 群組發布
有許多基本技術我們經常使用,甚至不假思索。那麼,如果你想一想,看看一些看似簡單的方法是如何實現的呢?我認為這將幫助我們更接近Java一步) Java 中的 charAt() - 1讓我們想像一種情況,我們需要提取某個字串中的某個字元。我們如何在 Java 中做到這一點?例如,透過調用Java String charAt. charAt()我們將在今天的文章中討論該方法。

句法

char charAt(int index)傳回指定索引處的 char 值。索引範圍從 0 到length()-1。也就是說,char序列的第一個值是 in index 0,下一個值是 in ,index 1等等,就像陣列索引的情況一樣。

例子

public static void main(String[] args) {
   System.out.print("JavaRush".charAt(0));
   System.out.print("JavaRush".charAt(1));
   System.out.print("JavaRush".charAt(2));
   System.out.print("JavaRush".charAt(3));
}
第一行採用第一個字符,第二行採用第二個字符,依此類推。由於這裡使用了 not println, but print,沒有換行,我們將在控制台得到以下輸出:

Java
如果char給定索引表示為 Unicode,則該方法的結果java charAt()將是表示該 Unicode 的字元:
System.out.println("J\u0061vaRush".charAt(1));
控制台輸出:

a

什麼是“引擎蓋下”

你問它是如何運作的?Java 中的 charAt() - 2事實上,每個物件都String包含一個數組byte,其中包含給定字串的元素位元組:
private final byte[] value;
這是方法本身chatAt
public char charAt(int index) {
   if (isLatin1()) {
       return StringLatin1.charAt(value, index);
   } else {
       return StringUTF16.charAt(value, index);
   }
}
isLatin1- 一個標誌,指示我們的字串是否僅包含拉丁字元。這決定了接下來要呼叫哪個方法。

isLatin1 = true

如果字串僅包含拉丁字符,則呼叫靜態charAt類別方法StringLatin1
public static char charAt(byte[] value, int index) {
   if (index < 0 || index >= value.length) {
       throw new StringIndexOutOfBoundsException(index);
   }
   return (char)(value[index] & 0xff);
}
第一步是檢查傳入的索引是否大於或等於0,並且沒有超出內部位元組數組,如果不是,則拋出異常new StringIndexOutOfBoundsException(index)。如果檢查通過,那麼我們需要的元素就會被獲取。最後我們看到:
  • &將二進位運算擴展為byte位元運算
  • 0xff什麼都不做,但&需要一個參數
  • (char)將資料從 ASCII 表轉換為char

isLatin1 = false

如果我們不僅僅有拉丁字符,則將使用該類別StringUTF16並調用其靜態方法:
public static char charAt(byte[] value, int index) {
   checkIndex(index, value);
   return getChar(value, index);
}
這又調用:
public static void checkIndex(int off, byte[] val) {
   String.checkIndex(off, length(val));
}
他委託靜態方法String
static void checkIndex(int index, int length) {
   if (index < 0 || index >= length) {
       throw new StringIndexOutOfBoundsException("index " + index +
                                                 ", length " + length);
   }
}
實際上,這裡會檢查索引是否有效:再次檢查它是正數還是零,以及它是否沒有超出數組的限制。但在類別中StringUTF16的一個方法中,charAt呼叫第二個方法會更有趣:
static char getChar(byte[] val, int index) {
   assert index >= 0 && index < length(val) : "Trusted caller missed bounds check";
   index <<= 1;
   return (char)(((val[index++] & 0xff) << HI_BYTE_SHIFT) |
                 ((val[index]   & 0xff) << LO_BYTE_SHIFT));
}
讓我們開始分析這裡實際發生的情況。這個方法開始的第一步是再次檢查索引的有效性。要了解接下來會發生什麼,您需要了解:當非拉丁字元進入陣列時value,它由兩個位元組(兩個陣列單元)表示。如果我們有一個由兩個西里爾字母“av”組成的字串,那麼:
  • 對於“a”,這是一對位元組 - 48 和 4;
  • 對於 'in' - 50 和 4。
也就是說,如果我們創建字串“av”,它將有一個數組value- {48, 4, 50, 4} 實際上,此方法適用於兩個數組單元value。因此,下一步是index <<= 1;直接取得數組中所需字元的第一個位元組的索引value。現在假設我們有一個字串"абвг"。則數值數組將如下所示:{48, 4, 49, 4, 50, 4, 51, 4}。我們要求字串的第三個元素,那麼二進位表示為 00000000 00000011。移位 1 後,我們得到 00000000 00000110,即index = 6。要刷新您有關位元運算的知識,您可以閱讀這篇文章Java 中的 charAt() - 4我們也看到一些變數: HI_BYTE_SHIFT 在本例中為 0。 LO_BYTE_SHIFT在本例中為 8。在此方法的最後一行:在此方法的最後一行:
  1. 從值數組中取出一個元素,按位移動HI_BYTE_SHIFT,即 0,同時增加index +1

    在字串 的範例中"абвг",第六個位元組 - 51 - 將保持不變,但同時索引增加到 7。

  2. 此後,以相同的方式取得陣列的下一個元素並按位移位,但移位量為 LO_BYTE_SHIFT,即 8 位元。

    如果我們有位元組 4,它具有二進位表示形式 - 00000000 00000100,那麼移位 8 位元後我們將得到 00000100 00000000。如果它是整數 - 1024。

  3. 接下來,對於這兩個值,進行操作| (OR)

    如果我們有位元組 51 和 1024,在二進位表示中看起來像 00000000 00110011 和 00000100 000000000,那麼在運算之後OR我們將得到 00000100 00110011,這意味著十進制中的數字 1075。

    好吧,最後,數字1075被轉換為char類型,而在轉換int -> char時,使用了ASCII表,在其中,數字1075的下面,有字元'g'。

實際上,這就是我們在 Java 程式設計中獲得“g”作為方法結果的方式charAt()
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION