Biz bu haqda o'ylamasdan muntazam ravishda ishlatadigan ko'plab asosiy texnikalar mavjud. Xo'sh, agar siz bu haqda o'ylab ko'rsangiz va oddiy ko'rinadigan usullar qanday amalga oshirilayotganiga qarasangiz nima bo'ladi? Menimcha, bu bizga Java-ga bir qadam yaqinlashishga yordam beradi) Keling, qandaydir satrda ma'lum bir belgini ajratib olishimiz kerak bo'lgan vaziyatni tasavvur qilaylik. Buni Java-da qanday qilishimiz mumkin? Masalan, ga qo'ng'iroq qilish orqali
Java String charAt
. Usul haqida bugungi maqolada charAt()
gaplashamiz .
Sintaksis
char charAt(int index)
belgilangan indeksdagi char qiymatini qaytaradi. Indeks 0 dan length()-1
. Ya'ni, massivni indekslashda bo'lgani kabi char
ketma-ketlikning birinchi qiymati -da index 0
, keyingisi -da va hokazo.index 1
Misol
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));
}
Birinchi qator birinchi belgini oladi, ikkinchi qator ikkinchisini oladi va hokazo. Yo'q println
, lekin bu erda ishlatilganligi sababli print
, yangi qatorsiz biz konsolga quyidagi natijani olamiz:
Java
Agar char
berilgan indeks Unicode sifatida taqdim etilgan bo'lsa, usulning natijasi java charAt()
ushbu Unicodeni ifodalovchi belgi bo'ladi:
System.out.println("J\u0061vaRush".charAt(1));
Konsol chiqishi:
a
"Kaput ostida" nima
Bu qanday ishlaydi, deb so'rayapsizmi? Gap shundaki, har bir ob'ektda berilgan satr elementlarining baytlari bo'lganString
massiv mavjud :byte
private final byte[] value;
Va bu usulning o'zi chatAt
:
public char charAt(int index) {
if (isLatin1()) {
return StringLatin1.charAt(value, index);
} else {
return StringUTF16.charAt(value, index);
}
}
isLatin1
- satrimizda faqat lotin belgilar mavjudmi yoki yo'qligini ko'rsatadigan bayroq. Bu keyingi qaysi usul chaqirilishini aniqlaydi.
isLatin1 = rost
Agar satr faqat lotin belgilarni o'z ichiga olsa, statikcharAt
sinf usuli deyiladi StringLatin1
:
public static char charAt(byte[] value, int index) {
if (index < 0 || index >= value.length) {
throw new StringIndexOutOfBoundsException(index);
}
return (char)(value[index] & 0xff);
}
Birinchi qadam, kiruvchi indeksning 0 dan katta yoki teng ekanligini va ichki bayt massividan tashqariga chiqmasligini tekshirish va agar bunday bo'lmasa, istisno chiqariladi new StringIndexOutOfBoundsException(index)
. Agar tekshiruvlar o'tgan bo'lsa, unda bizga kerak bo'lgan element olinadi. Oxirida biz ko'ramiz:
&
ikkilik operatsiya uchunbyte
bit yo'nalishiga qadar kengaytiriladi0xff
&
argument talab qilishdan boshqa hech narsa qilmaydi(char)
ASCII jadvalidan ma'lumotlarni o'zgartiradichar
isLatin1 = noto'g'ri
Agar bizda lotin harflaridan ko'proq bo'lsa, sinfdan foydalaniladiStringUTF16
va uning statik usuli chaqiriladi:
public static char charAt(byte[] value, int index) {
checkIndex(index, value);
return getChar(value, index);
}
Bu o'z navbatida chaqiradi:
public static void checkIndex(int off, byte[] val) {
String.checkIndex(off, length(val));
}
Va u statik usulga vakil qiladi String
:
static void checkIndex(int index, int length) {
if (index < 0 || index >= length) {
throw new StringIndexOutOfBoundsException("index " + index +
", length " + length);
}
}
Bu erda, aslida, indeks haqiqiy yoki yo'qligini tekshirish uchun tekshiriladi: yana, u ijobiy yoki nol bo'ladimi va massiv chegarasidan tashqariga chiqmaganmi. StringUTF16
Ammo usuldagi sinfda charAt
ikkinchi usulni chaqirish yanada qiziqarli bo'ladi:
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));
}
Keling, bu erda nima sodir bo'layotganini tahlil qilishni boshlaylik. Usulning boshida birinchi qadam indeksning haqiqiyligini yana bir tekshirishdir. Keyinchalik nima sodir bo'lishini tushunish uchun siz tushunishingiz kerak: lotin bo'lmagan belgi massivga kirganda value
, u ikki bayt (ikki massiv hujayra) bilan ifodalanadi. Agar bizda ikkita kirillcha belgilar qatori bo'lsa - "av", keyin:
- "a" uchun bu bir juft bayt - 48 va 4;
- "in" uchun - 50 va 4.
value
- {48, 4, 50, 4} Aslida, bu usul ikkita massiv katakchalari bilan ishlaydi value
. Shuning uchun, keyingi qadam index <<= 1;
to'g'ridan-to'g'ri massivdagi kerakli belgining birinchi bayti indeksiga o'tishdir value
. Endi bizda string bor deylik "абвг"
. Keyin qiymatlar massivi quyidagicha ko'rinadi: {48, 4, 49, 4, 50, 4, 51, 4}. Biz satrning uchinchi elementini so'raymiz, keyin ikkilik ko'rinish 00000000 00000011. 1 ga siljitganda biz 00000000 00000110 ni olamiz, ya'ni index = 6
. Bitli operatsiyalar bo'yicha bilimingizni yangilash uchun ushbu maqolani o'qishingiz mumkin . Biz ba'zi o'zgaruvchilarni ham ko'ramiz: HI_BYTE_SHIFT
bu holda u 0. LO_BYTE_SHIFT
bu holda u 8. Ushbu usulning oxirgi qatorida:
- Element qiymatlar massividan olinadi va
HI_BYTE_SHIFT
ortib borayotgan vaqtda , ya'ni 0 ga bit bo'yicha siljiydiindex +1
.Satrli misolda
"абвг"
oltinchi bayt - 51 - shunday bo'lib qoladi, lekin ayni paytda indeks 7 ga oshadi. - Shundan so'ng, massivning keyingi elementi olinadi va xuddi shu tarzda, lekin LO_BYTE_SHIFT orqali, ya'ni 8 bitga o'zgartiriladi.
Va agar bizda ikkilik ko'rinishga ega bo'lgan 4 bayt bo'lsa - 00000000 00000100, keyin 8 bitga siljitgandan so'ng bizda 00000100 00000000 bo'ladi. Agar u butun son bo'lsa - 1024.
- Keyinchalik, ushbu ikki qiymat uchun operatsiya bajariladi
| (OR)
.Va agar bizda ikkilik ko'rinishda 00000000 00110011 va 00000100 00000000 kabi ko'rinadigan 51 va 1024 baytlari bo'lsa, operatsiyadan so'ng
OR
biz 00000100 00110011 ni olamiz, bu o'nlik sistemada 1075 raqamini bildiradi.Oxir-oqibat, 1075 raqami char turiga aylantiriladi va int -> char ni o'zgartirganda, ASCII jadvalidan foydalaniladi va unda 1075 raqami ostida "g" belgisi mavjud.
charAt()
Aslida, Java dasturlashdagi usul natijasida biz "g" ni shunday olamiz .
GO TO FULL VERSION