Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/tfs/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java String和StringBuilder之间的差异及其内部组织_Java_String_Stringbuilder - Fatal编程技术网

Java String和StringBuilder之间的差异及其内部组织

Java String和StringBuilder之间的差异及其内部组织,java,string,stringbuilder,Java,String,Stringbuilder,这是一个非常基本的问题。我知道答案的范围是字符串是不可变的。StringBuilder不是,因此可以在末尾追加字符 那么StringBuilder内部是如何组织的呢?? 字符串是一个字符数组 StringBuilder也是一个字符数组吗? 因此,我有一个StringBuilder,我的_OBJ=“你好”。 现在,如果我尝试将字符附加到我的_OBJ的末尾,这不意味着您实际上正在创建一个新的数组对象并将所有这些字符复制到一个新的数组对象中吗?如果是这样,它如何比字符串更有效 我想问的另一个问题是,如

这是一个非常基本的问题。我知道答案的范围是字符串是不可变的。StringBuilder不是,因此可以在末尾追加字符

那么StringBuilder内部是如何组织的呢?? 字符串是一个字符数组

StringBuilder也是一个字符数组吗? 因此,我有一个StringBuilder,我的_OBJ=“你好”。 现在,如果我尝试将字符附加到我的_OBJ的末尾,这不意味着您实际上正在创建一个新的数组对象并将所有这些字符复制到一个新的数组对象中吗?如果是这样,它如何比字符串更有效

我想问的另一个问题是,如何标记StringBuilder的结束?
与C语言一样,我们使用“/0”

大多数StringBuilder实现都来自Sun的实现,在Sun的实现中,它是一个围绕字符数组的包装器。没有标记字符串的结尾,类本身包含一个计数变量,该变量表示字符串的实际大小。还有一个capacity方法将告诉您实际数组有多大(还有一个trimToSize方法将字符串生成器修剪为与当前存储的字符串一样大的数组)

只有当您达到当前字符串生成器容量时,才会创建新数组,而且此操作的成本并不高,因为它使用arrayCopy方法,并且容量始终会加倍,因此随着您的增长,达到限制的可能性会降低。如果事先知道字符串生成器的大小,还可以在其构造函数上定义,这样它就不必将内容复制到新数组中

此外,该代码:

StringBuilder MY_OBJ= "Hello";
不起作用

但这一个是:

StringBuilder MY_OBJ= new StringBuilder("Hello");
我不知道。我们去看看:

===

StringBuilder也是一个字符数组吗

显然,在这个特定的实现中

因此,我有一个StringBuilder,我的_OBJ=“你好”。现在,如果我尝试将字符附加到我的_OBJ的末尾,这不意味着您实际上正在创建一个新的数组对象并将所有这些字符复制到一个新的数组对象中吗

不一定。数组不一定已满(
count
),因此可能不需要分配新数组。理想情况下,您可以初始化StringBuilder的容量,以便从一开始就分配足够大的阵列

StringBuilder sb = new StringBuilder(20);
sb.append("Hello");
...
sb.append(" there");
我想问的另一个问题是,如何标记StringBuilder的结束?像在C中一样,我们使用“/0”


您不必在意-
String/StringBuilder
将在内部处理它。

如果您不打算更改该值,StringBuilder的效率并不比String高。如果要在字符串中添加/删除字符,则效率更高

StringBuilder的默认构造函数将创建一个可以容纳16个字符元素的数组
#append(String)
使用
String#getChars(int,int,char[],int)
将字符串的字符复制到StringBuidler的数组中。仅当没有空间添加更多字符时,才使用
Arrays.copyOf(char[],int)
重新调整数组大小。每次发生这种情况时,阵列的容量都会翻倍。通过计算数组中的字符数来标记结束

在旧版本的Java中,当在循环中串联字符串时,使用+运算符串联的每个字符串都会创建一个新的字符串对象。StringBuilder速度更快,因为它创建的对象更少

如果要保留StringBuilder实例,则可能需要在完成修改后调用
StringBuilder#trimToSize()
。它将尝试将阵列的容量降至所需的最小值


希望这能有所帮助。

谢谢,我的疑问已经澄清:)。挑剔-有些情况下,容量会增加一倍以上,而有些情况下,容量会减少一倍以下。(查看代码)但是,这些情况是例外,你基本上是对的。既然所有方法都是针对负值进行验证的,StringBuilder构造函数javadoc说如果提供了负值,它将抛出一个异常,那么现在确定负的newCapacity是如何发生的。+1用于指出任何人都可以去寻找自己的源代码。如果
StringBuilder
的内部数组计数大于实际字符串长度,大于平均值
StringBuilder
是动态数组,而
string
是不可变(固定大小)的正常数组?
45        * The value is used for character storage.
46        */
47       char[] value;
48   
49       /**
50        * The count is the number of characters used.
51        */
52       int count;
StringBuilder sb = new StringBuilder(20);
sb.append("Hello");
...
sb.append(" there");