Asl: “ ” yoki Konstruktor yordamida Java satri yaratilsinmi? X Wang tomonidan Java-da string ikkita usul yordamida yaratilishi mumkin:
String x = "abc";
String y = new String("abc");
Ikkita tirnoqdan foydalanish va konstruktordan foydalanish o'rtasidagi farq nima?
1. Qoʻsh tirnoq va boshqalar. Konstruktor
Bu savolga ikkita oddiy misolni ko'rib chiqish orqali javob berish mumkin. 1-misol:String a = "abcd";
String b = "abcd";
System.out.println(a == b); // True
System.out.println(a.equals(b)); // True
a==b
rost, chunki ularning a
ikkalasi ham b
bir xil ob'ektga ishora qiladi - usul sohasida literal (quyida satr literal) sifatida e'lon qilingan satr (biz o'quvchini manbamizdagi manbaga havola qilamiz: Java-ni tushunish uchun eng yaxshi 8 diagramma, 8-diagramma). Xuddi shu satr literali bir necha marta yaratilganda, satrning faqat bitta nusxasi xotirada saqlanadi, uning bir nusxasi (bizning holimizda "abcd"). Bu "string interning" deb ataladi. Kompilyatsiya vaqtida qayta ishlangan barcha satr konstantalari avtomatik ravishda Java-ga o'rnatiladi. 2-misol:
String c = new String("abcd");
String d = new String("abcd");
System.out.println(c == d); // False
System.out.println(c.equals(d)); // True
c==d
noto'g'ri, chunki c
ular d
xotirada (uyda) ikki xil ob'ektga ishora qiladi. Turli ob'ektlar har doim turli xil havolalarga ega. Ushbu diagramma yuqorida tavsiflangan ikkita holatni ko'rsatadi:
2. Dasturni bajarish bosqichida satrlarni o'rgatish
Muallif LukasEderga minnatdorchilik bildiradi (quyida sharh uniki): String interning ham konstruktorlar yordamida ikkita satr yaratilgan bo'lsa ham, dasturni bajarish paytida sodir bo'lishi mumkin:String c = new String("abcd").intern();
String d = new String("abcd").intern();
System.out.println(c == d); // Now true
System.out.println(c.equals(d)); // True
3. Qachon qo‘sh tirnoq va qachon konstruktorlardan foydalanish kerak
Literal "abcd" har doim String tipida bo'lganligi sababli, konstruktordan foydalanish qo'shimcha keraksiz ob'ektni yaratadi. Shunday qilib, agar siz shunchaki satr yaratishingiz kerak bo'lsa, ikkita tirnoq ishlatilishi kerak. Agar siz haqiqatan ham to'pda yangi ob'ekt yaratishingiz kerak bo'lsa, siz konstruktordan foydalanishingiz kerak. Foydalanish holatlari bu erda ko'rsatilgan (original) . (Men quyida tarjima qilingan matnni taqdim etaman. Lekin baribir ushbu havolada sharhlovchilar kodi bilan tanishib chiqishingizni tavsiya qilaman.)JDK 6 va JDK 7 da substring() usuli
JDK 6 va JDK 7 da substring() usuli X Vang tomonidan JDK 6 va JDK 7 da usulsubstring(int beginIndex, int endIndex)
boshqacha. Ushbu farqlarni bilish ushbu usuldan yaxshiroq foydalanishga yordam beradi. O'qish qulayligi uchun quyida substring()
biz to'liq sintaksisni nazarda tutamiz, ya'ni. substring(int beginIndex, int endIndex)
.
1. Substring() nima qiladi?
Usul belgilar raqami bilan boshlanadigan va belgilar raqami bilan tugaydigansubstring(int beginIndex, int endIndex)
qatorni qaytaradi . beginIndex
endIndex-1
String x = "abcdef";
x = x.substring(1,3);
System.out.println(x);
Chiqish:
bc
2. Substring() chaqirilganda nima sodir bo'ladi?
Siz bilishingiz mumkinki, o'zgarmasligi tufayli xx
ning natijasini belgilashda u butunlay yangi qatorga ishora qiladi (diagrammaga qarang): Biroq, bu diagramma to'liq to'g'ri emas; bu to'pda nima sodir bo'layotganini ko'rsatmaydi. JDK 6 va JDK 7 da chaqirilganda aslida nima sodir bo'ladi . x.substring(1,3)
x
substring()
3. JDK 6 da substring().
String turi massiv turi tomonidan qo'llab-quvvatlanadichar
. JDK 6 da sinf String
3 ta maydonni o'z ichiga oladi: char value[]
, int offset
, int count
. Ular belgilarning haqiqiy massivini, massivdagi birinchi belgi indeksini, qatordagi belgilar sonini saqlash uchun ishlatiladi. Usul chaqirilganda substring()
, u yangi qator yaratadi, lekin o'zgaruvchining qiymati baribir uyumdagi bir xil massivga ishora qiladi. Ikki satr o'rtasidagi farq ularning belgilar soni va massivdagi boshlang'ich belgining indeks qiymatidir. Quyidagi kod soddalashtirilgan va faqat muammoni ko'rsatish uchun asoslarni o'z ichiga oladi.
//JDK 6
String(int offset, int count, char value[]) {
this.value = value;
this.offset = offset;
this.count = count;
}
public String substring(int beginIndex, int endIndex) {
//check boundary
return new String(offset + beginIndex, endIndex - beginIndex, value);
}
4. JDK 6 da substring() tufayli yuzaga kelgan muammo
Agar sizda JUDA uzun satringiz bo'lsa, lekin uning faqat kichik bir qismi kerak bo'lsa, uni har safar ishlatganingizda olasizsubstring()
. Bu bajarish bilan bog'liq muammolarga olib keladi, chunki sizga faqat kichik bir qism kerak bo'ladi, lekin siz hali ham butun satrni saqlashingiz kerak. JDK 6 uchun yechim quyidagi kod bo'lib, u satrni haqiqiy pastki qatorga o'tkazadi:
x = x.substring(x, y) + ""
STepeR foydalanuvchisi savol yaratdi (uning sharhiga qarang) va 4-bandni qo'shish kerak edi. " substring()
JDK 6 da yuzaga kelgan muammo" kengroq misoldir. Umid qilamanki, bu javob bo'ladi va boshqalarga muammo nimada ekanligini tezda aniqlashga yordam beradi. Mana kod:
String a = "aLongLongString";
String b = a.substring(1, 2);
String c = a.substring(2, 6);
b
Shunday qilib , JDK 7 da a с
tipidagi ob'ektda String
usulni chaqirish orqali yaratilgan a substring()
tipidagi String
ob'ektlar to'pdagi ikkita yangi yaratilgan massivlarga havola qiladi - L
for b
, ongL
for c
. Ushbu ikkita yangi massiv a. tomonidan havola qilingan asl massiv bilan birga yig'mada saqlanadi aLongLongString
. Bular. asl massiv hech qaerda yo'qolmaydi. Endi JDK 6 ga qaytaylik. JDK 6 da to'p bitta massivni o'z ichiga oladi aLongLongString
. Kod qatorlarini bajargandan so'ng
String b = a.substring(1, 2);
String c = a.substring(2, 6);
ob'ektlar ob'ektga mos keladigan uyumdagi bir xil massivga b
ishora qiladi : - 1-indeksdan 2-chigacha bo'lgan elementlarga, - 2-indeksdan 6-gacha bo'lgan elementlarga (raqamlash 0 dan boshlanadi, eslatma). Bular. Shubhasiz, JDK 6-dagi o'zgaruvchilar yoki c ga keyingi har qanday kirish aslida asl massivning kerakli elementlarini yig'ishda "hisoblash" ga olib keladi. JDK 7 da o'zgaruvchilarga yoki c ga keyingi har qanday kirish allaqachon yaratilgan va uyada "yashovchi" zarur bo'lgan kichikroq massivlarga kirishga olib keladi. Bular. Shubhasiz, JDK 7 bu kabi holatlarda jismoniy ko'proq xotiradan foydalanadi. Ammo mumkin bo'lgan variantni tasavvur qilaylik: o'zgaruvchining ma'lum pastki satrlari o'zgaruvchilarga tayinlanadi va kelajakda har bir kishi faqat ulardan foydalanadi - ob'ektlar va . Endi hech kim a o‘zgaruvchisiga oddiygina kira olmaydi, unga havolalar yo‘q (maqola muallifi shuni nazarda tutadi). Natijada, bir vaqtning o'zida, axlat yig'uvchi ishga tushiriladi va (eng umumiy shaklda, albatta) biz 2 xil vaziyatga ega bo'lamiz: JDK 6 : ob'ekt yo'q qilinadi (axlat yig'iladi) , LEKIN - asl ulkan uyumdagi massiv tirik; u doimiy ravishda ishlatiladi va . JDK 7: a ob'ekti to'plamdagi asl massiv bilan birga yo'q qilinadi. Bu JDK 6 ning xotira oqishiga olib kelishi mumkin bo'lgan nuqta. c
a
b
c
b
b
b
c
a
b
c
a
b
c
5. JDK 7 da substring().
Usul JDK 7 da takomillashtirilgan. JDK 7 dasubstring()
u aslida uyumda yangi massiv yaratadi.
//JDK 7
public String(char value[], int offset, int count) {
//check boundary
this.value = Arrays.copyOfRange(value, offset, offset + count);
}
public String substring(int beginIndex, int endIndex) {
//check boundary
int subLen = endIndex - beginIndex;
return new String(value, beginIndex, subLen);
}
GO TO FULL VERSION