Ing karya programmer, asring sawetara tugas utawa komponen bisa diulang. Mula, dina iki aku arep nyentuh topik sing asring ditemoni ing karya saben dinane pangembang Jawa. Ayo nganggep sampeyan nampa senar tartamtu saka cara tartamtu. Lan kabeh babagan katon apik, nanging ana sawetara perkara sing ora cocog karo sampeyan. Contone, separator ora cocok, lan sampeyan kudu sawetara liyane (utawa ora kabeh). Apa sing bisa ditindakake ing kahanan kaya ngono? Alami, gunakake metode
replace
kelas String
.
string Jawa diganti
Obyek jinisString
duwe papat variasi cara panggantos replace
:
replace(char, char);
replace(CharSequence, CharSequence);
replaceFirst(String, String);
replaceAll(String, String).
replace(char, char)
String replace(char oldChar, char newChar)
- ngganti kabeh kedadean saka karakter bantahan pisanan oldChar
karo kaloro - newChar
. Ing conto iki, kita bakal ngganti koma kanthi titik koma:
String value = "In JavaRush, Diego the best, Diego is Java God".replace(',', ';');
System.out.println(value);
Output konsol:
In JavaRush; Diego the best; Diego is Java God
2.replace(CharSequence, CharSequence)
Nggantosaken saben substring saka senar sing cocog urutan tartamtu saka karakter karo urutan karakter panggantos.
String value = "In JavaRush, Diego the best, Diego is Java God".replace("Java", "Rush");
System.out.println(value);
Kesimpulan:
In RushRush, Diego the best, Diego is Rush God
3.replaceFirst(String, String)
String replaceFirst(String regex, String replacement)
- Ngganti substring pisanan sing cocog karo ekspresi reguler sing ditemtokake karo string panggantos. Nalika nggunakake ekspresi reguler sing ora bener, sampeyan bisa nyekel PatternSyntaxException (sing ora apik). Ing conto iki, ayo ngganti jeneng robot juara:
String value = "In JavaRush, Diego the best, Diego is Java God".replaceFirst("Diego", "Amigo");
System.out.println(value);
Output konsol:
In JavaRush, Amigo the best, Diego is Java God
Kaya sing kita deleng, mung entri pisanan "Diego" sing wis diganti, nanging sing sabanjure tetep ditinggalake - yaiku, ora kena. 4. replaceAll()
ing Jawa String replaceAll(String regex, String replacement)
- cara iki ngganti kabeh kedadeyan saka substring ing senar regex
karo replacement
. Ekspresi reguler bisa digunakake minangka argumen pisanan regex
. Contone, ayo nyoba ngganti jeneng sadurunge, nanging kanthi cara anyar:
String value = "In JavaRush, Diego the best, Diego is Java God".replaceAll("Diego", "Amigo");
System.out.println(value);
Output konsol:
In JavaRush, Amigo the best, Amigo is Java God
Nalika kita bisa ndeleng, kabeh simbol wis rampung diganti karo sing perlu. Aku rasa Amigo bakal seneng =)
Ekspresi biasa
Disebutake ing ndhuwur yen bisa diganti nggunakake ekspresi biasa. Kaping pisanan, ayo jelasake dhewe apa ekspresi reguler? Ekspresi reguler minangka basa resmi kanggo nggoleki lan manipulasi substrings ing teks, adhedhasar panggunaan metacharacters (wildcards). Cukup, iki minangka pola karakter lan metakarakter sing nemtokake aturan telusuran. Contone:\D
- cithakan njlèntrèhaké sembarang karakter non-digital; \d
- nemtokake karakter angka, sing uga bisa diterangake minangka [0-9]
; [a-zA-Z]
- cithakan sing njlèntrèhaké karakter Latin saka a nganti z, cilik ora sensitif; Coba aplikasi ing metode replaceAll
kelas String
:
String value = "In JavaRush, Diego the best, Diego is Java God".replaceAll("\\s[a-zA-Z]{5}\\s", " Amigo ");
System.out.println(value);
Output konsol:
In JavaRush, Amigo the best, Amigo is Java God
\\s[a-zA-Z]{5}\\s
— nerangake tembung 5 aksara Latin diubengi spasi. Patut, cithakan iki diganti karo senar kita liwati.
Jawa regex ngganti
Sejatine, kanggo nggunakake ekspresi reguler ing Jawa, kemampuan sakajava.util.regex
. Kelas utama yaiku:
Pattern
- kelas sing nyedhiyakake versi kompilasi saka ekspresi reguler.Matcher
- kelas iki kokwaca pola lan nemtokake cocog ing senar ditampa.
Matcher
lan 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);
Lan kesimpulan kita bakal padha:
In JavaRush, Amigo the best, Amigo is Java God
Sampeyan bisa maca liyane babagan ekspresi reguler ing artikel iki .
Alternatif kanggo nggantiAll
Ora ana sangsi manawa metode kasebutreplace
nyengsemake String
, nanging ora bisa nglirwakake kasunyatan manawa obyek String
kasebut immutable
, yaiku, ora bisa diganti sawise nggawe. Mulane, nalika kita ngganti sawetara bagéan saka senar nggunakake cara replace
, kita ora ngganti obyek String
, nanging nggawe anyar saben wektu, karo isi perlu. Nanging nggawe obyek anyar saben wektu mbutuhake wektu suwe, apa ora? Utamané nalika pitakonan ora saperangan obyek, nanging saperangan saka atusan, utawa malah ewu. Ora gelem, sampeyan mulai mikir babagan alternatif. Lan apa alternatif sing kita duwe? Hmm... Nalika nerangake String
properti immutable
, sampeyan langsung mikir alternatif, nanging ora immutable
, yaiku StringBuilder/StringBuffer . Nalika kita ngelingi, kelas iki ora bener beda-beda, kajaba StringBuffer
padha optimized kanggo nggunakake ing lingkungan multi-Utas, supaya StringBuilder
padha bisa luwih cepet ing nggunakake siji-Utas. Adhedhasar iki, dina iki kita bakal nggunakake StringBuilder.
Kelas iki wis akeh cara menarik, nanging khusus saiki kita kasengsem ing replace
. StringBuilder replace(int start, int end, String str)
- cara iki ngganti karakter ing substring saka urutan iki karo karakter ing senar kasebut. Substring diwiwiti ing wiwitan sing ditemtokake lan terus nganti karakter ing pungkasan indeks, -1
utawa nganti pungkasan urutan yen ora ana karakter kasebut. Ayo ndeleng conto:
StringBuilder strBuilder = new StringBuilder("Java Rush");
strBuilder.replace(5, 9, "God");
System.out.println(strBuilder);
Kesimpulan:
Java God
Nalika sampeyan bisa ndeleng, kita nunjukaké interval kang kita arep kanggo nulis senar, lan nulis substring ing ndhuwur apa ing interval. Dadi, kanthi bantuan, StringBuilder
kita bakal nggawe maneh analog saka metode kasebut replaceall java
. Carane bakal katon kaya:
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();
}
Sepisanan medeni, nanging kanthi pangerten sethithik sampeyan bisa ngerti manawa kabeh ora rumit lan cukup logis. Kita duwe telung argumen:
str
- baris ing ngendi kita pengin ngganti sawetara substrings;oldStr
- perwakilan saka substrings sing bakal kita ganti;newStr
- apa kita bakal ngganti karo.
if
Kita butuh sing pertama kanggo mriksa data sing mlebu, lan yen senar str
kasebut oldStr
kosong, utawa substring anyar newStr
padha karo sing lawas oldStr
, banjur nglakokake metode kasebut ora ana gunane. Mulane, kita bali senar asli - str
. Sabanjure, kita mriksa newStr
, null
lan yen iki, banjur kita ngowahi dadi format string kosong sing luwih trep kanggo kita - ""
. Banjur kita duwe deklarasi variabel sing kita butuhake:
- dawa string total
str
; - dawa substring
oldStr
; - obyek
StringBuilder
saka senar sing dienggo bareng.
StringBuilder
- indexOf
- kita ngerteni indeks kedadeyan pisanan saka substring sing kita minati. Sayange, aku pengin dicathet yen indexOf
ora bisa digunakake karo ekspresi reguler, mula cara pungkasan kita mung bakal bisa digunakake karo kedadeyan strings ((Yen indeks iki padha karo -1
, mula ora ana kedadeyan maneh ing obyek saiki StringBuilder
, supaya kita metu saka metode kanthi asil kapentingan: ana ing StringBuilder
, sing diowahi dadi String
, nggunakake toString
. Yen indeks kita padha -1
ing pengulangan pisanan saka daur ulang, banjur substring sing kudu diganti ora ana ing umum. string pisanan. Mulane, ing kahanan kaya mengkono, kita mung bali senar umum. Sabanjure kita duwe lan cara sing diterangake ing ndhuwur digunakake replace
kanggo StringBuilder
nggunakake indeks ketemu kedadeyan kanggo nunjukaké koordinat saka substring bakal diganti. Daur ulang iki bakal mbukak Kaping pirang-pirang substrings sing kudu diganti ditemokake Yen senar mung kalebu karakter sing kudu diganti, banjur mung ing kasus iki, loop bakal mlaku kanthi lengkap lan asil bakal diowahi StringBuilder
dadi senar. Kita kudu mriksa bener cara iki, ta? Ayo nulis tes sing mriksa operasi metode kasebut ing macem-macem kahanan:
@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, "");
}
Bisa dipérang dadi 7 tes sing kapisah, sing saben bakal tanggung jawab kanggo kasus tes dhewe. Sawise diluncurake, kita bakal weruh manawa ijo, yaiku, sukses. Inggih, misale jek sing kabeh. Senajan ngenteni, kita ngandika ndhuwur sing cara iki bakal luwih cepet replaceAll
saka String
. Inggih, ayo ndeleng:
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);
Sabanjure, kode iki ditindakake kaping telu lan entuk asil ing ngisor iki: Output konsol:
Performance ratio - 5.012148941181627
Performance ratio - 5.320637176017641
Performance ratio - 4.719192686500394
Minangka kita bisa ndeleng, rata-rata cara kita 5 kaping luwih produktif tinimbang replaceAll
kelas klasik! String
Inggih, pungkasanipun, ayo padha mbukak mriksa padha, nanging, supaya ngomong, muspra. Ing tembung liyane, ing kasus nalika ora ketemu match. Ayo ngganti string telusuran saka "tyu"
menyang "--"
. Telung mlaku ngasilake asil ing ngisor iki: Output konsol:
Performance ratio - 8.789647093542246
Performance ratio - 9.177105482660881
Performance ratio - 8.520964375227406
Rata-rata, kinerja kanggo kasus sing ora ditemokake cocog tambah 8,8 kaping!
GO TO FULL VERSION