java - 我们什么时候应该将 String 更改为 Stringbuilder?

标签 java string memory-management refactoring stringbuilder

在应用程序中,字符串是一种常用的数据类型。我们所知道的是,字符串的变化会占用大量内存。所以我们可以做的是使用 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 使用的内存少于 比具有相同内容的StringBuilderStringBuilder 类有一些额外的常量开销,并且通常有一个预先分配的缓冲区来存储比任何给定时刻所需的更多的数据(以减少分配)。 String 的问题在于它们不可变,这意味着只要您需要更改其内容,Java 就需要创建一个新实例。

总而言之,StringBuilder 不是为您提到的操作(拆分和替换)而设计的,并且它在任何情况下都不会产生更好的性能。 split 方法无法从 StringBuilder 的可变性中获益,因为它无论如何都会创建一个不可变字符串数组作为其输出。替换方法仍然需要遍历整个字符串,如果替换的字符串与搜索到的字符串大小不同,则需要进行大量复制。

如果您需要做大量的追加,那么请使用StringBuilder。由于它在底层使用“可变”字符数组,因此将数据添加到末尾将特别有效。

This article比较几种 StringBuilderString 方法的性能(尽管我会保留 Concatenation 部分,因为它根本没有提到动态字符串追加并且专注于单个仅限 Join 操作)。

关于java - 我们什么时候应该将 String 更改为 Stringbuilder?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7510422/

相关文章:

java - 以下 java 代码给出输出 1 2 3 。代码是如何执行的?

java - 扫描带注释的类不适用于 Instant Run

c - 两种不同的内存错误取决于我分配内存的位置

MySQL 服务器最大化内存,Galera 集群

c# - Winform应用,window最小化强制垃圾回收?

java - 在 Java 中创建 Unix 时间戳

Java Guava 过滤两个不同类型的集合

c# - 连接常量字符串和枚举

ios - 在 iOS 计算器上创建退格键

string - swift println float 使用字符串