Java中的String,StringBuffer和StringBuilder
在了解这个问题的时候查了不少资料,最有帮助的是这个博文:http://swiftlet.net/archives/1694,看了一段时间,咀嚼了一段时间,写一个经过自己消化的博文,希望能帮到大家。
首先,String,StringBuffer,和StringBuilder都是对char[]的封装,而不同点在于String可以被认为是字符串常量,而StringBuffer,StringBuilder则是字符串变量。
String的成员变量如下:
private final char value[];
private final int offset;
private final int count;
注意到char value[]是final的,代表着对象一旦被创建就不可改。我们平时常对String执行类似如下操作看起来更改字符串比较自由随意,但是其本身是不断创建新对象的过程:
String a="Hello World";
a=a+"!";
System.out.println(a);
//result: Hello World!
所以,对String执行这种经常修改字符串的操作是效率低下的。
与String不同,StringBuffer和StringBuilder都继承于AbstractStringBuilder,所以我们从AbstractStringBuilder看起
其中成员变量如下
char value[];
int count;
首先不是final的,其次这个类引入了很多对“容量”控制的方法,很像C++中的<Vector>
例如扩容:当添加字符的长度使得char value[]超出了其本身的最大大小,需要创建一个更大的char[]并将内容复制:
void expandCapacity(int minimumCapacity)
{
int newCapacity = (value.length + 1) * 2;
if (newCapacity < 0)
{
newCapacity = Integer.MAX_VALUE;
} else if (minimumCapacity > newCapacity)
{
newCapacity = minimumCapacity;
}
char newValue[] = new char[newCapacity];
System.arraycopy(value, 0, newValue, 0, count);
value = newValue;
}
同样,char[]不可能所有容量都被使用,结束标识符同C一样是“\0”;
补长或者截断:
public void setLength(int newLength)
{
if (newLength < 0)
throw new StringIndexOutOfBoundsException(newLength);
if (newLength > value.length)
expandCapacity(newLength);
if (count < newLength)
{
for (; count < newLength; count++)
value[count] = '\0';
} else
{
count = newLength;
}
}
内存复制的方法常用的是:
public static native void arraycopy(Object src, int srcPos, Object dest, int destPos, int length);
那么StringBuffer和StringBuilder有什么区别:先从StringBuffer和StringBuilder到String的转换看起:
public String(StringBuffer buffer)
{
synchronized(buffer)
{
this.value = Arrays.copyOf(buffer.getValue(), buffer.length()); }
}
public String(StringBuilder builder)
{
this.value = Arrays.copyOf(builder.getValue(), builder.length());
}
可见,对于StringBuffer而言,处处要考虑其在多线程环境下的并发问题。也就是说,相比于StringBuilder而言,StringBuffer是线程安全的。
另外,关于String的intern方法,是将字符串常量放在一个由String类维护的常量池中。当调用intern 方法时,如果池中已经包含一个等于此String 对象的字符串(是否相等由 equals(Object)方法确定),则返回池中的字符串引用。否则,将此 String 对象添加到池中,并且返回此String 对象的引用。例如:对于任何两个字符串s和t,当且仅当s.equals(t)为true时,s.intern()==t.intern()才为true。
最新文章
- 【IOS】自定义可点击的多文本跑马灯YFRollingLabel
- Android中Bitmap,byte[],Drawable相互转化
- 在Ubuntu14.04_ROS_indigo上安装Kinect2驱动和bridge
- BAE hibernate c3p0数据库连接池
- Linux高级编程--04.GDB调试程序(查看数据)
- [Android Pro] Android Support 包里究竟有什么
- Java学习笔记——JDK1.7的新特性。
- 去除C/C++程序代码中的注释
- 让你的WizFi250适应各种气候
- 使用Visual Studio 创建可视Web Part部件
- iOS画面模糊
- 关于JS中变量提升的规则和原理的一点理解(二)
- JS中定义对象和集合
- Docker技术知识点总结
- Filter笔记
- Largest Rectangle in a Histogram POJ - 2559 (单调栈)
- iOS:百度长语音识别具体的封装:识别、播放、进度刷新
- pycharm修改快捷键
- fzu2204 dp
- 设置webstorm支持ES6语法