Түпнуска: “ ” же Конструкторду колдонуп Java сапын түзөсүзбү? X Wang тарабынан Javaда сап эки ыкманы колдонуу менен түзүлүшү мүмкүн:
String x = "abc";
String y = new String("abc");
Кош тырмакчаларды колдонуу менен конструкторду колдонуунун ортосунда кандай айырма бар?
1. Кош тырмакчалар vs. Конструктор
Бул суроого эки жөнөкөй мисалды карап жооп берүүгө болот. 1-мисал:String a = "abcd";
String b = "abcd";
System.out.println(a == b); // True
System.out.println(a.equals(b)); // True
a==b
чын, анткени алар a
экөө тең b
бир an objectке - метод аймагында литерал (төмөндө литерал сап) катары жарыяланган сапка тиешелүү (биз окурманды биздин ресурсубуздагы булакка кайрылабыз: Java түшүнүү үчүн мыкты 8 диаграмма , 8-диаграмма). Бир эле сап литералы бир нече жолу түзүлгөндө, саптын бир гана көчүрмөсү эстутумда сакталат, анын бир гана нускасы (биздин учурда "abcd"). Бул "сап интернинг" деп аталат. Компиляция убагында иштетилген бардык сап константалары автоматтык түрдө Java-да интернацияланат. 2-мисал:
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
false, анткени c
алар d
эс тутумдагы эки башка an objectке (үймөктө) кайрылышат. Ар кандай an objectилерде ар дайым ар кандай шилтемелер бар. Бул диаграмма жогоруда сүрөттөлгөн эки жагдайды көрсөтөт:
2. Программаны аткаруу стадиясында саптарды практикалоо
Author LukasEderге ыраазычылык билдирет (төмөнкү комментарий анын): Стринг интернинги программаны аткаруу учурунда да болушу мүмкүн, ал тургай конструкторлор аркылуу эки сап түзүлсө да: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. Кош тырмакчаларды качан колдонуу керек жана конструкторлорду качан колдонуу керек
Литералдык "abcd" ар дайым String тибинде болгондуктан, конструкторду колдонуу кошумча керексиз an objectти түзөт. Ошентип, сиз жөн гана сап түзүшүңүз керек болсо, кош тырмакчалар колдонулушу керек. Эгер чындыгында үймөктө жаңы an object түзүшүңүз керек болсо, конструкторду колдонушуңуз керек. Колдонуу учурлары бул жерде көрсөтүлгөн (оригинал) . (Төмөндө которулган текстти берем. Бирок мен дагы эле бул шилтеме боюнча комментаторлордун codeу менен таанышууну сунуштайм.)JDK 6 жана JDK 7де substring() ыкмасы
JDK 6 жана JDK 7деги substring() методу By X Wang JDK 6 жана JDK 7деги ыкмаsubstring(int beginIndex, int endIndex)
башкача. Бул айырмачылыктарды билүү бул ыкманы жакшыраак колдонууга жардам берет. Окууну жеңилдетүү үчүн төмөндө substring()
биз толук синтаксисти билдиребиз, б.а. substring(int beginIndex, int endIndex)
.
1. Substring() эмне кылат?
Метод символдун номери менен башталып , символдун саны менен аяктаганsubstring(int beginIndex, int endIndex)
сапты кайтарат . beginIndex
endIndex-1
String x = "abcdef";
x = x.substring(1,3);
System.out.println(x);
Чыгуу:
bc
2. Substring() чакырылганда эмне болот?
x
Сиз өзгөрүлбөстүгүнөн улам , x натыйжасын дайындоодо x.substring(1,3)
, x
ал таптакыр жаңы сапты көрсөтөөрүн билесиз (диаграмманы караңыз): Бирок, бул диаграмма толук туура эмес; ал үймөктө эмне болуп жатканын көрсөтпөйт. substring()
JDK 6 жана JDK 7де чакырганда иш жүзүндө эмне болот .
3. JDK 6дагы substring()
Сап түрү массив түрү тарабынан колдоого алынатchar
. JDK 6да класс String
3 талааны камтыйт: char value[]
, int offset
, int count
. Алар символдордун чыныгы массивин, массивдеги биринчи символдун индексин, саптагы символдордун санын сактоо үчүн колдонулат. Метод чакырылганда substring()
, ал жаңы сапты түзөт, бирок өзгөрмөнүн мааниси дагы эле үймөктөгү ошол эле массивди көрсөтөт. Эки саптын ортосундагы айырма алардын символдорунун саны жана массивдеги башталгыч символдун индексинин мааниси. Төмөндөгү code жөнөкөйлөштүрүлгөн жана көйгөйдү көрсөтүү үчүн гана негиздерин камтыйт.
//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дагы substring() тарабынан келип чыккан көйгөй
Эгерде сизде ӨТӨ узун сап болсо, бирок сизге анын кичинекей бөлүгү гана керек, аны ар дайым колдонгон сайын аласызsubstring()
. Бул аткаруу көйгөйлөрүн жаратат, анткени сизге кичинекей гана бөлүк керек, бирок сиз дагы эле бүт сапты сакташыңыз керек. JDK 6 үчүн чечим төмөнкү code болуп саналат, ал сапты чыныгы субсапка чыгарат:
x = x.substring(x, y) + ""
STepeR колдонуучусу суроо түздү (анын комментарийин караңыз) жана 4-пунктту кошуу зарыл болуп көрүндү. " substring()
JDK 6да пайда болгон көйгөй" - бул кеңири мисал. Бул жооп болот жана башкаларга көйгөй эмнеде экенин тез түшүнүүгө жардам берет деп үмүттөнөм. Бул жерде code:
String a = "aLongLongString";
String b = a.substring(1, 2);
String c = a.substring(2, 6);
b
Ошентип , JDK 7де с
а типтеги an objectте String
методду чакыруу менен түзүлгөн а substring()
түрүндөгү an objectтер String
үймөктө жаңы түзүлгөн эки массивге шилтеме кылат - L
for b
, ongL
for c
. Бул эки жаңы массив aLongLongString
a. Ошол. баштапкы массив эч жерде жок болбойт. Эми JDK 6га кайталы. JDK 6да үймөк бир массивди камтыйт aLongLongString
. Коддун саптарын аткаргандан кийин
String b = a.substring(1, 2);
String c = a.substring(2, 6);
Объекттер үймөктөгү ошол эле массивге тиешелүү, an objectке тиешелүү b
: - 1-индекстен 2-ге чейинки элементтерге, - 2-индекстен 6-ка чейинки элементтерге (номерлөө 0дөн башталат, эскертме). Ошол. Албетте, JDK 6дагы өзгөрмөлөргө же cга мындан аркы кирүү чындыгында түпнуска массивдин керектүү элементтеринин үймөккө "эсептелишине" алып келет. JDK 7де, өзгөрмөлөргө же c үчүн ар кандай мындан аркы жетүү мурунтан эле түзүлгөн жана үймөктө "тирүү" болгон керектүү майда массивдерге мүмкүнчүлүк берет. Ошол. Албетте, JDK 7 ушул сыяктуу жагдайларда физикалык жактан көбүрөөк эстутумду колдонот. Бирок, келгиле, мүмкүн болгон вариантты элестетип көрөлү: өзгөрмөнүн айрым ички саптары өзгөрмөлөргө ыйгарылат жана келечекте баары аларды гана колдонот - an objectтер жана . Эми эч ким a өзгөрмөсүнө кирбейт, ага шилтемелер жок (макаланын автору ушуну билдирет). Натыйжада, кандайдыр бир учурда таштанды жыйноочу ишке киргизилет жана (эң жалпы формада, албетте) биз 2 түрдүү кырдаалды алабыз: JDK 6 : an object жок кылынат (таштанды чогултулган) , БИРОК - баштапкы чоң массив үймөктө тирүү; ал дайыма колдонулат жана . JDK 7: a an objectи үймөгдөгү баштапкы массив менен бирге жок кылынат. Бул JDK 6дагы эс тутумдун агып кетишине алып келиши мүмкүн болгон жагдай. c
a
b
c
b
b
b
c
a
b
c
a
b
c
5. JDK 7де substring()
Метод JDK 7де жакшыртылган. JDK 7деsubstring()
ал үймөктө жаңы массивди түзөт.
//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