4-bo‘lim
Satrlar bilan ishlash
String o'zgarmasligi, == va equals farqi, satrlar havzasi, asosiy metodlar, StringBuilder, matn bloklari va madaniyatga bog'liq formatlash.
Ushbu bo‘lim mundarijasi
Matn bilan ishlash dasturchining kundalik ishi. Java'da satrlar kuchli, lekin ularda yangi boshlovchilar eng ko'p yiqiladigan tuzoq ham bor.
== va equals - eng muhim qoida #
Shundan boshlaymiz, chunki bu Java'dagi eng ko'p uchraydigan xato.
public class Solishtirish {
public static void main(String[] args) {
String a = "salom";
String b = "salom";
String c = new String("salom");
System.out.println("a == b : " + (a == b));
System.out.println("a == c : " + (a == c));
System.out.println("a.equals(c) : " + a.equals(c));
System.out.println("a == c.intern(): " + (a == c.intern()));
}
}
a == b : true
a == c : false
a.equals(c) : true
a == c.intern(): true
== satrlarni solishtirmaydi== ikkita havola bir xil obyektga ishora qiladimi, degan savolga
javob beradi. U satrlar mazmunini taqqoslamaydi.
Yuqorida a == b rost chiqdi, chunki Java bir xil matnli literallarni
satrlar havzasida (string pool) saqlaydi va qayta ishlatadi -
ikkalasi bitta obyekt.
new String("salom") esa majburan yangi obyekt yaratadi, shuning
uchun a == c yolg'on.
Qoida: satrlarni har doim equals bilan solishtiring.
Bu tuzoq shu bilan xavfliki, kichik dasturda == ko'pincha
"ishlaydi" - hamma satrlar literal bo'lgani uchun. Keyin foydalanuvchi
kiritgan yoki fayldan o'qilgan satr paydo bo'ladi va kod jimgina
noto'g'ri ishlay boshlaydi.
null xavfsiz solishtirishpublic class Xavfsiz {
public static void main(String[] args) {
String kiritilgan = null;
System.out.println("literal birinchi: "
+ "ha".equals(kiritilgan));
System.out.println("Objects bilan: "
+ java.util.Objects.equals(kiritilgan, "ha"));
}
}
literal birinchi: false
Objects bilan: false
kiritilgan.equals("ha") yozsangiz, kiritilgan null bo'lganda
dastur qulaydi. Literalni birinchi qo'ysangiz yoki
Objects.equals ishlatsangiz - xavfsiz.
Satr o'zgarmas #
public class Ozgarmas {
public static void main(String[] args) {
String asl = "salom";
asl.toUpperCase(); // natija tashlab yuborildi
System.out.println("Birinchi: " + asl);
String katta = asl.toUpperCase(); // to'g'ri
System.out.println("Ikkinchi: " + katta + ", asl: " + asl);
}
}
Birinchi: salom
Ikkinchi: SALOM, asl: salom
Java'da satrni tahrirlab bo'lmaydi. Har bir metod yangi satr qaytaradi - uni o'zlashtirmasangiz, hech narsa o'zgarmaydi.
Asosiy metodlar #
public class Metodlar {
public static void main(String[] args) {
String matn = "Namangan viloyati";
System.out.println(matn.length());
System.out.println(matn.toUpperCase());
System.out.println(matn.contains("viloyat"));
System.out.println(matn.startsWith("Naman"));
System.out.println(matn.indexOf("viloyat"));
System.out.println(matn.substring(0, 8));
System.out.println(matn.replace("viloyati", "shahri"));
System.out.println(" bo'shliq ".strip() + "|");
System.out.println("ha".repeat(3));
}
}
17
NAMANGAN VILOYATI
true
true
9
Namangan
Namangan shahri
bo'shliq|
hahaha
| Metod | Vazifasi |
|---|---|
length() | Belgilar soni |
toUpperCase / toLowerCase | Katta / kichik harf |
strip() | Chetlardagi bo'shliqlarni olib tashlaydi |
contains | Ichida bormi |
startsWith / endsWith | Boshlanadimi / tugaydimi |
indexOf | O'rnini topadi, topilmasa -1 |
substring | Bir qismini ajratadi |
replace | Almashtiradi |
split | Bo'laklarga ajratadi |
isBlank() | Bo'sh yoki faqat bo'shliqmi |
repeat(n) | n marta takrorlaydi |
strip() va trim() farqiIkkalasi ham chetlardagi bo'shliqlarni olib tashlaydi, lekin:
trim()- eski metod, faqatU+0020dan kichik belgilarni kesadi;strip()- Java 11 dan, Unicode qoidalari bo'yicha ishlaydi va uzilmas bo'shliq kabi belgilarni ham to'g'ri qirqadi.
Yangi kodda strip() ishlating.
Split va join #
public class Bolish {
public static void main(String[] args) {
String qator = "Namangan,Andijon,Samarqand,Toshkent";
String[] shaharlar = qator.split(",");
System.out.println("Bo'laklar soni: " + shaharlar.length);
for (String shahar : shaharlar) {
System.out.println(" - " + shahar);
}
System.out.println(String.join(" | ", shaharlar));
}
}
Bo'laklar soni: 4
- Namangan
- Andijon
- Samarqand
- Toshkent
Namangan | Andijon | Samarqand | Toshkent
split muntazam ifodani qabul qiladisplit ning argumenti oddiy matn emas, muntazam ifoda (regular
expression). Shuning uchun maxsus belgilar kutilmagan natija beradi:
public class Nuqta {
public static void main(String[] args) {
String sana = "2026.09.11";
System.out.println("Xato: " + sana.split(".").length);
System.out.println("To'g'ri: " + sana.split("\\.").length);
}
}
Xato: 0
To'g'ri: 3
Muntazam ifodada . "istalgan belgi" degani, shuning uchun hamma
narsa ajratuvchi deb qabul qilindi va natija bo'sh bo'lib qoldi.
Ajratuvchi sifatida . | * + ? ( ) [ ] { } \ ^ $ belgilaridan birini
ishlatsangiz, oldiga \ qo'ying.
StringBuilder #
Satr o'zgarmas bo'lgani uchun halqa ichida += qilish har safar yangi
obyekt yaratadi.
public class Quruvchi {
public static void main(String[] args) {
StringBuilder quruvchi = new StringBuilder();
for (int i = 1; i <= 5; i++) {
quruvchi.append(i);
if (i < 5) {
quruvchi.append(" -> ");
}
}
System.out.println(quruvchi.toString());
System.out.println("Uzunligi: " + quruvchi.length());
System.out.println("Teskari: " + quruvchi.reverse());
}
}
1 -> 2 -> 3 -> 4 -> 5
Uzunligi: 21
Teskari: 5 >- 4 >- 3 >- 2 >- 1
-> emas, >- chiqdi?reverse() matnni belgima-belgi teskari qiladi. U -> ni yaxlit
bir belgi deb hisoblamaydi: avval >, keyin - yoziladi.
Xuddi shu sabab qavslarga ham tegishli - (a+b) teskari qilinsa
)b+a( bo'ladi, qavslar almashmaydi.
reverse() ni faqat oddiy matn bilan ishlating; tuzilishi bor
matnda u kutilgan natija bermaydi.
| Holat | Nima ishlatish |
|---|---|
| Bir nechta satrni qo'shish | Oddiy + - kompilyator o'zi optimallashtiradi |
| Halqa ichida, minglab marta | StringBuilder |
| Ro'yxatni birlashtirish | String.join yoki Collectors.joining |
Muhim tafsilot: halqadan tashqarida + ishlatish sekin emas.
Kompilyator "a" + b + "c" ni o'zi StringBuilder ga aylantiradi.
Muammo faqat sikl ichida yuzaga keladi, chunki u yerda har
takrorda yangi quruvchi yaratiladi.
Matn bloklari #
Java 15 dan ko'p qatorli matnni uch qo'shtirnoq bilan yozish mumkin:
public class Blok {
public static void main(String[] args) {
String json = """
{
"ism": "Husanboy",
"shahar": "Namangan"
}""";
System.out.println(json);
}
}
{
"ism": "Husanboy",
"shahar": "Namangan"
}
Qochish belgilari kerak emas. Chekinish yopuvchi """ joyiga qarab
hisoblanadi - shuning uchun JSON chap chekkadan boshlandi.
Formatlash va madaniyat #
import java.util.Locale;
public class Format {
public static void main(String[] args) {
double narx = 1234.5;
System.out.println(String.format(Locale.ROOT, "%.2f", narx));
System.out.println(String.format(Locale.GERMANY, "%.2f", narx));
System.out.println(String.format(Locale.ROOT, "%,.2f", narx));
System.out.println(String.format(Locale.ROOT, "%8s|", "chap"));
System.out.println(String.format(Locale.ROOT, "%-8s|", "o'ng"));
System.out.println(String.format(Locale.ROOT, "%05d", 42));
}
}
1234.50
1234,50
1,234.50
chap|
o'ng |
00042
Yuqorida Locale.ROOT ataylab yozilgan. Usiz String.format
operatsion tizim sozlamasidan foydalanadi.
Ya'ni rus yoki nemis tiliga sozlangan kompyuterda %.2f natijasi
1234,50 bo'lib chiqadi - nuqta o'rniga vergul.
Bu faylga yozganda va tarmoqqa yuborganda haqiqiy muammo tug'diradi: boshqa kompyuter o'sha sonni o'qiy olmaydi yoki noto'g'ri o'qiydi.
Qoida:
- Ekranga chiqarganda - foydalanuvchi madaniyati;
- Faylga, JSON ga, bazaga - har doim
Locale.ROOT.
Bu darslikdagi barcha misollarda sonlar aynan shu sababdan
Locale.ROOT bilan chiqariladi - shunda natija sizning
kompyuteringizda ham xuddi shunday bo'ladi.
Bo'shliq tekshirish #
public class Boshliq {
public static void main(String[] args) {
String bosh = "";
String faqatBoshliq = " ";
String matn = "salom";
System.out.println("isEmpty: " + bosh.isEmpty()
+ ", " + faqatBoshliq.isEmpty());
System.out.println("isBlank: " + bosh.isBlank()
+ ", " + faqatBoshliq.isBlank());
System.out.println("matn: " + matn.isBlank());
}
}
isEmpty: true, false
isBlank: true, true
matn: false
Foydalanuvchi kiritgan ma'lumotni tekshirishda deyarli har doim
isBlank() kerak: probel bosib yuborgan foydalanuvchi ham hech
narsa kiritmagan hisoblanadi.
Belgilar bo'ylab yurish #
public class Belgilar {
public static void main(String[] args) {
String soz = "Namangan";
int unliSoni = 0;
for (char belgi : soz.toCharArray()) {
if ("aeiouAEIOU".indexOf(belgi) >= 0) {
unliSoni++;
}
}
System.out.println("'" + soz + "' so'zida " + unliSoni + " ta unli");
System.out.println("Teskari: "
+ new StringBuilder(soz).reverse());
}
}
'Namangan' so'zida 3 ta unli
Teskari: nagnamaN
- Ikkita bir xil matnli satrni
==vaequalsbilan solishtiring. new String("salom")yaratib, farqni ko'ring.nullbilan xavfsiz solishtirishni sinang.toUpperCasenatijasini o'zlashtirmaslik xatosini takrorlang.split(".")vasplit("\.")natijalarini solishtiring.StringBuilderbilan 1 dan 10 gacha sonlarni birlashtiring.- Matn bloki bilan ko'p qatorli JSON yozing.
- Bir sonni
Locale.ROOTvaLocale.GERMANYda formatlang. isEmptyvaisBlankfarqini tekshiring.- So'zdagi undosh harflar sonini hisoblang.
Xulosa #
- Satrlarni
==bilan solishtirmang - har doimequals. ==rost chiqishi mumkin, chunki bir xil literallar satrlar havzasida qayta ishlatiladi - bu tasodif, qoida emas.nullxavfi bo'lsa literalni birinchi qo'ying yokiObjects.equalsishlating.- Satrlar o'zgarmas: har bir metod yangi satr qaytaradi.
splitmuntazam ifoda qabul qiladi -.uchun\.yozing.- Yangi kodda
strip(),trim()emas. - Halqa ichida minglab marta qo'shsangiz -
StringBuilder. - Matn bloklari (
""") ko'p qatorli matn va JSON uchun. - Sonni formatlaganda
Locale.ROOTni oshkora bering.
Keyingi bo'limda shartlar va switch ni o'rganamiz.
O‘qish tarixini saqlamoqchimisiz?
Tizimga kirsangiz, tugatgan bo‘limlaringiz saqlanadi va qoldirgan joyingizdan davom etasiz.
Xatolik topdingizmi?
Imlo xatosi, ishlamaydigan kod yoki noto‘g‘ri ma‘lumotni ko‘rsangiz - bizga xabar bering. Har bir xabar administrator tomonidan ko‘rib chiqiladi.