学习目标:
- 1、理解String、StringBuffer、Stringbuilder三者的异同
- 2、掌握StringBuffer、Stringbuilder的常用方法
- 3、读源码
学习内容:
一、三者的异同
- 不同点:String:是不可变的字符序列;StringBuffer;可变的字符序列、线程安全的,效率低;StringBuilder:可变的字符序列:线程不安全的,效率高,jdk5.0新增。
- 相同点:三者底层都是char[]来存储的。
为什么可变:
源码分析:
String str = new String();//new char[0];
String str1 = new String("abc");//new char[]{'a','b','c'};
StringBuffer sb1 = new StringBuffer();//new char[16];底层创建类一个长度为16的数组
sb1.append('a');//value[0] = 'a';
sb1.append('b');//value[1] = 'b';
StringBuffer sb2 = new String("abc");//char[] value = new char["abc.length()+16];
//问题1.System.out.println(sb2.length());//3
//问题2.扩容问题:如果要添加的数据底层数组装不下了,扩容原来的2倍+2,同时将原有的数组中的元素复制到新的数组中。
指导意义:在开发中建议使用指定容量的构造器。
二、常用方法
- StringBuffer append(xxx):提供了很多的append()方法,用于进行字符串拼接
测试代码:
测试结果:
- StringBuffer delete(int start,int end):删除指定位置的内容,start:开始删除的起始点(包含)end:删除的结束点(不包含),简单的说就是左闭右开。
测试代码:
测试结果:
- StringBuffer replace(int start, int end, String str):把[start,end)位置替换为str,start:开始取代的起始点(包含)end:删除的结束点(不包含),简单的说就是左闭右开。
测试代码:
测试结果:
- StringBuffer insert(int offset, xxx):在指定位置插入xxx,offest:指的是偏移量。
测试程序:
测试结果:
- StringBuffer reverse() :把当前字符序列逆转,把内容改变了,但是地址没有改变
测试程序:
测试结果:
- public int indexOf(String str):返回传入字符串出现在指定字符串的第一个索引位置,没有找到的话返回-1。
测试程序:
测试结果:
public String substring(int start,int end):返回指定字符串的子串
测试程序:
测试结果:
- public int length():返回指定字符串的长度
测试程序:
测试结果:
- public char charAt(int n )
测试程序:
测试结果:
- public void setCharAt(int n ,char ch)
测试程序:
测试结果:
三、源码阅读
一、StringBuffer、Stringbuilder类的介绍
- StringBuffer、Stringbuilder都是用final关键字修饰,所以不能被继承。二者都extends AbstractStringBuilder implements java.io.Serializable, CharSequence。同时继承同一个父类, 它俩的方法都是差不多的。继承java.io.Serializable说明是可序列化,CharSequence 接口定义了charAt、length、subSequence这三个抽象方法,CharSequence是只读序列接口,String、StringBuffer、Stringbuilder都实现了这一接口,说明它的内容是只读的。
- Stringbuilder:与StringBuffer是兼容的,是不同步的,在单线程时效率一般比StringBuffer高,所以在一般情况下优先考虑效率比较高的StringBuffer。其次最主要的方法是添加和插入,添加是添加在指定字符序列的末尾,插入根据需求插入特定索引位置之后(按照偏移量),sb.append(x)和sb.insert(sb.length(), x)得到结果是一样的。
- StringBuffer:一个线程安全的、可变的字符序列。字符串缓冲区类似于字符串,但可以修改。它的方法都是同步的,这样任何特定实例上的所有操作的行为就好像它们以某种串行顺序发生,而这种顺序与涉及到的每个单独线程进行方法调用的顺序是一致的。同样的最主要的方法是添加和插入。
二、构造器
有三个构造器:
- StringBuffer():初始容量为16的字符串缓冲区
- StringBuffer(int size):构造指定容量的字符串缓冲区 //开发中建议使用,减少重新造对象的开销
- StringBuffer(String str):将内容初始化为指定字符串内容 //字符串构建器的初始容量是16加上 “字符串参数的长度”
三、常用方法
首先当append和insert时,如果原来value数组长度不够,可扩容,扩容原来的2倍+2,同时将原有的数组中的元素复制到新的数组中。