该替代方法,这一事实返回一个字符串对象,而不是更换定字符串的内容是有点钝(但可以理解的,当你知道字符串是不可变Java中)。 我正在通过使用一些代码嵌套很深的更换打了一个重大的性能。 有什么我可以用它代替将使它更快吗?
Answer 1:
这是StringBuilder的是为。 如果你打算做很多操作的,做它一个StringBuilder
,然后把它转换成一个String
,当您需要。
StringBuilder
是这样描述:
“一个可变的字符序列。这类提供的StringBuffer兼容的API,但不保证同步的”。
它已replace
(及append
, insert
, delete
等),你可以使用toString
把它演变成一个真正的String
。
Answer 2:
以前的职位是正确的,StringBuilder的/ StringBuffer的是一个解决方案。
不过,你也不用怀疑,如果它是一个好主意,做在内存大的字符串替换。
我经常被实现为流字符串操作,所以不是字符串中替换它,然后把它发送到一个OutputStream,我做的,把我的字符串发送到OutputStream的时刻更换。 这工作比任何替代快得多。
如果你想这个替换实施模板机制这样更快。 流总是更快,因为你消耗更少的内存,如果客户是缓慢的,你只需要以缓慢的速度产生 - 因此它扩展好得多。
Answer 3:
后续的代码是约。 如果不存在匹配和快5倍,如果有一个匹配快30倍。
static String fastReplace( String str, String target, String replacement ) {
int targetLength = target.length();
if( targetLength == 0 ) {
return str;
}
int idx2 = str.indexOf( target );
if( idx2 < 0 ) {
return str;
}
StringBuilder buffer = new StringBuilder( targetLength > replacement.length() ? str.length() : str.length() * 2 );
int idx1 = 0;
do {
buffer.append( str, idx1, idx2 );
buffer.append( replacement );
idx1 = idx2 + targetLength;
idx2 = str.indexOf( target, idx1 );
} while( idx2 > 0 );
buffer.append( str, idx1, str.length() );
return buffer.toString();
}
Answer 4:
我同意以上所述。 使用StringBuffer的线程安全和StringBuilder的单线程工作时。
Answer 5:
添加到@paxdiablo答案,这里是一个使用StringBuffers比String.replaceAll()快〜3.7倍的replaceAll的样本实现:
码:
public static String replaceAll(final String str, final String searchChars, String replaceChars)
{
if ("".equals(str) || "".equals(searchChars) || searchChars.equals(replaceChars))
{
return str;
}
if (replaceChars == null)
{
replaceChars = "";
}
final int strLength = str.length();
final int searchCharsLength = searchChars.length();
StringBuilder buf = new StringBuilder(str);
boolean modified = false;
for (int i = 0; i < strLength; i++)
{
int start = buf.indexOf(searchChars, i);
if (start == -1)
{
if (i == 0)
{
return str;
}
return buf.toString();
}
buf = buf.replace(start, start + searchCharsLength, replaceChars);
modified = true;
}
if (!modified)
{
return str;
}
else
{
return buf.toString();
}
}
测试用例 - 输出是下面的(DELTA1 = 1917009502; DELTA2 = 7241000026):
@Test
public void testReplaceAll()
{
String origStr = "1234567890-1234567890-";
String replacement1 = StringReplacer.replaceAll(origStr, "0", "a");
String expectedRep1 = "123456789a-123456789a-";
String replacement2 = StringReplacer.replaceAll(origStr, "0", "ab");
String expectedRep2 = "123456789ab-123456789ab-";
String replacement3 = StringReplacer.replaceAll(origStr, "0", "");
String expectedRep3 = "123456789-123456789-";
String replacement4 = StringReplacer.replaceAll(origStr, "012", "a");
String expectedRep4 = "1234567890-1234567890-";
String replacement5 = StringReplacer.replaceAll(origStr, "123", "ab");
String expectedRep5 = "ab4567890-ab4567890-";
String replacement6 = StringReplacer.replaceAll(origStr, "123", "abc");
String expectedRep6 = "abc4567890-abc4567890-";
String replacement7 = StringReplacer.replaceAll(origStr, "123", "abcdd");
String expectedRep7 = "abcdd4567890-abcdd4567890-";
String replacement8 = StringReplacer.replaceAll(origStr, "123", "");
String expectedRep8 = "4567890-4567890-";
String replacement9 = StringReplacer.replaceAll(origStr, "123", "");
String expectedRep9 = "4567890-4567890-";
assertEquals(replacement1, expectedRep1);
assertEquals(replacement2, expectedRep2);
assertEquals(replacement3, expectedRep3);
assertEquals(replacement4, expectedRep4);
assertEquals(replacement5, expectedRep5);
assertEquals(replacement6, expectedRep6);
assertEquals(replacement7, expectedRep7);
assertEquals(replacement8, expectedRep8);
assertEquals(replacement9, expectedRep9);
long start1 = System.nanoTime();
for (long i = 0; i < 10000000L; i++)
{
String rep = StringReplacer.replaceAll(origStr, "123", "abcdd");
}
long delta1 = System.nanoTime() -start1;
long start2= System.nanoTime();
for (long i = 0; i < 10000000L; i++)
{
String rep = origStr.replaceAll( "123", "abcdd");
}
long delta2 = System.nanoTime() -start1;
assertTrue(delta1 < delta2);
System.out.printf("Delta1 = %d; Delta2 =%d", delta1, delta2);
}
Answer 6:
如果你有多数的绳,以取代(如XML换码序列),尤其是其中所述置换是从图案不同长度的,FSM词法分析器类型算法好像它可能是最有效的,类似的处理的建议以流方式,其中输出逐步建立。
也许一个匹配器对象可以用来做有效。
Answer 7:
刚刚获得char[]
中的String
,并遍历它。 使用一个临时StringBuilder
。
寻找你想要在迭代如果你没有找到模式,写你扫描到的东西来替代模式StringBuilder
,否则写替换文本到StringBuilder
。
Answer 8:
一般而言,所有的字符串操作是非常慢的。 考虑到用StringBuffer,它不是完全一样的String类,但有很多共同点,这是可变的为好。
Answer 9:
当你更换单个字符,可以考虑遍历你的字符数组,但通过使用(预先创建)替换字符HashMap<Character, Character>()
我使用这个策略,统一标字符为一个整数指数字符串转换。
这是关于快两倍,比String.replace(char, char)
。 需要注意的是关联到创建哈希表的时间不包括在这个比较。
Answer 10:
因为String.replace(CharSequence target, CharSequence replacement)
已Pattern.compile
, matcher
, replaceAll
里面,一个可以稍微通过优化它用于使用预编译目标图案恒定,这样的:
private static final Pattern COMMA_REGEX = Pattern.compile(",");
...
COMMA_REGEX.matcher(value).replaceAll(replacement);