JDK源码学习--String篇(四) 终结篇
StringBuilder和StringBuffer
前面讲到String是不可变的,如果需要可变的字符串将如何使用和操作呢?JAVA提供了连个操作可变字符串的类,StringBuilder和StringBuffer,从源码中可以看到这两个类都是采用final修饰,并且继承抽象类AbstractStringBuilder的。
abstract class AbstractStringBuilder implements Appendable, CharSequence {
/**
* The value is used for character storage.
*/
char[] value;
/**
* The count is the number of characters used.
*/
int count;
}
同String相同,都是采用字符数组来存储的,但是String中使用final修饰,是不可变的。
StringBuffer和StringBuilder都提供了一些常用的操作字符串的方法,有什么不同之处呢?还是从源码着手分析:
StringBuffer源码解析
/**
* Constructs a string buffer with no characters in it and an
* initial capacity of 16 characters.
*/
public StringBuffer() {
super(16);
}
看AbstractStringBuilder可知:
AbstractStringBuilder(int capacity) {
value = new char[capacity];
}
无参构造函数,构造一个初始容量为16的字符串缓冲区。同时提供多个有参的构造函数,其中:
/**
* Constructs a string buffer initialized to the contents of the
* specified string. The initial capacity of the string buffer is
* {@code 16} plus the length of the string argument.
*
* @param str the initial contents of the buffer.
*/
public StringBuffer(String str) {
super(str.length() + 16);
append(str);
}
这个构造函数需提供一个字符串参数,构造一个字符串缓冲区,并将其内容初始化为指定的字符串内容,该字符串的初始容量为 16 加上字符串参数的长度。其中的append方法是重要部分。
@Override
public synchronized StringBuffer append(String str) {
toStringCache = null;
super.append(str);
return this;
}
// AbstractStringBuilder
public AbstractStringBuilder append(String str) {
if (str == null)
return appendNull();
int len = str.length();
ensureCapacityInternal(count + len);
str.getChars(0, len, value, count);
count += len;
return this;
}
append方法前加了同步锁,保证了线程安全,StringBuffer中很多方法都采用同步锁,保证了多线程操作时的同步安全。
其中的ensureCapacityInternal方法中对存储空间的分配:当存储空间不够用的时候,重新new char[],存储空间为:(原始大小+1)*2,最大为:Integer.MAX_VALUE ,
StringBuilder
StringBuilder通StringBuffer操作逻辑基本一致,只是没有做同步处理。
总结
String:字符常量
StringBuffer:字符变量【线程安全】
StringBuilder:字符变量【非线程安全】
由此也可知,在大部分情况下,三者在执行速度方面的比较:StringBuilder > StringBuffer > String
用法总结:
String:用于少量需要对字符串进行操作【因为String 每次生成对象都会对系统性能产生影响,当内存中无引用对象产生过多时,GC就会开始工作】
StringBuilder:单线程下,多次大量操作字符串【字符串处理时不会产生新的对象,而是对象自身做改变】
StringBuffer:多线程下,多次大量操作字符串【字符串处理时不会产生新的对象,而是对象自身做改变】
JDK源码学习--String篇(四) 终结篇的更多相关文章
- JDK源码学习--String篇(二) 关于String采用final修饰的思考
JDK源码学习String篇中,有一处错误,String类用final[不能被改变的]修饰,而我却写成静态的,感谢CTO-淼淼的指正. 风一样的码农提出的String为何采用final的设计,阅读JD ...
- JDK源码学习--String篇(三) 存储篇
在进一步解读String类时,先了解下内存分配和数据存储的. 数据存储 1.寄存器:最快的存储区,位于处理器的内部.由于寄存器的数量有限,所以寄存器是按需分配. 2.堆栈:位于RAM中,但是通过堆栈指 ...
- JDK源码学习--String篇(-)
工作三年了,用了三年的JAVA,突然发现竟然没有好好的看下JDK的源码,整天用着的String,只是大概知道怎么回事,其中的实现逻辑却是一头雾水. 知耻而后勇,加油!!! java.lang.Stri ...
- JDK源码学习系列03----StringBuffer+StringBuilder
JDK源码学习系列03----StringBuffer+StringBuilder 由于前面学习了StringBuffer和StringBuilder的父类A ...
- JDK源码学习系列01----String
JDK源码学习系列01----String 写在最前面: 这是我JDK源码学习系列的第一篇博文,我知道 ...
- JDK源码学习系列02----AbstractStringBuilder
JDK源码学习系列02----AbstractStringBuilder 因为看StringBuffer 和 StringBuilder 的源码时发现两者都继承了AbstractStringBuil ...
- JDK源码学习笔记——LinkedHashMap
HashMap有一个问题,就是迭代HashMap的顺序并不是HashMap放置的顺序,也就是无序. LinkedHashMap保证了元素迭代的顺序.该迭代顺序可以是插入顺序或者是访问顺序.通过维护一个 ...
- JDK1.8源码学习-String
JDK1.8源码学习-String 目录 一.String简介 String类是Java中最常用的类之一,所有字符串的字面量都是String类的实例,字符串是常量,在定义之后不能被改变. 二.定义 p ...
- JDK源码学习系列05----LinkedList
JDK源码学习系列05----LinkedList 1.LinkedList简介 LinkedList是基于双向链表实 ...
随机推荐
- Network()
Network Time Limit : 2000/1000ms (Java/Other) Memory Limit : 60000/30000K (Java/Other) Total Submi ...
- Linux Kernel系列一:开篇和Kernel启动概要
前言 近期几个月将Linux Kernel的大概研究了一下,以下须要进行深入具体的分析.主要将以S3C2440的一块开发板为硬件实体.大概包含例如以下内容: 1 bootloader分析,以uboot ...
- 动画原理——绘制正弦函数&环绕运动&椭圆运动
书籍名称:HTML5-Animation-with-JavaScript 书籍源码:https://github.com/lamberta/html5-animation 1.正弦函数.x位置递增, ...
- OC 实现多选参数
在iOS的开发过程中有许多方法都是有可选参数的,例如: + (instancetype)arrayWithObjects:(ObjectType)firstObj, ... NS_REQUIRES_N ...
- Excal数据转化成Asset数据文件
我们知道,在Unity当中的文件都可以称之为Asset文件,在项目开发当中需要把数据读取来之后存放起来,而有的数据是不可以改变的,今天就来写一个demo处理一下这些数据,在这里就不写读取Excal数据 ...
- Windows vista以上模拟Alt Ctrl Delete
之前客户要求我们能够在windows登陆界面能够用指定账户批量控制机器登陆,然后用windows credentials provider(vista以上,xp需要用Gina)实现了这个功能,这期间遇 ...
- C++自定义命名空间
关于C++自定义命名空间,今天验证了一下命名空间如何使用,和嵌套命名空间以及出现的bug. 如何自定义命名空间,实例如下: insertion_sort.h和insertion_sort.cpp #p ...
- android应用程序的组成部分
android 应用程序的组成部分 activity 应用表示层,应用程序中每一个UI都是通过activity类或者多个扩展实现的.activity使用fragment和视图来布局和显示信息,以及响应 ...
- getActionBar().setTitle(); Java.lang.NullPoint异常解决方案
getActionBar().setTitle(); Java.lang.NullPoint异常解决方案,是由于低版本不支持直接获取的缘故,修改方案: try changing your theme ...
- 联系InfoSphere Streams和OpenMI时对水利模型联系的设计模式的一些考虑
从<时序计算通用模型接口 OpenMI开发技术及应用>一书中的第一章的对接口要求描述,我想到InfoSphere streams的流数据处理模式刚好可以满足这种模型/数据之间对接的需求. ...