在应用程序中,字符串是一种常用的数据类型。我们所知道的是,字符串的变化会占用大量内存。所以我们可以做的是使用 StringBuilder/StringBuffer。
但我们应该在什么时候更改为 StringBuilder?
当我们必须拆分它或替换其中的字符时,我们应该怎么做?
例如:
//original:
String[] split = string.split("?");
//better? :
String[] split = stringBuilder.toString().split("?);
或
//original:
String replacedString = string.replace("l","st");
//better? :
String replacedString = stringBuilder.toString().replace("l","st");
//or
StringBuilder replacedStringBuilder = new StringBuilder(stringBuilder.toString().replace("l","st);
最佳答案
在您的示例中,使用 StringBuilder
没有任何好处,因为您使用 toString
方法创建了一个不可变的 String
你的 StringBuilder
。
您应该只在完成追加(或以其他方式修改)后将 StringBuilder
的内容复制到 String
中。
Java 的 StringBuilder
的问题在于它缺少一些您在使用普通字符串时可以获得的方法(检查此线程,例如:How to implement StringBuilder.replace(String, String))。
What we know, is that a String uses lots of memory.
实际上,准确地说,String
使用的内存少于 比具有相同内容的StringBuilder
。 StringBuilder
类有一些额外的常量开销,并且通常有一个预先分配的缓冲区来存储比任何给定时刻所需的更多的数据(以减少分配)。 String
的问题在于它们不可变,这意味着只要您需要更改其内容,Java 就需要创建一个新实例。
总而言之,StringBuilder
不是为您提到的操作(拆分和替换)而设计的,并且它在任何情况下都不会产生更好的性能。 split
方法无法从 StringBuilder
的可变性中获益,因为它无论如何都会创建一个不可变字符串数组作为其输出。替换方法仍然需要遍历整个字符串,如果替换的字符串与搜索到的字符串大小不同,则需要进行大量复制。
如果您需要做大量的追加,那么请使用StringBuilder
。由于它在底层使用“可变”字符数组,因此将数据添加到末尾将特别有效。
This article比较几种 StringBuilder
和 String
方法的性能(尽管我会保留 Concatenation 部分,因为它根本没有提到动态字符串追加并且专注于单个仅限 Join
操作)。
关于java - 我们什么时候应该将 String 更改为 Stringbuilder?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7510422/