classlib: fix String.replace, add optimizations for some corner cases

Fix #932
This commit is contained in:
Alexey Andreev 2024-07-18 18:51:42 +02:00
parent 8889b63df7
commit 13a959ce67
2 changed files with 31 additions and 13 deletions

View File

@ -501,22 +501,37 @@ public class TString extends TObject implements TSerializable, TComparable<TStri
} }
public String replace(TCharSequence target, TCharSequence replacement) { public String replace(TCharSequence target, TCharSequence replacement) {
var sb = new StringBuilder(); if (target == replacement) {
int sz = length() - target.length(); return (String) (Object) this;
int i = 0; } else if (target.isEmpty()) {
outer: var sb = new StringBuilder();
for (; i <= sz; ++i) { for (var i = 0; i < length(); ++i) {
for (int j = 0; j < target.length(); ++j) { sb.append(replacement);
if (charAt(i + j) != target.charAt(j)) { sb.append(charAt(i));
sb.append(charAt(i));
continue outer;
}
} }
sb.append(replacement); sb.append(replacement);
i += target.length() - 1; return sb.toString();
} else if (target.length() == 1 && replacement.length() == 1) {
return (String) (Object) replace(target.charAt(0), replacement.charAt(0));
} else {
var sb = new StringBuilder();
int sz = length() - target.length();
int i = 0;
outer:
for (; i <= sz; ++i) {
for (int j = 0; j < target.length(); ++j) {
if (charAt(i + j) != target.charAt(j)) {
sb.append(charAt(i));
continue outer;
}
}
sb.append(replacement);
i += target.length() - 1;
}
sb.append(substring(i));
return sb.toString();
} }
sb.append(substring(i));
return sb.toString();
} }
public TString trim() { public TString trim() {

View File

@ -197,6 +197,9 @@ public class StringTest {
@Test @Test
public void sequenceReplaced() { public void sequenceReplaced() {
assertEquals("ba", "aaa".replace("aa", "b")); assertEquals("ba", "aaa".replace("aa", "b"));
assertEquals("xaxaxax", "aaa".replace("", "x"));
assertEquals("axc", "abc".replace("b", "x"));
assertEquals("abc", "abc".replace("bc", "bc"));
} }
@Test @Test