JavaRush /Java blogi /Random-UZ /Java tilidagi satrlar (java.lang.String sinfi)
Viacheslav
Daraja

Java tilidagi satrlar (java.lang.String sinfi)

Guruhda nashr etilgan

Kirish

Dasturchining yo'li murakkab va uzoq jarayondir. Va ko'p hollarda ekranda Hello World-ni ko'rsatadigan dastur bilan boshlanadi. Java ham bundan mustasno emas (Qarang: Dars: “Salom dunyo!” Ilovasi ). Ko'rib turganimizdek, xabar System.out.println("Hello World!"); Java API yordamida chiqariladi, System.out.println usuli kirish parametri sifatida String ni oladi . Ushbu turdagi ma'lumotlar muhokama qilinadi.

Belgilar ketma-ketligi sifatida string

Aslida, ingliz tilidan tarjima qilingan String - bu string. To'g'ri, String turi matn qatorini ifodalaydi. Matn qatori nima? Matn qatori - bu bir-biridan keyin keladigan belgilarning tartiblangan ketma-ketligi. Belgisi - char. Ketma-ketlik - ketma-ketlik. Shunday qilib, ha, mutlaqo to'g'ri, String - bu amalga oshirish java.lang.CharSequence. Va agar siz String sinfining o'ziga qarasangiz, unda belgilar qatoridan boshqa narsa yo'q: u juda oddiy shartnomaga private final char value[]; ega :java.lang.CharSequence
Java tilidagi satrlar (java.lang.String sinfi) - 1
Bizda elementlar sonini olish, ma'lum bir elementni olish va elementlar to'plamini olish + toString usulining o'zi bor, bu buni qaytaradi) Java 8 da bizga kelgan usullarni tushunish qiziqroq va bu : chars()va codePoints() Oracle qoʻllanmasidan eslab koʻring “ Primitive Data” Types bu char single 16-bit Unicode character. Yaʼni, char 0 dan 65535 gacha boʻlgan raqamlarni ifodalovchi int ning yarmi oʻlchamidagi (32 bit) tipdir (oʻnlik kasr qiymatlariga qarang). ASCII jadvalida ) . Ya'ni, agar xohlasak, charni int sifatida ifodalashimiz mumkin. Java 8 esa bundan foydalandi. Java-ning 8-versiyasidan boshlab bizda IntStream - ibtidoiy ints bilan ishlash uchun oqim mavjud. Shuning uchun, charSequence-da belgilar yoki kod nuqtalarini ifodalovchi IntStreamni olish mumkin. Ularga o'tishdan oldin, biz ushbu yondashuvning qulayligini ko'rsatish uchun misolni ko'rib chiqamiz. Keling, Tutorialspoint onlayn java kompilyatoridan foydalanamiz va kodni bajaramiz:
public static void main(String []args){
        String line = "aaabccdddc";
        System.out.println( line.chars().distinct().count() );
}
Endi siz ushbu oddiy usulda bir qator noyob belgilarni olishingiz mumkin.

CodePoints

