Көптөгөн негизги ыкмалар бар, алар жөнүндө ойлонбостон дайыма колдонобуз. Эгер сиз бул жөнүндө ойлонуп, жөнөкөй көрүнгөн ыкмалар кантип ишке ашырылып жатканын карасаңызчы? Менимче, бул бизге Javaга бир кадам жакындашыбызга жардам берет) Келгиле, кандайдыр бир сапта белгилүү бир символду чыгарып алышыбыз керек болгон кырдаалды элестетип көрөлү. Муну Javaда кантип кылсак болот? Мисалы, чакыруу менен
Java String charAt
. Метод жөнүндө charAt()
биз бүгүнкү макалада сүйлөшөбүз .
Синтаксис
char charAt(int index)
белгиленген индекс боюнча char маанисин кайтарат. Индекс 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
"Капоттун астында" деген эмне
Кантип иштейт, сиз сурайсызбы? Чындыгында, ар бир an object берилген саптын элементтеринин 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
&
аргумент талап кылуудан башка эч нерсе кылbyte(char)
маалыматтарды ASCII tableсына айлантат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
. Биттик операциялар боюнча бorмиңизди жаңыртуу үчүн, сиз бул макаланы окуй аласыз . Кээ бир өзгөрмөлөрдү да көрөбүз: HI_BYTE_SHIFT
бул учурда 0. LO_BYTE_SHIFT
бул учурда 8. Бул ыкманын акыркы сабында:
- Элемент маани массивинен алынып,
HI_BYTE_SHIFT
көбөйүү учурунда битке жылдырылат, башкача айтканда, 0index +1
.сап менен мисалда
"абвг"
алтынчы byte - 51 - ошол бойдон калат, бирок ошол эле учурда индекс 7ге чейин көбөйөт. - Андан кийин, массивдин кийинки элементи алынат жана бит боюнча ушундай эле жол менен, бирок LO_BYTE_SHIFT, башкача айтканда, 8 битке жылдырылат.
Ал эми бизде бинардык өкүлчүлүгү бар 4 byte болсо - 00000000 00000100, анда 8 битке жылгандан кийин 00000100 00000000 болот. Эгерде ал бүтүн сан болсо - 1024.
- Андан кийин, бул эки маани үчүн операция аткарылат
| (OR)
.Ал эми бизде экorк көрсөтүүдө 00000000 00110011 жана 00000100 00000000 сыяктуу көрүнгөн 51 жана 1024 byteтарыбыз болсо, операциядан кийин
OR
биз 00000100 00110011 алабыз, бул ондук системадагы 1075 дегенди билдирет.Ошентип, акырында 1075 саны char түрүнө которулат, ал эми int -> char түрлөтүүдө ASCII tableсы колдонулат жана анда 1075 санынын астында "g" символу бар.
charAt()
Чынында, биз Java программалоодогу ыкманын натыйжасында "g" ды ушундайча алабыз .
GO TO FULL VERSION