1.StringBuider类
StringBuider中append(String)的实现
StringBuider继承自AbstractStringBuilder ,
AbstractStringBuilder中有两个全局属性分别是:
char value[]; //存储字符的数组
int count; //数组中,已经存储字符的个数。(不是数组的长度)
来看一下append(String)的实现:
public AbstractStringBuilder append(String str) {
if (str == null) str = "null";
int len = str.length();
if (len == 0) return this;
int newCount = count + len;
if (newCount > value.length)
expandCapacity(newCount);//如果容量不够,扩容
str.getChars(0, len, value, count);
count = newCount;
return this;
}
首先要做的是判断value[] 数组的容量是否足够大以容下添加的字符串,如果不够大则扩容。
看一下expandCapacity(int minimumCapacity)函数
void expandCapacity(int minimumCapacity) {
int newCapacity = (value.length + 1) * 2;
if (newCapacity < 0) {
newCapacity = Integer.MAX_VALUE;
} else if (minimumCapacity > newCapacity) {
newCapacity = minimumCapacity;
}
value = Arrays.copyOf(value, newCapacity);
}
可以看到,扩容为(原来已经存储字符的个数+1)的两倍,如果溢出,则扩容为Integer的最大值,
如果扩容后的长度仍小于需要的长度,则扩容为需要的长度。
(如果进一步查看copyOf方法,可以看到它最后使用的是一个native方法System.arraycopy() )
回到append(String str);
public AbstractStringBuilder append(String str) {
if (str == null) str = "null";
int len = str.length();
if (len == 0) return this;
int newCount = count + len;
if (newCount > value.length)
expandCapacity(newCount);//如果容量不够,扩容
str.getChars(0, len, value, count);//把str添加到value[] 数组里面
count = newCount;//更新 已经存储字符的个数属性count
return this;
}
可以看到StringBuilder使用的是一个char类型的数组来存储字符串,一次扩容是根据(已经存储的个数+1)*2来扩容的。并且使用String的getChars方法把新增数组增加到value[]里面,下面来看下StringBuffer类
2.StringBuffer类
可以看到StringBuffer类也是继承AbstractStringBuilder
看一下它的append(String)
public synchronized StringBuffer append(String str) {
super.append(str);
return this;
}
可以看到除了增加了synchronized没有增加其他东西,它直接引用父类(AbstractStringBuilder)的append(String)方法。再看一下其他方法,发现同样的现象。
也就是说StringBuffer除了方法线程安全之外其他和StringBuider基本一致,并且这两个类都有使用final修饰,也就是说不允许我们进行继承修改。
3.String 类
String类中定义了四个全局属性,暂时关注其中的三个。
private final char value[]; //存储字符的数组
private final int offset;//数组中,第一个存储了字符的位置的index
private final int count;//已经存储的字符个数
这几个全局属性都是final修饰的,并且这些属性是通过构造函数来初始化的,通俗来说,new一个String()出来之后,该String就不可改变了。来看下concat(String)函数
public String concat(String str) {
int otherLen = str.length();
if (otherLen == 0) {
return this;
}
char buf[] = new char[count + otherLen];
getChars(0, count, buf, 0);
str.getChars(0, otherLen, buf, count);
return new String(0, count + otherLen, buf);
}
可以看到在String类型的字符串后面增加字符串,会new一个新的String返回。这里如果不处理好会发生内存泄露。而StringBuffer和StringBuider的append(String)就不存在这个情况。
分享到:
相关推荐
"String StringBuffer和StringBuilder区别之源码解析" 在Java中,字符串是我们经常使用的数据类型,而String、StringBuffer和StringBuilder是Java中三种常用的字符串类。在这篇文章中,我们将从源码角度对String、...
在Java编程语言中,`String`、`StringBuffer`和`StringBuilder`是处理字符串的三个重要类,它们各自有特定的使用场景和优缺点。理解它们的差异对于编写高效的代码至关重要。 **String类** `String`是不可变的类,...
StringBuffer:字符创变量 StringBuilder:字符创变量 从上面的名字可以看到,String是“字符创常量”,也就是不可改变的对象。对于这句话的理解你可能会产生这样一个疑问 ,比如这段代码:
针对String的详细介绍针对String的详细介绍针对String的详细介绍针对String的详细介绍针对String的详细介绍针对String的详细介绍针对String的详细介绍针对String的详细介绍针对String的详细介绍针对String的详细介绍...
在Java编程语言中,String、StringBuilder和StringBuffer都是用来处理字符串的类,它们之间存在一些重要的区别,主要涉及到性能和线程安全性。 首先,`String`类代表的是字符串常量,一旦创建,其内容就不能改变。...
### StringBuffer与String的区别详解 #### 一、概念与特性 **String** 是 Java 中一个不可变的类,代表了字符序列。一旦一个 String 对象被创建后,其内容就不能被改变。这使得 String 类非常适合用来表示常量或者...
String, StringBuffer 与 StringBuilder 的区别 在 Java 中,String, StringBuffer 和 StringBuilder 三个类都是用于字符操作的,但它们之间有着很大的区别。 首先,String 是不可变类,意味着一旦创建了 String ...
stringbuilder用法 String、StringBuilder、StringBuffer 用法比较String、StringBuilder、StringBuffer 用法比较String、StringBuilder、StringBuffer 用法比较String、StringBuilder、StringBuffer 用法比较String...
如果比较的是不同内容的`String`对象,`==`将返回`false`,除非使用`equals`方法进行内容比较。 总结来说,选择`String`还是`StringBuffer`(或`StringBuilder`)取决于具体的需求。如果字符串操作较少或者在单线程...
- 查看`String`的源码,我们可以看到`String`的构造函数和`concat`方法都是通过创建新对象来完成字符串的连接。 - 对于`StringBuffer`,它的`append`方法内部直接修改了`char[]`数组,无需创建新的对象。 综上所...
在上述代码示例中,我们比较了使用`String`和`StringBuffer`进行5000次字符串拼接操作的时间消耗。当使用`String`时,每次循环都会生成新的`String`对象,导致总时间达到46687毫秒。而使用`StringBuffer`,由于其...
在Java编程语言中,`String`和`StringBuffer`都是用来表示和操作字符串的重要类,但它们在使用场景和性能上有显著的区别。了解这些差异对于编写高效、优化的代码至关重要。 首先,`String`类是不可变的。这意味着...
由于`StringBuffer`的方法(如`append`、`insert`等)都是线程安全的,这意味着在多线程环境下,不同线程可以同时调用这些方法,不会引发数据不一致的问题。然而,这也意味着`StringBuffer`在进行修改操作时,会进行...
但是,在某些特别情况下,String 对象的字符串拼接其实是被 JVM 解释成了 StringBuffer 对象的拼接,所以这些时候 String 对象的速度并不会比 StringBuffer 对象慢。 线程安全性 StringBuffer 是线程安全的,而 ...
#### 四、String与StringBuffer的操作方法 - **String**: - `charAt(int index)`:返回指定索引处的字符。 - `concat(String str)`:将当前字符串与另一个字符串连接起来。 - `indexOf(String str)`:返回指定...
根据给定的信息,本文将对`String`与`StringBuffer`在Java中的使用进行详细的解析与对比,并结合实例深入分析二者的异同及其适用场景。 ### `String` 和 `StringBuffer` 的基本概念 #### `String` 在Java中,`...
- 使用`equals()`方法比较两个`String`对象的内容是否相同。 5. **其他常用方法** - `length()`: 返回字符串的长度。 - `charAt(int index)`: 返回指定索引位置的字符。 - `substring(int beginIndex, int ...
在Java编程语言中,`String`与`StringBuffer`是两个重要的字符串处理类,它们各自具有独特的特性和用途,尤其在面试或笔试中常被提及作为考察应聘者对Java基础知识掌握程度的重要知识点。 ### `String`类:不可变性...