Shunday qilib, biz belgilar haqida ko'rdik. Endi bu qanday kod nuqtalari ekanligi aniq emas. CodePoint kontseptsiyasi paydo bo'ldi, chunki Java paydo bo'lganda, belgini kodlash uchun 16 bit (yarim int) etarli edi. Shuning uchun java'dagi char UTF-16 formatida ("Unicode 88" spetsifikatsiyasi) taqdim etiladi. Keyinchalik Unicode 2.0 paydo bo'ldi, uning kontseptsiyasi xarakterni surrogat juftlik (2 ta belgi) sifatida ifodalashdan iborat edi. Bu bizga mumkin bo'lgan qiymatlar diapazonini int qiymatiga kengaytirishga imkon berdi. Batafsil ma'lumot uchun stackoverflow ga qarang: " Charni kod nuqtasi bilan solishtirasizmi? " UTF-16, shuningdek, belgilar uchun JavaDoc da eslatib o'tilgan . U erda JavaDoc da shunday deyilgan: In this representation, supplementary characters are represented as a pair of char values, the first from the high-surrogates range, (\uD800-\uDBFF), the second from the low-surrogates range (\uDC00-\uDFFF). Buni standart alifbolarda ko'paytirish juda qiyin (va hatto imkonsizdir). Lekin belgilar harflar va raqamlar bilan tugamaydi. Yaponiyada ular emoji sifatida kodlash juda qiyin narsa - ideogrammalar va kulgichlar tilini o'ylab topishdi. Vikipediyada bu haqda qiziqarli maqola bor: “ Emoji ”. Keling, emoji misolini topamiz, masalan: “ Emoji Ghost ”. Ko'rib turganimizdek, xuddi shu kod nuqtasi hatto u erda ham ko'rsatilgan (qiymat = U+1F47B). U o'n oltilik formatda ko'rsatilgan. Agar biz o'nlik songa aylantirsak, biz 128123 ni olamiz. Bu 16 bitdan ko'proq ruxsat beradi (ya'ni 65535 dan ortiq). Keling, uni nusxalashtiramiz:
Java tilidagi satrlar (java.lang.String sinfi) - 2
Afsuski, JavaRush platformasi matndagi bunday belgilarni qo'llab-quvvatlamaydi. Shuning uchun, quyidagi misolda siz Stringga qiymat kiritishingiz kerak bo'ladi. Shunday qilib, endi biz oddiy testni tushunamiz:
public static void main(String []args){
	    String emojiString = "Вставте сюда эмоджи через ctrl+v";
	    //На один emojiString приходится 2 чара (т.к. не влезает в 16 бит)
	    System.out.println(emojiString.codePoints().count()); //1
	    System.out.println(emojiString.chars().count()); //2
}
Ko'rib turganingizdek, bu holda 1 codePoint 2 ta belgi uchun ketadi. Bu sehr.

Xarakter

Yuqorida ko'rganimizdek, Java tilidagi strings chardan iborat. Ibtidoiy tip sizga qiymatni saqlashga imkon beradi, lekin java.lang.Characteribtidoiy turdagi o'ram bu belgi bilan juda ko'p foydali narsalarni qilish imkonini beradi. Masalan, biz satrni katta harfga o'zgartirishimiz mumkin:
public static void main(String[] args) {
    String line = "организация объединённых наций";
    char[] chars = line.toCharArray();
    for (int i = 0; i < chars.length; i++) {
        if (i == 0 || chars[i - 1] == ' ') {
            chars[i] = Character.toUpperCase(chars[i]);
        }
    }
    System.out.println(new String(chars));
}
Xo'sh, turli xil qiziqarli narsalar: isAlphabetic(), isLetter(), isSpaceChar(), isDigit(), isUpperCase(), isMirrored()(masalan, qavslar. '(' oyna tasviriga ega ')').

String hovuzi

Java tilidagi satrlar o'zgarmas, ya'ni doimiydir. Bu java.lang.String sinfining JavaDoc faylida ham ko'rsatilgan . Ikkinchidan, shuningdek, juda muhim, satrlarni literal sifatida ko'rsatish mumkin:
String literalString = "Hello, World!";
String literalString = "Hello, World!";
Ya'ni, yuqorida aytib o'tilganidek, har qanday tirnoqli satr aslida ob'ektdir. Va bu savol tug'iladi - agar biz satrlardan tez-tez foydalansak va ular ko'pincha bir xil bo'lishi mumkin bo'lsa (masalan, "Xato" yoki "Muvaffaqiyatli" matni), satrlar har safar yaratilmasligiga ishonch hosil qilishning biron bir usuli bormi? Aytgancha, bizda hali ham Xaritalar mavjud, bu erda kalit satr bo'lishi mumkin. Shunda biz, albatta, bir xil satrlar turli ob'ektlar bo'lishi mumkin emas, aks holda biz xaritadan ob'ektni ololmaymiz. Java dasturchilari o'ylashdi, o'ylashdi va String Poolni o'ylab topishdi. Bu satrlar saqlanadigan joy, siz uni simli kesh deb atashingiz mumkin. U erda hamma qatorlar tugamaydi, faqat kodda literal bilan belgilangan satrlargina tugaydi. Hovuzga o'zingiz chiziq qo'shishingiz mumkin, ammo keyinroq bu haqda ko'proq ma'lumotga ega bo'lasiz. Shunday qilib, xotirada bizda bu kesh bor. Adolatli savol: bu basseyn qayerda joylashgan? Bunga javobni stackoverflow da topish mumkin: “ Java ning String doimiy hovuzi qayerda yashaydi, to'p yoki stek? " U Heap xotirasida, maxsus ish vaqti doimiy hovuz hududida joylashgan. Runtime doimiy puli virtual mashina tomonidan metod maydonidan - Java Virtual Mashina ichidagi barcha oqimlar kirish huquqiga ega bo'lgan Heap-ning maxsus maydonidan sinf yoki interfeys yaratilganda ajratiladi . String pool bizga nima beradi? Bu bir qator afzalliklarga ega:
  • Xuddi shu turdagi ob'ektlar yaratilmaydi
  • Malumot bo'yicha taqqoslash, tenglar orqali belgilarma-belgilarni taqqoslashdan tezroq
Ammo yaratilgan ob'ektni ushbu keshga joylashtirmoqchi bo'lsak-chi? Keyin, bizda maxsus usul mavjud: String.intern Bu usul String Poolga string qo'shadi. Shuni ta'kidlash kerakki, bu shunchaki massiv ko'rinishidagi kesh turi emas (Integers uchun). Stajyorlik usuli "mahalliy" deb belgilangan. Bu usulning o'zi boshqa tilda (asosan C++) amalga oshirilganligini bildiradi. Asosiy Java usullari bo'lsa, ularga JVM darajasida turli xil optimallashtirishlar qo'llanilishi mumkin. Umuman olganda, sehr bu erda sodir bo'ladi. Stajyor haqidagi quyidagi postni o'qish qiziq: https://habr.com/post/79913/#comment_2345814 Va bu yaxshi fikrga o'xshaydi. Ammo bu bizga qanday ta'sir qiladi? Lekin bu haqiqatan ham ta'sir qiladi)
public static void main(String[] args) {
    String test = "literal";
    String test2 = new String("literal");
    System.out.println(test == test2);
}
Ko'rib turganingizdek, chiziqlar bir xil, ammo natija noto'g'ri bo'ladi. Va barchasi, chunki == qiymat bo'yicha emas, balki mos yozuvlar bo'yicha taqqoslaydi. Va bu shunday ishlaydi:
public static void main(String[] args) {
    String test = "literal";
    String test2 = new String("literal").intern();
    System.out.println(test == test2);
}
Shuni yodda tutingki, biz hali ham yangi String qilamiz. Ya'ni, stajyor bizga keshdan Stringni qaytaradi, lekin biz keshda qidirgan asl String tozalash uchun tashqariga tashlanadi, chunki u haqida boshqa hech kim bilmaydi. Bu aniq resurslarning keraksiz iste'moli =( Shuning uchun, imkon qadar to'satdan va aniqlash qiyin bo'lgan xatolarga yo'l qo'ymaslik uchun har doim tenglardan foydalangan holda satrlarni solishtirishingiz kerak.
public static void main(String[] args) {
    String test = "literal";
    String test2 = new String("literal").intern();
    System.out.println(test.equals(test2));
}
Equals belgilar qatorini taqqoslashni amalga oshiradi.

Birlashtirish

Biz eslaganimizdek, chiziqlar qo'shilishi mumkin. Va biz eslaganimizdek, bizning satrlarimiz o'zgarmasdir. Xo'sh, u qanday ishlaydi? To'g'ri, yangi qator yaratiladi, u qo'shilayotgan ob'ektlarning belgilaridan iborat. Plyus birlashtirish qanday ishlashining millionlab versiyalari mavjud. Ba'zilar har safar yangi ob'ekt paydo bo'ladi deb o'ylashadi, boshqalari esa boshqa narsa bo'ladi deb o'ylashadi. Ammo faqat bitta odam haq bo'lishi mumkin. Va kimdir javac kompilyatoridir. Keling, onlayn kompilyator xizmatidan foydalanamiz va ishga tushiramiz:
public class HelloWorld {

    public static void main(String[] args) {
        String helloMessage = "Hello, ";
        String target = "World";
        System.out.println(helloMessage + target);
    }

}
Keling, buni zip arxivi sifatida saqlaymiz, uni katalogga chiqaramiz va bajaramiz: javap –c HelloWorld Va bu erda biz hamma narsani bilib olamiz:
Java tilidagi satrlar (java.lang.String sinfi) - 3
Loopda, albatta, StringBuilder orqali birlashtirishni o'zingiz amalga oshirgan ma'qul. Va qandaydir sehr tufayli emas, balki StringBuilder tsikldan oldin yaratilishi va tsiklning o'zida faqat qo'shimchalar paydo bo'lishi uchun. Aytgancha, bu erda yana bir qiziq narsa bor. Ajoyib maqola bor: “ Java-da string ishlov berish. I qism: String, StringBuffer, StringBuilder ." Izohlarda juda ko'p foydali ma'lumotlar. new StringBuilder().append()...toString()Masalan, ko'rinishni birlashtirishda ichki optimallashtirish amalda bo'lishi ko'rsatilgan , bu sukut bo'yicha yoqilgan -XX:+OptimizeStringConcat opsiyasi bilan tartibga solinadi. ichki - "ichki" deb tarjima qilingan. JVM bunday narsalarni maxsus usulda boshqaradi, ularni Native sifatida qayta ishlaydi, faqat JNIning qo'shimcha xarajatlarisiz. Batafsil o'qing: " HotSpot VM dagi ichki usullar ".

StringBuilder va StringBuffer

Yuqorida ko'rganimizdek, StringBuilder juda foydali vositadir. Satrlar o'zgarmasdir, ya'ni. o'zgarmas. Va men uni katlamoqchiman. Shuning uchun bizga yordam berish uchun 2 ta dars beriladi: StringBuilder va StringBuffer. Ikkala o'rtasidagi asosiy farq shundaki, StringBuffer JDK1.0 da joriy qilingan, StringBuilder esa java 1.5 da StringBuffer ning sinxronlashtirilmagan versiyasi sifatida kelgan, bu keraksiz usul sinxronizatsiyasining ortib borayotgan qo'shimcha xarajatlarini bartaraf etish uchun. Bu sinflarning ikkalasi ham AbstractStringBuilder mavhum sinfining amalga oshirilishi - belgilarning o'zgaruvchan ketma-ketligi. Ichkarida jozibalar majmuasi saqlanadi, ular qoida bo'yicha kengaytiriladi: value.length * 2 + 2. Odatiy bo'lib, StringBuilder hajmi (sig'imi) 16 ga teng.

Taqqoslash mumkin

Satrlar solishtirish mumkin, ya'ni. compareTo usulini qo'llang. Bu belgi-belgilarni taqqoslash yordamida amalga oshiriladi. Qizig'i shundaki, minimal uzunlik ikkita satrdan tanlanadi va uning ustida pastadir bajariladi. Shuning uchun, compareTo birinchi mos kelmaydigan belgilarning int qiymatlari orasidagi farqni eng kichik satr uzunligigacha qaytaradi yoki agar barcha belgilar minimal satr uzunligi ichida mos kelsa, satr uzunliklari orasidagi farqni qaytaradi. Bu taqqoslash "leksikografik" deb ataladi.

Java satrlari bilan ishlash

String juda ko'p foydali usullarga ega:
Java tilidagi satrlar (java.lang.String sinfi) - 4
Satrlar bilan ishlash uchun ko'plab vazifalar mavjud. Masalan, Coding Bat -da . Shuningdek, kurslar bo'yicha kurs mavjud: " Stringlardagi algoritmlar ".

Xulosa

Hatto ushbu sinfning qisqacha sharhi ham ta'sirchan joy egallaydi. Va bu hammasi emas. Men JPoint 2015 hisobotini tomosha qilishni tavsiya qilaman: Aleksey Shipilev - Catechism java.lang.String
#Viacheslav
Izohlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION