java常用类————StringBuffer/StringBuilder

一、String、StringBuffer和StringBuilder的区别
  • 相同点:
    • 都是与字符串相关的类
    • 底层结构都是使用 char[] 存储字符串
  • 不同点:
    • String是不可变的字符序列
    • StringBuffer是可变的字符序列,线程安全,但效率偏低
    • StringBuilder是可变的字符序列,线程不安全,但效率高

StringBuilder和StringBuffer的不同仅仅是,StringBuilder的所有方法都是线程安全的,这篇文章仅仅使用StringBuffer作为参考分析,两者方法的调用都是一样的

二、StringBuffer源码分析
1. 成员变量
 public final class StringBuffer
    extends AbstractStringBuilder
    implements java.io.Serializable, CharSequence
{
	// StringBuffer类的成员变量字符数组没有使用final修饰,因此它是可变的
    private transient char[] toStringCache;

    static final long serialVersionUID = 3388685877147921107L;
	// 其他构造器
2. 构造器
(1)源码中字符数组的大小如何初始化?

1. StringBuffer对象在构建过程中,默认的字符数组value的大小为16:

	// StringBuffer源码的构造器
	public StringBuffer() {
	        super(16);
	    }
	// ——————————————————————————————————————————————————————————
	// StringBuffer的父类AbstractStringBuilder对应的构造器:
	AbstractStringBuilder(int capacity) {
	        value = new char[capacity];
	    }

2. 对StringBuffer的构造器传入一个字符串,value的大小为字符串长度+16:

  public StringBuffer(String str) {
        super(str.length() + 16);
        append(str); // 创建好value后将字符串添加给value
    }
   // ——————————————————————————————————————————————————————————
   // 对应父类中的构造器
  AbstractStringBuilder(int capacity) {
        value = new char[capacity];
    }

3. 如果想要字符串可以改变,又不想频繁扩容,可以给构造器传入一个整数用来创建想要容量的value:

	public StringBuffer(int capacity) {
		super(capacity);
	}
	// ——————————————————————————————————————————————————————————
	// 在父类中,传入的整数作为value的长度
	AbstractStringBuilder(int capacity) {
		value = new char[capacity];
    }
(2)字符串的长度
  • StringBuffer中length()方法返回的不是字符数组value的长度,返回的是count,该变量用于动态的计算字符串的长度
	StringBuffer strbuff = new StringBuffer("breaking bad");
    System.out.println( strbuff.length()); // strbuff.length() 等于多少?
    // ——————————————————————————————————————————————————————————
	// StringBuffer源码的length():
    public synchronized int length() {
       return count; // count是在父类中定义的成员变量
    }
    // ——————————————————————————————————————————————————————————
    // 父类AbstractStringBuilder 中的count:
    abstract class AbstractStringBuilder implements Appendable, CharSequence {
		// The value is used for character storage.
		char[] value;
		
		// The count is the number of characters used. 
		// 使用count统计字符串长度
		int count
		// 其他部分源码
(3)如果字符数组的容量填满了,该如何扩容?
  • 如果value的剩余空间不足以添加一个新的字符串,通常情况下,源码中扩容的策略有两种:
    • 将原字符串长度+新添加的字符串长度得到的值记作minCapacity
    1. 将value数组的长度*2+2得到新的数组长度为newCapacity ,如果newCapacity 的长度大于minCapacity,则newCapacity 为扩容后的字符数组value的长度
    2. 如果由1得到的newCapacity 依旧小于minCapacity,则此时直接将minCapacity作为新的字符数组value的长度。
    // 由于源码中牵扯的方法比较多,这里放最核心的代码
	StringBuffer strbuff = new StringBuffer("breaking bad:");
	strbuff.append("Heisenberg");
    // ——————————————————————————————————————————————————————————
	// 其中minCapacity原字符串长度+要添加的字符串长度
	// newCapacity为要扩容的数组长度
	private int newCapacity(int minCapacity) {
	  // overflow-conscious code
	   int newCapacity = (value.length << 1) + 2;
	   if (newCapacity - minCapacity < 0) {
	       newCapacity = minCapacity;
	   }
	   return (newCapacity <= 0 || MAX_ARRAY_SIZE - newCapacity < 0)
	       ? hugeCapacity(minCapacity)
	       : newCapacity;
	}
三. 常用方法
  1. append() 添加
  2. deleteCharAt() 删除指定索引处的字符
  3. delete() 删除一段字符

方法测试

	StringBuffer strbuff = new StringBuffer("breaking bad:");
	strbuff.append("\"Heisenberg\"");
	strbuff.append(2021);
	strbuff.append('Q');
	strbuff.append("JavaEE");
	System.out.println(strbuff); // 输出:
	strbuff.deleteCharAt(strbuff.indexOf("2021"));
	System.out.println(strbuff); // 输出:
	strbuff.delete(25,strbuff.length());
	System.out.println(strbuff); // 输出:
// 运行结果:
breaking bad:"Heisenberg"2021QJavaEE
breaking bad:"Heisenberg"021QJavaEE
breaking bad:"Heisenberg"
  1. replace() 将指定左闭右开区间内的字符成另一串字符
  2. setCharAt() 更改指定索引处的字符

方法测试

	StringBuffer strbuff = new StringBuffer("breaking bad:\"Heisenberg\"");
	strbuff.setCharAt(0,'B'); 
	System.out.println(strbuff);
	strbuff.replace(14,24,"Walter Hartwell White");
	System.out.println(strbuff);
// 运行结果:
Breaking bad:"Heisenberg"
Breaking bad:"Walter Hartwell White"
  1. charAt() 查找指定索引处的字符并返回
  2. indexOf(String str) 查找字符串中首次出现指定子字符串的索引
  3. indexOf(String str,int index) 查找字符串index位置后,子串str首次出现的索引
  4. insert() 在指定索引处进行插入一串字符
        StringBuffer strbuff = new StringBuffer("Breaking bad:\"Heisenberg\"");
        for (int i = 0; i < strbuff.length(); i++) {
            System.out.print(strbuff.charAt(i));
            System.out.print(' ');
        }
        System.out.println();
        System.out.println("strbuff.indexOf(\"Heisen\") = " + strbuff.indexOf("Heisen"));
        strbuff.insert(strbuff.length()-1,"_");
        System.out.println("strbuff = " + strbuff);
// 运行结果:
B r e a k i n g   b a d : " H e i s e n b e r g " 
strbuff.indexOf("Heisen") = 14
strbuff = Breaking bad:"Heisenberg_"
  1. reverse() 对字符串进行反转
        StringBuffer strbuff = new StringBuffer("Breaking bad:\"Heisenberg\"");
        System.out.println(strbuff.reverse());
// 运行结果
"grebnesieH":dab gnikaerB
  1. substring() 截取一段子字符串
        StringBuffer strbuff = new StringBuffer("Breaking bad:\"Heisenberg\"");
        String str = strbuff.substring(14,24);
        System.out.println("str = " + str);
        System.out.println("strbuff = " + strbuff);
// 运行结果
str = Heisenberg
strbuff = Breaking bad:"Heisenberg"
四、StringBuffer/StringBuilder 与String的转换
  • StringBuffer/StringBuilder转化成String:String.valueOf(str);
  • String转化成StringBuffer/StringBuilder:new StringBuffer(str)/new StringBuilder(str)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值