使用巨大的堆空间替换字符串

时间:2012-11-28 19:00:00

标签: java

我正在进行xml解析并执行一些使用大量内存空间的字符串replaceAll,如下图所示。

代码如下:

private final String getText() {
  // special handling for apostrophe encoding
  // site will expect both ' , ' and %27.
  // change %27 or 'or ' to '
  return _text.toString().trim().replaceAll("'", "'")
            .replaceAll("'", "'").replaceAll("%27", "'");
}

getText()方法经常从SAXParser的endElement()方法调用。

任何人都可以建议如何更改使用较小堆空间的此功能

![跟踪] [1]

6 个答案:

答案 0 :(得分:6)

使用replace()代替replaceAll()replaceAll()使用regular expression,您不需要它们,而且它们也是开销。

答案 1 :(得分:3)

使用正则表达式进行简单的字符串替换是非常昂贵的。 我只想构建一个这样的StringBuilder实例:

StringBuilder sb = new StringBuilder();

while (not end of _text) {
   find next '&'
   if the next substring is in (' ') etc.
     append the prev portion of _text to sb
     append replacement char
     set the beginning of the chunk to the next char
}
return sb.toString();

答案 2 :(得分:3)

由于_text已经是StringBuffer,您可以使用indexOf(String str)replace(int start, int end, String str)。这样,您根本不会创建临时String个对象。

使用类似的功能:

private void replace(StringBuffer buff,String toReplace,String replaceTo){
 int start;
 while ((start=buff.indexOf(toReplace))>=0)
   buff.replace(start,start+toReplace.length(),replaceTo);
}

并为您调用getText()中的函数,对于每个组合,例如:

String replaceTo=",";
replace(_text,"'",replaceTo);
replace(_text,"'",replaceTo);
replace(_text,"%27",replaceTo);
return _text.toString();

答案 3 :(得分:1)

您的replaceAll方法在String上调用,这是不可变的。因此,每次修改时都必须创建一个全新的字符串(在这种情况下为3次)。如果您使用StringBuilder代替,您的字符串将是可变的,并且每次更换内容时都不需要再次分配。

顺便说一句,在StringBuilders中没有像你需要的那样“替换”,所以你必须反复使用indexOf找到你的违规字符串,并在结果上replace。 trim()就在那里。

答案 4 :(得分:1)

您可以一次性完成所有3次替换

text.replaceAll("('|&39;|%27)", "'");

它比3次连续替换效率高3倍,因为每次替换都可能创建一个新的String

答案 5 :(得分:1)

由于您在SAX中获取文本,因此必须来自此处

characters(char[] ch, int start, int length) 

你必须在字段中保存这些args,在endElement()上你可以替换为

    StringBuilder sb = new StringBuilder();
    for (int i = start; i < length; i++) {
               // %27
        if (ch[i] == '%' && length - i > 2 && ch[i + 1] == '2' && ch[i + 2] == '7') {
                         sb.append('\'');
            i += 2;
                // &apos;
                } else if (
                   ...
                // &#39;
                } else if (
                   ...
        } else {
            sb.append(ch[i]);
        }
    }
    String res = sb.toString();

代码很长但效率很高,你也可以添加修剪