JavaRush /จาวาบล็อก /Random-TH /วิธีการ charAt() ใน Java

วิธีการ charAt() ใน Java

เผยแพร่ในกลุ่ม
มีเทคนิคพื้นฐานมากมายที่เราใช้เป็นประจำโดยไม่ต้องคิดเลย แล้วถ้าคุณคิดเกี่ยวกับมันและดูว่าวิธีการบางอย่างที่ดูเหมือนง่าย ๆ นั้นถูกนำไปใช้อย่างไร? ฉันคิดว่านี่จะช่วยให้เราเข้าใกล้ Java มากขึ้นอีกขั้นหนึ่ง) charAt() ใน Java - 1ลองจินตนาการถึงสถานการณ์ที่เราจำเป็นต้องแยกอักขระบางตัวออกจากสตริงบางตัว เราจะทำสิ่งนี้ใน Java ได้อย่างไร? เช่น โดยการเรียกJava String charAt. charAt()เราจะพูดถึงวิธีการ ในบทความของวันนี้

ไวยากรณ์

char charAt(int index)ส่งกลับค่าถ่านที่ดัชนีที่ระบุ ดัชนีมีตั้งแต่ 0 length()-1ถึง นั่นคือcharค่าแรกของลำดับอยู่ใน ค่าindex 0ถัดไปอยู่ใน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));
}
บรรทัดแรกใช้อักขระตัวแรก บรรทัดที่สองใช้อักขระตัวที่สอง และต่อๆ ไป เนื่องจากไม่ใช่printlnแต่ ถูกใช้ที่นี่ printหากไม่มีบรรทัดใหม่ เราจะได้ผลลัพธ์ต่อไปนี้ไปยังคอนโซล:

Java
หากcharดัชนีที่กำหนดแสดงเป็น Unicode ผลลัพธ์ของวิธีการjava charAt()จะเป็นอักขระที่แสดงถึง Unicode นี้:
System.out.println("J\u0061vaRush".charAt(1));
เอาต์พุตคอนโซล:

a

"ภายใต้ประทุน" คืออะไร

มันทำงานอย่างไรคุณถาม? charAt() ใน Java - 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 = จริง

หากสตริงมีเพียงอักขระละติน วิธี 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 = เท็จ

หากเราไม่เพียงมีอักขระละตินเท่านั้น คลาสจะถูกใช้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;
  • สำหรับ 'ใน' - 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คือ หากต้องการรีเฟรชความ รู้เกี่ยวกับการดำเนินการระดับบิต คุณสามารถอ่านบทความ นี้ charAt() ใน Java - 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 ถ้าเป็นจำนวนเต็ม - 1,024

  3. ถัดไป สำหรับสองค่านี้ ให้ปฏิบัติตามการดำเนิน| (OR)การ

    และถ้าเรามีไบต์ 51 และ 1,024 ซึ่งในการเป็นตัวแทนไบนารีดูเหมือน 00000000 00110011 และ 00000100 00000000 หลังจากการดำเนินการORเราจะได้รับ 00000100 00110011 ซึ่งหมายถึงตัวเลข 1,075 ในระบบทศนิยม

    ในที่สุดหมายเลข 1,075 จะถูกแปลงเป็นประเภทถ่านและเมื่อแปลง int -> char จะใช้ตาราง ASCII และในนั้นภายใต้หมายเลข 1,075 จะมีอักขระ 'g'

จริงๆ แล้ว นี่คือวิธีที่เราได้รับ 'g' เป็นผลมาจากวิธีการcharAt()ในการเขียนโปรแกรม Java
ความคิดเห็น
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION