Дар кори барномасоз аксар вақт баъзе вазифаҳо ё ҷузъҳои онҳо метавонанд такрор шаванд. Аз ин рӯ, имрӯз мехоҳам ба мавзӯъе дахл кунам, ки дар кори ҳаррӯзаи ҳар як таҳиягари Java аксар вақт дучор мешавад. Фарз мекунем, ки шумо аз як усули муайян сатри муайян мегиред. Ва ҳама чиз дар бораи он ба назар хуб аст, аммо чизи каме вуҷуд дорад, ки ба шумо мувофиқат намекунад. Масалан, ҷудокунанда мувофиқ нест ва ба шумо дигаре лозим аст (ё тамоман не). Дар чунин вазъият чй кор кардан мумкин аст? Табиист, ки усулҳои
replace
синфро истифода баред String
.
Иваз кардани сатри Java
Объекти навъиString
дорои чор варианти усули ивазкунӣ мебошад replace
:
replace(char, char);
replace(CharSequence, CharSequence);
replaceFirst(String, String);
replaceAll(String, String).
replace(char, char)
String replace(char oldChar, char newChar)
- ҳама рӯйдодҳои аломати далели аввалро oldChar
бо дуюм - иваз мекунад newChar
. Дар ин мисол мо вергулро бо нуқта-вергул иваз мекунем:
String value = "In JavaRush, Diego the best, Diego is Java God".replace(',', ';');
System.out.println(value);
Натиҷаи консол:
In JavaRush; Diego the best; Diego is Java God
2.replace(CharSequence, CharSequence)
Ҳар як зерсатри сатрро, ки ба пайдарпаии муайяни аломатҳо мувофиқат мекунад, бо пайдарпаии аломатҳои ивазшаванда иваз мекунад.
String value = "In JavaRush, Diego the best, Diego is Java God".replace("Java", "Rush");
System.out.println(value);
Хулоса:
In RushRush, Diego the best, Diego is Rush God
3.replaceFirst(String, String)
String replaceFirst(String regex, String replacement)
- Зерсатри аввалро, ки ба ифодаи муқаррарии муқарраршуда мувофиқат мекунад, бо сатри ивазкунанда иваз мекунад. Ҳангоми истифодаи ифодаи муқаррарии беэътибор, шумо метавонед PatternSyntaxException-ро гиред (ки ин кори хуб нест). Дар ин мисол, биёед номи роботи қаҳрамонро иваз кунем:
String value = "In JavaRush, Diego the best, Diego is Java God".replaceFirst("Diego", "Amigo");
System.out.println(value);
Натиҷаи консол:
In JavaRush, Amigo the best, Diego is Java God
Тавре ки мебинем, танҳо вуруди аввалини «Диего» тағйир ёфтааст, аммо баъдӣ дар канор монданд, яъне дастнорас. 4. replaceAll()
дар Java String replaceAll(String regex, String replacement)
- ин усул ҳама рӯйдодҳои зерхатро дар сатр regex
бо replacement
. Ифодаи муқаррариро метавон ҳамчун далели аввал истифода бурд regex
. Мисол, биёед кӯшиш кунем, ки ивазкунии қаблиро бо номҳо иҷро кунем, аммо бо усули нав:
String value = "In JavaRush, Diego the best, Diego is Java God".replaceAll("Diego", "Amigo");
System.out.println(value);
Натиҷаи консол:
In JavaRush, Amigo the best, Amigo is Java God
Тавре ки мебинем, ҳамаи рамзҳо пурра бо аломатҳои зарурӣ иваз карда шудаанд. Ман фикр мекунам Амиго хушнуд мешавад =)
Ифодаҳои муқаррарӣ
Дар боло гуфта шуд, ки бо истифода аз ибораи муқаррарӣ иваз кардан мумкин аст. Аввалан, биёед худамон равшан кунем, ки ибораи муқаррарӣ чист? Ифодаҳои муқаррарӣ як забони расмӣ барои ҷустуҷӯ ва коркарди зерсатрҳо дар матн дар асоси истифодаи метаҳарфаҳо (ҳарфҳои ҷодугар) мебошанд. Оддӣ карда гӯем, он як намунаи аломатҳо ва метаҳарфаҳо мебошад, ки қоидаи ҷустуҷӯро муайян мекунад. Масалан:\D
- қолабе, ки ҳар гуна аломати рақамиро тавсиф мекунад; \d
— ҳар гуна аломати ададро муайян мекунад, ки онро метавон ҳамчун [0-9]
; [a-zA-Z]
— қолабе, ки ҳарфҳои лотиниро аз а то z тавсиф мекунад, ба ҳарфҳои ҳарф ҳассос нест; Аризаро дар усули replaceAll
синф баррасӣ кунед String
:
String value = "In JavaRush, Diego the best, Diego is Java God".replaceAll("\\s[a-zA-Z]{5}\\s", " Amigo ");
System.out.println(value);
Натиҷаи консол:
In JavaRush, Amigo the best, Amigo is Java God
\\s[a-zA-Z]{5}\\s
— калимаи 5 алифбои лотиниро, ки дар атрофаш фосила доранд, тасвир мекунад. Мутаносибан, ин қолаб бо сатри гузаштаамон иваз карда мешавад.
Иваз кардани regex Java
Асосан, барои истифодаи ибораҳои муқаррарӣ дар Java, имкониятҳоиjava.util.regex
. Синфҳои асосӣ инҳоянд:
Pattern
- синфе, ки versionи тартибдодашудаи ифодаи муқаррариро таъмин мекунад.Matcher
— ин синф намунаро шарҳ медиҳад ва мувофиқатро дар сатри қабулкардааш муайян мекунад.
Matcher
ва Pattern
:
Pattern pattern = Pattern.compile("\\s[a-zA-Z]{5}\\s");
Matcher matcher = pattern.matcher("In JavaRush, Diego the best, Diego is Java God");
String value = matcher.replaceAll(" Amigo ");
System.out.println(value);
Ва хулосаи мо чунин хоҳад буд:
In JavaRush, Amigo the best, Amigo is Java God
Шумо метавонед дар бораи ибораҳои муқаррарӣ дар ин мақола бештар хонед .
Алтернатива барои replaceAll
Шубхае нест, ки усулхо хелеreplace
таъсирбахшанд String
, вале аз он чиз чашм пушидан мумкин нест, ки String
вай immutable
an object аст, яъне баъд аз офарида шуданаш онро тагьир додан мумкин нест. Аз ин рӯ, вақте ки мо баъзе қисмҳои сатрро бо истифода аз усулҳо иваз мекунем replace
, мо an objectро тағир намедиҳем String
, балки ҳар дафъа як наверо бо мундариҷаи зарурӣ эҷод мекунем. Аммо сохтани an objectи нав ҳар дафъа вақти зиёдро мегирад, ҳамин тавр не? Хусусан, вақте ки савол на як ҷуфти an object, балки якчанд садҳо ва ҳатто ҳазорҳо аст. Бо вуҷуди ин, шумо дар бораи алтернативаҳо фикр мекунед. Ва мо чӣ алтернативаҳо дорем? Hmm... Вақте ки сухан дар бораи String
моликияти он меравад immutable
, шумо фавран дар бораи алтернативаҳо фикр мекунед, аммо на immutable
, яъне StringBuilder/StringBuffer . Тавре ки мо дар ёд дорем, ин синфҳо воқеан фарқ намекунанд, ба истиснои он, ки StringBuffer
онҳо барои истифода дар муҳити чанд ришта оптимизатсия шудаанд, аз ин рӯ StringBuilder
онҳо дар истифодаи як ришта то андозае тезтар кор мекунанд. Дар асоси ин, имрӯз мо истифода хоҳем кард StringBuilder.
Ин синф усулҳои ҷолиби зиёде дорад, аммо махсусан ҳоло мо ба replace
. StringBuilder replace(int start, int end, String str)
— ин усул аломатҳои зерсатри ин пайдарпаро бо аломатҳои сатри муайяншуда иваз мекунад. Зерсатри аз ибтидои муайяншуда оғоз мешавад ва то аломати охири индекс -1
ё то охири пайдарпай идома меёбад, агар чунин аломат мавҷуд набошад. Биёед як мисолро дида бароем:
StringBuilder strBuilder = new StringBuilder("Java Rush");
strBuilder.replace(5, 9, "God");
System.out.println(strBuilder);
Хулоса:
Java God
Тавре ки шумо мебинед, мо фосилаеро нишон медиҳем, ки мо сатрро дар он навиштан мехоҳем ва дар болои он чизе, ки дар фосила аст, зерхатро нависед. Ҳамин тавр, бо истифода аз кӯмак, StringBuilder
мо аналоги усулро дубора эҷод мекунем replaceall java
. Он чӣ гуна хоҳад буд:
public static String customReplaceAll(String str, String oldStr, String newStr) {
if ("".equals(str) || "".equals(oldStr) || oldStr.equals(newStr)) {
return str;
}
if (newStr == null) {
newStr = "";
}
final int strLength = str.length();
final int oldStrLength = oldStr.length();
StringBuilder builder = new StringBuilder(str);
for (int i = 0; i < strLength; i++) {
int index = builder.indexOf(oldStr, i);
if (index == -1) {
if (i == 0) {
return str;
}
return builder.toString();
}
builder = builder.replace(index, index + oldStrLength, newStr);
}
return builder.toString();
}
Ин дар назари аввал даҳшатнок аст, аммо бо каме фаҳмиш шумо метавонед фаҳмед, ки ҳама чиз он қадар мураккаб ва комилан мантиқӣ нест.Мо се далел дорем:
str
— сатре, ки мо мехоҳем баъзе зерсатрҳоро иваз кунем;oldStr
— муаррифии зерсатриҳо, ки мо онҳоро иваз мекунем;newStr
— онро бо чй иваз мекунем.
if
Барои санҷидани маълумоти воридотӣ ба мо аввалин лозим аст ва агар сатр холӣ str
бошад oldStr
ё зерсатри нав newStr
ба сатри кӯҳна баробар бошад oldStr
, пас иҷрои усул бемаънӣ хоҳад буд. Аз ин рӯ, мо сатри аслии - -ро бармегардонем str
. Баъдан, мо newStr
-ро тафтиш мекунем null
ва агар ин тавр бошад, пас мо онро ба формати сатри холӣ табдил медиҳем, ки барои мо қулайтар аст - ""
. Пас мо эъломияи тағирёбандаҳоеро дорем, ки ба мо лозим аст:
- дарозии умумии сатр
str
; - дарозии зери сатр
oldStr
; - an object
StringBuilder
аз сатри муштарак.
StringBuilder
- indexOf
- мо индекси пайдоиши аввалини зерсатри ба мо манфиатдорро пайдо мекунем. Мутаассифона, ман мехоҳам қайд намоям, ки он indexOf
бо ибораҳои муқаррарӣ кор намекунад, бинобар ин усули ниҳоии мо танҳо бо пайдоиши сатрҳо кор хоҳад кард (( Агар ин индекс ба , баробар бошад -1
, пас дар an objectи ҷорӣ дигар ҳодисаҳои ин ҳодисаҳо вуҷуд надоранд StringBuilder
, аз ин рӯ, мо бо натиҷаи шавқ аз усул мебароем: он дар мо мавҷуд аст StringBuilder
, ки мо ба он табдил медиҳем String
, бо истифода аз toString
.Агар индекси мо -1
дар такрори аввали давра баробар бошад, пас зерсатри иваз кардан лозим аст, дар маҷмӯъ набуд. Дар аввал сатр.Аз ин рӯ, дар чунин вазъият мо танҳо сатри умумиро бармегардонем.Дар оянда мо дорем ва усули дар боло тавсифшуда replace
барои StringBuilder
истифодаи индекси пайдошудаи ҳодиса барои нишон додани координатаҳои зерсатри ивазшаванда истифода мешавад.Ин давра иҷро мешавад. чанд маротиба зерсатри ивазшаванда пайдо мешавад.Агар сатр танҳо аз аломати ивазшаванда иборат бошад, пас танҳо дар ин ҳолат мо Давраи пурра иҷро мешавад ва мо натиҷаро StringBuilder
ба сатр табдил медиҳем. Мо бояд дурустии ин усулро тафтиш кунем, дуруст? Биёед санҷишеро нависед, ки кори усулро дар ҳолатҳои гуногун тафтиш мекунад:
@Test
public void customReplaceAllTest() {
String str = "qwertyuiop__qwertyuiop__";
String firstCase = Solution.customReplaceAll(str, "q", "a");
String firstResult = "awertyuiop__awertyuiop__";
assertEquals(firstCase, firstResult);
String secondCase = Solution.customReplaceAll(str, "q", "ab");
String secondResult = "abwertyuiop__abwertyuiop__";
assertEquals(secondCase, secondResult);
String thirdCase = Solution.customReplaceAll(str, "rtyu", "*");
String thirdResult = "qwe*iop__qwe*iop__";
assertEquals(thirdCase, thirdResult);
String fourthCase = Solution.customReplaceAll(str, "q", "");
String fourthResult = "wertyuiop__wertyuiop__";
assertEquals(fourthCase, fourthResult);
String fifthCase = Solution.customReplaceAll(str, "uio", "");
String fifthResult = "qwertyp__qwertyp__";
assertEquals(fifthCase, fifthResult);
String sixthCase = Solution.customReplaceAll(str, "", "***");
assertEquals(sixthCase, str);
String seventhCase = Solution.customReplaceAll("", "q", "***");
assertEquals(seventhCase, "");
}
Онро ба 7 санҷиши алоҳида тақсим кардан мумкин аст, ки ҳар яки онҳо барои парвандаи санҷишии худ масъул хоҳанд буд. Онро ба кор андохта, мебинем, ки он сабз аст, яъне муваффақ аст. Бале, ин ҳама ба назар мерасад. Гарчанде интизор шавед, мо дар боло гуфтем, ки ин усул нисбат replaceAll
ба String
. Хуб, биёед як назар андозем:
String str = "qwertyuiop__qwertyuiop__";
long firstStartTime = System.nanoTime();
for (long i = 0; i < 10000000L; i++) {
str.replaceAll("tyu", "#");
}
double firstPerformance = System.nanoTime() - firstStartTime;
long secondStartTime = System.nanoTime();
for (long i = 0; i < 10000000L; i++) {
customReplaceAll(str, "tyu", "#");
}
double secondPerformance = System.nanoTime() - secondStartTime;
System.out.println("Performance ratio - " + firstPerformance / secondPerformance);
Баъдан, ин code се маротиба иҷро шуд ва мо натиҷаҳои зеринро гирифтем: Натиҷаи консол:
Performance ratio - 5.012148941181627
Performance ratio - 5.320637176017641
Performance ratio - 4.719192686500394
Тавре ки мо мебинем, ба ҳисоби миёна усули мо нисбат ба replaceAll
синфи классикӣ String
5 маротиба самараноктар аст! Хайр, нихоят, хамин чекро гузаронем, вале, гуем, бехуда. Ба ибораи дигар, дар мавриде, ки ягон мувофиқат пайдо нашавад. Биёед сатри ҷустуҷӯро аз "tyu"
ба "--"
. Се давидан натиҷаҳои зерин дод: Натиҷаи консол:
Performance ratio - 8.789647093542246
Performance ratio - 9.177105482660881
Performance ratio - 8.520964375227406
Ба ҳисоби миёна, нишондиҳандаҳо дар ҳолатҳое, ки ягон гугирд ёфт нашуд, 8,8 маротиба зиёд шуд!
GO TO FULL VERSION