Біз бұл туралы ойланбастан үнемі қолданатын көптеген негізгі әдістер бар. Егер сіз бұл туралы ойланып, қарапайым болып көрінетін әдістердің қалай жүзеге асырылатынын қарастырсаңыз ше? Менің ойымша, бұл бізге Java-ға бір қадам жақындауға көмектеседі) Қандай да бір жолда белгілі бір таңбаны шығару керек жағдайды елестетіп көрейік. Мұны 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
берілген индекс Юниcode ретінде ұсынылса, әдіс нәтижесі java charAt()
осы Юниcodeты көрсететін таңба болады:
System.out.println("J\u0061vaRush".charAt(1));
Консоль шығысы:
a
«Капот астында» деген не
Бұл қалай жұмыс істейді, сіз сұрайсыз ба? Өйткені, әрбір нысанда берілген жолдың элементтерінің byteтары бар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-ден үлкен немесе оған тең екенін және оның ішкі byte массивінен аспайтынын тексеру, ал егер олай болмаса, ерекше жағдай шығарылады 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
, ол екі byteпен (екі жиым ұяшығы) көрсетіледі. Егер бізде екі кириллица таңбасының жолы болса - «av», онда:
- 'a' үшін бұл byte жұбы - 48 және 4;
- «in» үшін - 50 және 4.
value
- {48, 4, 50, 4} Іс жүзінде бұл әдіс екі массив ұяшығымен жұмыс істейді value
. Сондықтан, келесі қадам index <<= 1;
массивтегі қажетті таңбаның бірінші byteының индексіне тікелей өту үшін ауысу болып табылады value
. Енді бізде жол бар делік "абвг"
. Содан кейін мәндер массиві келесідей болады: {48, 4, 49, 4, 50, 4, 51, 4}. Біз жолдың үшінші элементін сұраймыз, содан кейін екілік ұсыну 00000000 00000011. 1-ге жылжытқанда, біз 00000000 00000110 аламыз, яғни index = 6
. Биттік операциялар туралы біліміңізді жаңарту үшін осы мақаланы оқуға болады . Біз сондай-ақ кейбір айнымалыларды көреміз: HI_BYTE_SHIFT
бұл жағдайда ол 0. LO_BYTE_SHIFT
бұл жағдайда ол 8. Бұл әдістің соңғы жолында:
- Элемент мәндер массивінен алынады және
HI_BYTE_SHIFT
көбейту кезінде бит бойынша , яғни 0-ге жылжытыладыindex +1
.Жолы бар мысалда
"абвг"
алтыншы byte - 51 - солай қалады, бірақ сонымен бірге индекс 7-ге дейін артады. - Осыдан кейін массивтің келесі элементі алынады және дәл осылай бит бойынша ауыстырылады, бірақ LO_BYTE_SHIFT арқылы, яғни 8 битке.
Ал егер бізде екілік көрінісі бар 4 byte болса - 00000000 00000100, онда 8 битке жылжытқаннан кейін бізде 00000100 00000000 болады. Егер ол бүтін болса - 1024.
- Әрі қарай, осы екі мән үшін операция орындалады
| (OR)
.Ал егер бізде екілік кескінде 00000000 00110011 және 00000100 00000000 сияқты көрінетін 51 және 1024 byteтары болса, онда операциядан кейін
OR
біз 00000100 00110011 аламыз, бұл ондық жүйедегі 1075 санын білдіреді.Соңында 1075 саны char түріне түрленеді, ал int -> char түрлендіру кезінде ASCII кестесі пайдаланылады және оның ішінде 1075 санының астында 'g' таңбасы болады.
charAt()
Шындығында, Java бағдарламалауындағы әдістің нәтижесі ретінде біз «g» аламыз .
GO TO FULL VERSION