javastring替换⼀批_更快的替代⽅法来替换JavaString中的⽅
法?
replace⽅法返回字符串对象⽽不是替换给定字符串的内容这⼀事实有点让⼈费解(但是,当您知道字符串在Java中是不变的时,这是可以理解的)。 通过在某些代码中使⽤深度嵌套的替换,我的性能受到了重⼤影响。 有什么我可以替换的东西可以使它更快吗?
呵呵替换替换
您使⽤字符串吗? 你疯了吗? 使⽤字节数组!
这就是StringBuilder的⽬的。如果要进⾏很多操作,请在StringBuilder上进⾏操作,然后在需要时将其转换为String。
StringBuilder的描述如下:
"A mutable sequence of characters. This class provides an API compatible with StringBuffer, but with no guarantee of synchronization".
它具有replace(以及append,insert,delete等),您可以使⽤toString将其变形为真实的String。
还请记住,如果您不需要线程安全,则通常使⽤StringBuilder,它通常更快并且⼯作原理相同。
另外,place的⼯作⽅式与place完全不同,因此您不能将其⽤作嵌⼊式替代品!
前⾯的帖⼦是正确的,StringBuilder / StringBuffer是⼀种解决⽅案。
但是,您还必须质疑对内存中的⼤字符串进⾏替换是否是个好主意。
我经常将String操作实现为流,因此,在将String发送到outputstream的那⼀刻,我执⾏了替换操作,⽽不是将其替换为字符串,然后将其发送到OutputStream。这⽐任何替换都快得多。
如果您希望此替换实现模板机制,则可以更快地⼯作。流传输总是更快,因为您消耗的内存更少,并且如果客户端很慢,则只需要以较慢的速度⽣成⽂件即可,因此扩展性更好。
你能举个例⼦吗?
以下代码是⼤约。如果没有匹配项,则0倍;如果存在匹配项,则快5倍。
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() );
String();
}
您是⾃⼰创建还是在某处到它?我需要像这样的功能来在本机Java中拆分⼯作吗?任何想法
我不知道了。但它看起来像我的代码样式。我认为我是⾃⼰写的。另外,如果设置为副本,我没有设置任何链接或参考。对不起,我不是那个意思,但要感谢您的回应
我同意以上所述。使⽤单线程时,请使⽤StringBuffer来确保线程安全,并使⽤StringBuilder。
除了@paxdiablo答案,这是使⽤StringBuffers的replaceAll的⽰例实现,它⽐placeAll()快约3.7倍:
码:
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;
}
String();
}
buf = place(start, start + searchCharsLength, replaceChars); modified = true;
}
if (!modified)
{
return str;
}
else
{
String();
}
}
测试⽤例-输出如下(Delta1 = 1917009502; Delta2 = 7241000026):
@Test
public void testReplaceAll()
{
String origStr ="1234567890-1234567890-";
String replacement1 = placeAll(origStr,"0","a");
String expectedRep1 ="123456789a-123456789a-";
String replacement2 = placeAll(origStr,"0","ab");
String expectedRep2 ="123456789ab-123456789ab-";
String replacement3 = placeAll(origStr,"0","");
String expectedRep3 ="123456789-123456789-";
String replacement4 = placeAll(origStr,"012","a"); String expectedRep4 ="1234567890-1234567890-";
String replacement5 = placeAll(origStr,"123","ab"); String expectedRep5 ="ab4567890-ab4567890-";
String replacement6 = placeAll(origStr,"123","abc"); String expectedRep6 ="abc4567890-abc4567890-";
String replacement7 = placeAll(origStr,"123","abcdd"); String expectedRep7 ="abcdd4567890-abcdd4567890-";
String replacement8 = placeAll(origStr,"123","");
String expectedRep8 ="4567890-4567890-";
String replacement9 = placeAll(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);
java replace方法assertEquals(replacement8, expectedRep8);
assertEquals(replacement9, expectedRep9);
long start1 = System.nanoTime();
for (long i = 0; i < 10000000L; i++)
{
String rep = placeAll(origStr,"123","abcdd");
}
long delta1 = System.nanoTime() -start1;
long start2= System.nanoTime();
for (long i = 0; i < 10000000L; i++)
{
String rep = placeAll("123","abcdd");
}
long delta2 = System.nanoTime() -start1;
assertTrue(delta1 < delta2);
System.out.printf("Delta1 = %d; Delta2 =%d", delta1, delta2);
}
只需获取String的char[]并对其进⾏迭代。使⽤临时StringBuilder。
如果不到模式,请在迭代时查要替换的模式,将扫描的内容写⼊StringBuilder,否则将替换⽂本写⼊StringBuilder。
如果要替换的字符串很多(例如XML转义序列),尤其是替换的长度与模式长度不同时,FSM lexer类型算法似乎是最有效的,类似于以流⽅式进⾏处理的建议,其中将逐步构建输出。
也许可以使⽤Matcher对象来有效地做到这⼀点。
由于place(CharSequence target, CharSequence replacement)内部具有Patternpile,matcher,replaceAll,因此可以使⽤预编译的⽬标模式常量对其进⾏稍微优化,如下所⽰:
private static final Pattern COMMA_REGEX = Patternpile(",");
...
COMMA_REGEX.matcher(value).replaceAll(replacement);
当您替换单个字符时,请考虑遍历您的字符数组,但要使⽤(预先创建的)HashMap()替换字符。
我使⽤此策略通过Unicode上标字符转换整数指数字符串。
它是place(char, char)的两倍。请注意,与创建哈希映射表相关的时间不包括在此⽐较中。
通常,所有字符串操作都⾮常慢。考虑使⽤StringBuffer,它与String类并不完全⼀样,但是有很多共同点,并且也是可变的。
通常,如果您不需要缓冲区是线程安全的(即您没有多个线程⼀次操作同⼀缓冲区),则应使⽤StringBuilder⽽不是StringBuffer。从StringBuffer⽂档中:StringBuilder类通常优先于此类使⽤,因为
它⽀持所有相同的操作,但是它更快,因为它不执⾏同步。我过去经常在多线程环境中⼯作,所以StringBuffer⾃然⽽然地出现在我的脑海中。
不知道为什么这个问题引起了骚动。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论