天道酬勤,学无止境

Does string.replaceAll() performance suffer from string immutability?

Lets say I called replaceAll() on a big string that replaced 1,000 matching instances. Does it mean that 1,000 strings were created and reassigned in process because of string immutability? Is there any faster alternatives?

评论

If you dig into String, you'll see that it delegates replaceAll() to Pattern & Matcher and Matcher.replaceAll() uses a StringBuilder to store the eventually returned value.

So no, String.replaceAll() does not create more than a small number of objects.

you can try with a StringBuffer/StringBuilder, since they are mutable CharSequences:

CharSequence veryBigString = new StringBuilder();
Pattern.compile(regex).matcher(veryBigString).replaceAll(replacement);

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • Fastest way to perform a lot of strings replace in Java
    I have to write some sort of parser that get a String and replace certain sets of character with others. The code looks like this: noHTMLString = noHTMLString.replaceAll("</p>", "\n"); noHTMLString = noHTMLString.replaceAll("<br/>", "\n\n"); noHTMLString = noHTMLString.replaceAll("<br />", "\n\n"); //here goes A LOT of lines like these ones The function is very long and performs a lot of strings replaces. The issue here is that it takes a lot of time because the method it's called a lot of times, slowing down the application performance. I have read some threads here about using StringBuilder
  • 在 Java 中执行大量字符串替换的最快方法(Fastest way to perform a lot of strings replace in Java)
    问题 我必须编写某种解析器来获取字符串并将某些字符集替换为其他字符集。 代码如下所示: noHTMLString = noHTMLString.replaceAll("</p>", "\n"); noHTMLString = noHTMLString.replaceAll("<br/>", "\n\n"); noHTMLString = noHTMLString.replaceAll("<br />", "\n\n"); //here goes A LOT of lines like these ones 该函数很长并且执行了很多字符串替换。 这里的问题是它需要很多时间,因为它被调用了很多次,降低了应用程序的性能。 我在这里阅读了一些关于使用 StringBuilder 作为替代方法的线程,但它缺少 ReplaceAll 方法,正如这里所指出的那样 string.replaceAll() 性能是否受到字符串不变性的影响? String 类中的 replaceAll 方法适用于 Match Pattern & Matcher 和 Matcher.replaceAll() 使用 StringBuilder 来存储最终返回的值,所以我不知道切换到 StringBuilder 是否真的会减少执行替换的时间。 您知道一种快速进行大量字符串替换的快速方法吗? 你对这个问题有什么建议吗? 谢谢。
  • 字符串replaceAll()与Matcher replaceAll()(性能差异)(String replaceAll() vs. Matcher replaceAll() (Performance differences))
    问题 一个非常简单的问题,但这是来自C / C ++人员进入Java的复杂性的。 我知道我可以启动jUnit和自己的一些性能测试来得到答案。 但我只是想知道这是否在那里。 在性能方面,String.replaceAll()和Matcher.replaceAll()(在从Regex.Pattern创建的Matcher对象上)之间是否存在已知差异? 此外,两者在高级API方面的区别是什么? (不可变性,处理NULL,处理空字符串,煮咖啡等) 回答1 根据String.replaceAll的文档,关于调用该方法有以下说法: 调用该方法的形式为str.replaceAll(regex, repl)其结果与表达式完全相同Pattern.compile(regex).matcher(str).replaceAll(repl) 因此,可以预期在调用String.replaceAll和显式创建Matcher和Pattern之间的性能应该是相同的。 编辑 正如评论中指出的那样,对于一次从String或Matcher调用replaceAll而言,不存在性能差异是正确的,但是,如果一个人需要执行多次对replaceAll调用,则可以期望它对保持已编译的Pattern ,因此不必每次都执行相对昂贵的正则表达式pattern编译。 回答2 String.replaceAll()源代码: public
  • String replaceAll() vs. Matcher replaceAll() (Performance differences)
    Pretty simple question, but this is coming from a C/C++ person getting into the intricacies of Java. I understand I can fire up jUnit and a few performance tests of my own to get an answer; but I'm just wondering if this is out there. Are there known difference(s) between String.replaceAll() and Matcher.replaceAll() (On a Matcher Object created from a Regex.Pattern) in terms of performance? Also, what are the high-level API 'ish differences between the both? (Immutability, Handling NULLs, Handling empty strings, making coffee etc.)
  • 如何在Java中替换字符串中的字符?(How do I replace a character in a string in Java?)
    问题 使用Java,我想通过一个文本行并更换所有符号的符号( & )的XML实体引用& 。 我先扫描文本行,然后再使用Scanner类扫描文本中的每个单词。 然后,我使用CharacterIterator遍历单词的每个字符。 但是,如何替换角色? 首先,字符串是不可变的对象。 其次,我想用几个字符( amp&; )替换一个字符( & )。 我应该如何处理? CharacterIterator it = new StringCharacterIterator(token); for(char ch = it.first(); ch != CharacterIterator.DONE; ch = it.next()) { if(ch == '&') { } } 回答1 尝试改用String.replace()或String.replaceAll() 。 String my_new_str = my_str.replace("&", "&"); (都替换所有出现的内容; replaceAll允许使用正则表达式。) 回答2 简单的答案是: token = token.replace("&", "&"); 尽管名称与replaceAll相比,replace确实执行了replaceAll,但它只是不使用正则表达式,这似乎在这里是有序的(从性能和良好实践的角度来看
  • 有效地从Java中的字符串中删除特定字符(某些标点符号)?(Efficiently removing specific characters (some punctuation) from Strings in Java?)
    问题 在Java中,从字符串中删除给定字符的最有效方法是什么? 目前,我有以下代码: private static String processWord(String x) { String tmp; tmp = x.toLowerCase(); tmp = tmp.replace(",", ""); tmp = tmp.replace(".", ""); tmp = tmp.replace(";", ""); tmp = tmp.replace("!", ""); tmp = tmp.replace("?", ""); tmp = tmp.replace("(", ""); tmp = tmp.replace(")", ""); tmp = tmp.replace("{", ""); tmp = tmp.replace("}", ""); tmp = tmp.replace("[", ""); tmp = tmp.replace("]", ""); tmp = tmp.replace("<", ""); tmp = tmp.replace(">", ""); tmp = tmp.replace("%", ""); return tmp; } 如果我使用某种StringBuilder或正则表达式,或者其他方法,会更快吗? 是的,我知道:剖析并查看,但是我希望有人能够提供一个解答
  • 如何替换字符串的子字符串(How to replace a substring of a string [duplicate])
    问题 这个问题已经在这里有了答案: 字符串替换方法不替换字符(5个答案) 4年前关闭。 假设我有一个像这样的String string : "abcd=0; efgh=1" 我想将“ abcd”替换为“ dddd”。 我试图做这样的事情: string.replaceAll("abcd","dddd"); 这是行不通的。 有什么建议? 编辑:更具体地说,我正在Java中工作,并且试图解析HTML文档,具体来说就是<script>标记之间的内容。 我已经找到了一种方法来将这些内容解析为字符串: if(tag instanceof ScriptTag){ if(((ScriptTag) tag).getStringText().contains("DataVideo")){ String tagText = ((ScriptTag)tag).getStringText(); } } 现在,我必须找到一种方法,用一个子字符串替换另一个子字符串。 回答1 您需要使用replaceAll()方法的返回值。 replaceAll()不会替换当前字符串中的字符,而是返回带有替换的新字符串。 字符串对象是不可变的,创建后不能更改其值。 如果不需要正则表达式,则可以使用replace()代替replaceAll()。 String str = "abcd=0; efgh=1"; String
  • Java String.replace / replaceAll不起作用(Java String.replace/replaceAll not working)
    问题 因此,我正在尝试解析Java中包含(开头)方括号的String输入。 我有str.replace("\\[", "") ,但这绝对没有任何作用。 我也尝试了replaceAll ,并使用了多个不同的正则表达式,但是输出始终保持不变。 我一部分人想知道这是否可能是因为我所有的反斜杠字符都显示为日元符号(自从我在语言中添加了日语以来),但是这种方式已经存在了一年多,并且没有给我造成任何影响。像这样的问题。 知道我在这里可能做错了什么吗? 回答1 字符串在Java中是不可变的。 确保将返回值重新分配给相同的String变量: str = str.replaceAll("\\[", ""); 对于常规的replace方法,您无需转义括号: str = str.replace("[", ""); 回答2 public String replaceAll(String regex, String replacement) 如上面的代码所示,replaceAll方法将第一个参数用作正则表达式,因此,如果替换文本中存在要替换的字符,则需要转义“ ( “,” ) “等(带有” \ “)等字符的字符串。 例如 : String oldString = "This is (stringTobeReplaced) with brackets."; String newString =
  • ReplaceAll 与 java8 lambda 函数(ReplaceAll with java8 lambda functions)
    问题 鉴于以下变量 templateText = "Hi ${name}"; variables.put("name", "Joe"); 我想使用以下代码(不起作用)将占位符 ${name} 替换为值“Joe” variables.keySet().forEach(k -> templateText.replaceAll("\\${\\{"+ k +"\\}" variables.get(k))); 但是,如果我采用“旧式”方式,则一切正常: for (Entry<String, String> entry : variables.entrySet()){ String regex = "\\$\\{" + entry.getKey() + "\\}"; templateText = templateText.replaceAll(regex, entry.getValue()); } 当然我在这里遗漏了一些东西:) 回答1 你也可以使用 Stream.reduce(identity,accumulator,combiner)。 身份 identity是归约函数的初始值,即accumulator 。 累加器 accumulator将identity减少到result ,如果流是顺序的,则这是下一个减少的identity 。 合路器 这个函数永远不会在顺序流中被调用。
  • 无法使用 replaceAll 从字符串中删除单词(Can't delete words from a string with replaceAll)
    问题 if(containsAllWeather || containsAllWeather2){ String weatherLocation = value.toString(); if (weatherLocation != null){ weatherLocation.replaceAll("how","") .replaceAll("what","") .replaceAll("weather", "") .replaceAll("like", "") .replaceAll(" in", "") .replaceAll(" at", "") .replaceAll("around", ""); } WeatherLocation 仍然准确地给出变量值包含的内容,并且不会删除上面列出的任何单词。 当我将weatherLocation 拆分为一个字符串数组(例如weatherLoc 数组)并且这些代码行适用于weatherLoc[1] 时,这有效 我究竟做错了什么? 回答1 您需要将方法调用返回的值赋给 String 引用变量。 每次执行replaceAll() ,它都会返回一个新的String对象,但您的weatherLocation变量仍在引用原始 String。 weatherLocation = weatherLocation.replaceAll("how",""
  • 为什么replaceAll在此代码行中不起作用? [复制](Why doesn't replaceAll work in this line of code? [duplicate])
    问题 这个问题已经在这里有了答案: 字符串替换方法不替换字符(5个答案) 3年前关闭。 String weatherLocation = weatherLoc[1].toString(); weatherLocation.replaceAll("how",""); weatherLocation.replaceAll("weather", ""); weatherLocation.replaceAll("like", ""); weatherLocation.replaceAll("in", ""); weatherLocation.replaceAll("at", ""); weatherLocation.replaceAll("around", ""); test.setText(weatherLocation); weatherLocation仍然包含“赞” 回答1 字符串是不可变的。 String#replaceAll()方法将创建一个新字符串。 您需要将结果重新分配给变量: weatherLocation = weatherLocation.replaceAll("how",""); 现在,由于replaceAll方法返回了修改后的字符串,因此您还可以在一行中链接多个replaceAll调用。 实际上,您在这里不需要replaceAll() 。
  • 如何从Java字符串中删除“”(How to remove “ ” from java string)
    问题 我有一个带" "的Java字符串从文本文件中,程序将使用Buffered Reader对象进行访问。 我已经尝试过string.replaceAll(" ","") ,但它似乎不起作用。 有任何想法吗? cleaned = cleaned.replace(" "," "); 回答1 cleaned = cleaned.replace("\u00a0","") 回答2 这是一个两步过程: strLineApp = strLineApp.replaceAll("&"+"nbsp;", " "); strLineApp = strLineApp.replaceAll(String.valueOf((char) 160), " "); 这对我有用。 希望它也对您有帮助! 回答3 您提到的方式相同: String cleaned = s.replace(" "," "); 这个对我有用。 回答4 有一个现成的解决方案可以从Apache公用区取消对HTML的转义: StringEscapeUtils.unescapeHtml("") 您还可以根据需要转义HTML: StringEscapeUtils.escapeHtml("") 回答5 字符串是不可变的,因此您需要 string = string.replaceAll(" ","") 回答6 您可以使用JSoup库: String
  • 用java替换字符串中的最后一个字符(Replacing last character in a String with java)
    问题 我有一个字符串: String fieldName = "A=2,B=3 and C=3,"; 现在我想最后更换,与空间。 我用过了: if (fieldName.endsWith(",")) { fieldName.replace(",", " "); fieldName = fieldName.replace((char) (fieldName.length() - 1), 'r'); } System.out.println("fieldName = " + fieldName); 但我仍然得到相同的旧字符串。 我怎么能得到这个输出呢? fieldName = A=2,B=3 and C=3 回答1 您可以简单地使用substring : if(fieldName.endsWith(",")) { fieldName = fieldName.substring(0,fieldName.length() - 1); } 确保在执行substring字符串后重新分配您的字段,因为字符串在 java 中是不可变的 回答2 我想用空格替换最后一个 ',' if (fieldName.endsWith(",")) { fieldName = fieldName.substring(0, fieldName.length() - 1) + " "; } 如果要删除尾随逗号,只需去掉
  • javac 或 Hotspot 会自动添加“final”作为对不变变量的优化吗?(Do javac or Hotspot automatically add 'final' as an optimisation of invariant variables?)
    问题 共识似乎是将成员变量标记为 final 有性能优势,因为它们永远不需要从主内存重新加载。 我的问题是,当变量显然无法更改时,javac 或 Hotspot 会自动为我执行此操作。 例如,javac 将在下面的这个类中使 'x' 成为 final ...... public class MyClass { private String x; MyClass(String x) { this.x = x; } public String getX() { return x; } } 在第二点上,有没有人提供经验证据表明将成员标记为 final 会使代码运行得更快? 在进行远程调用或数据库查找的任何应用程序中,任何好处肯定可以忽略不计? 回答1 像许多性能“增强”一样,通常最好询问; 什么更容易理解和推理? 例如,如果一个字段是最终的,我知道它不会在任何地方改变。 这通常会导致更优化的代码,但更重要的是它应该是更易于维护的代码。 ;) 当然,我将任何可以是 final 的字段设为 final。 就我个人而言,我更希望final是默认行为,你必须使用像var这样的关键字来使其可变。 回答2 允许 javac 这样做将是一个错误。 由于不同 jar 中的代码可能依赖于正在编译的代码(模块化),因此为了优化而在编译时更改代码不是一个可行的选择。 至于第二个参数“永远不需要从主内存重新加载
  • 关于 String.replaceAll() 和 String.replaceFirst() 方法的问题(Question about the String.replaceAll() and String.replaceFirst() method)
    问题 我需要对一段字符串进行简单的字符串替换操作。 我遇到了以下问题,希望得到一些建议。 在我得到的原始字符串中,我可以将诸如<div class="more">的字符串替换为其他字符串。 但是,在同一个原始字符串中,如果我想替换如下所示的很长的字符串,它将不起作用。 通话后没有任何东西被替换。 <div class="more"><a href="http://SERVER_name/profiles/atom/mv/theboard/entries/related.do?email=xyz.com&ps=20&since=1273518953218&sinceEntryId=abc-def-123-456">More...</a></div> 我试过这两种方法: originalString.replaceFirst(moreTag, newContent); originalString.replaceAll(moreTag, newContent); 提前致谢。 回答1 您需要掌握替换的结果并进一步使用它: String newString = originalString.replaceFirst(moreTag, newContent); System.out.println(newString); 说明:Java 中的字符串是不可变的。 java.lang
  • 更快的替代方法来替换Java String中的方法?(Faster alternatives to replace method in a Java String?)
    问题 replace方法返回一个字符串对象而不是替换给定字符串的内容这一事实有点让人费解(但是,当您知道字符串在Java中是不变的时,这是可以理解的)。 通过在某些代码中使用深度嵌套的替换,我的性能受到了重大影响。 有什么我可以替换的东西可以使它更快吗? 回答1 这就是StringBuilder的目的。 如果要进行很多操作,请在StringBuilder上进行操作,然后在需要时将其转换为String 。 这样描述了StringBuilder : “可变的字符序列。此类提供了与StringBuffer兼容的API,但不保证同步”。 它具有replace (以及append , insert , delete等),您可以使用toString将其变形为真实的String 。 回答2 前面的帖子是正确的,StringBuilder / StringBuffer是一种解决方案。 但是,您还必须质疑对内存中的大字符串进行替换是否是一个好主意。 我经常将String操作实现为流,因此,在将String发送到outputstream的那一刻,我执行了替换操作,而不是将其替换为字符串,然后将其发送到OutputStream。 这比任何替换都快得多。 如果您希望此替换实现模板机制,则可以更快地工作。 流传输总是更快,因为您消耗的内存更少,并且如果客户端很慢,则只需要以缓慢的速度生成文件
  • 为什么 Scala 标准库中没有不可变数组?(Why no immutable arrays in scala standard library?)
    问题 Scala 有各种各样的不可变序列,如 List、Vector 等。 我很惊讶地发现没有由简单数组支持的不可变索引序列的实现(Vector 对于我的需要来说似乎太复杂了)。 这有设计原因吗? 我在邮件列表上找不到很好的解释。 您是否有与数组具有接近相同性能的不可变索引序列的建议? 我正在考虑使用 scalaz 的 ImmutableArray,但例如它在使用 Scala 主干方面存在一些问题。 谢谢 回答1 您可以将数组转换为序列。 val s: Seq[Int] = Array(1,2,3,4) 该数组将隐式转换为 WrappedArray。 由于类型是 Seq,更新操作将不再可用。 回答2 所以,让我们首先区分接口和类。 接口是一种API设计,而类是这种API的实现。 Scala 中的接口具有相同的名称和不同的包以区分不变性: Seq 、 immutable.Seq 、 mutable.Seq 。 另一方面,这些类通常不共享名称。 List是一个不可变的序列,而ListBuffer是一个可变的序列。 也有例外,比如HashSet ,但这只是实现方面的巧合。 现在, Array不是 Scala 集合的一部分,它是一个 Java 类,但它的包装器WrappedArray清楚地显示了它将出现的位置:作为一个可变类。 WrappedArray实现的接口是IndexedSeq
  • Why does my performance slow to a crawl I move methods into a base class?
    I'm writing different implementations of immutable binary trees in C#, and I wanted my trees to inherit some common methods from a base class. Unfortunately, classes which derive from the base class are abysmally slow. Non-derived classes perform adequately. Here are two nearly identical implementations of an AVL tree to demonstrate: AvlTree: http://pastebin.com/V4WWUAyT DerivedAvlTree: http://pastebin.com/PussQDmN The two trees have the exact same code, but I've moved the DerivedAvlTree.Insert method in base class. Here's a test app: using System; using System.Collections.Generic; using
  • 替换C#字符串中的多个字符(Replace multiple characters in a C# string)
    问题 有替代字符串的更好方法吗? 令我惊讶的是,Replace不包含字符数组或字符串数​​组。 我想我可以编写自己的扩展名,但我很好奇是否有更好的内置方法可以执行以下操作? 请注意,最后一个Replace是字符串而不是字符。 myString.Replace(';', '\n').Replace(',', '\n').Replace('\r', '\n').Replace('\t', '\n').Replace(' ', '\n').Replace("\n\n", "\n"); 回答1 您可以使用替换正则表达式。 s/[;,\t\r ]|[\n]{2}/\n/g s/开头表示搜索 [和]之间的字符是要搜索的字符(任何顺序) 第二个/分隔搜索文本和替换文本 用英语,这是: “搜索;或,或\t或\r或 (空格)或两个连续的\n并将其替换为\n “ 在C#中,您可以执行以下操作:(在导入System.Text.RegularExpressions ) Regex pattern = new Regex("[;,\t\r ]|[\n]{2}"); pattern.Replace(myString, "\n"); 回答2 如果您感觉特别聪明并且不想使用正则表达式: char[] separators = new char[]{' ',';',',','\r','\t','\n'}
  • String.split()位于元字符处+(String.split() at a meta character +)
    问题 我正在制作一个简单的程序,该程序将处理方程式的字符串输入中的方程式,但是当我运行它时,由于尝试将“ +”替换为“ +”而出现异常,因此我可以分割字符串在空间。 我应该如何使用 字符串replaceAll方法替换这些特殊字符? 下面是我的代码 线程“主”中的异常java.util.regex.PatternSyntaxException:在索引0 + ^附近悬挂元字符'+' public static void parse(String x){ String z = "x^2+2=2x-1"; String[] lrside = z.split("=",4); System.out.println("Left side: " + lrside[0] + " / Right Side: " + lrside[1]); String rightside = lrside[0]; String leftside = lrside[1]; rightside.replaceAll("-", " -"); rightside.replaceAll("+", " +"); leftside.replaceAll("-", " -"); leftside.replaceAll("+", " +"); List<String> rightt = Arrays.asList(rightside