第二十七讲 常用类——StringBuffer与StringBuilder

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yerenyuan_pku/article/details/82904410

StringBuffer

概述

我们如果对字符串进行拼接操作的话,每次拼接时,都会构建一个新的String对象,既耗时又浪费空间。而StringBuffer就可以解决这个问题。StringBuffer是一个线程安全的可变字符序列(即字符串缓冲区),它是一个容器。

特点

  1. 长度可以变化;
  2. 可以对内容通过指定的方法进行修改;
  3. 容器对象一般都会具备对容器中的元素进行操作的功能,比如增删改查;
  4. 缓冲区中可以存储不同类型的数据;
  5. 最终缓冲区存储完的数据都会变成字符串。

试看以下代码:

String str = "a" + 4 + "c";

如果我们分析以上代码在内存中的变化情况,可得出以下结论:

  1. 先创建一个字符串缓冲区容器;
  2. 将要组成字符串的元素先存储起来;
  3. 最后将缓冲区中填充的数据变成字符串。

用代码来表示就是:

str = new StringBuffer().append("a").append(4).append("c").toString();

常见操作方法

添加功能

在这里插入图片描述

package cn.liayun;

public class StringBufferDemo {

	public static void main(String[] args) {
		method_add();
	}

	private static void method_add() {
		StringBuffer sb = new StringBuffer();
		sb.append("abc").append(true).append(34);//方法调用链。
		sb.insert(1, "qq");
//		System.out.println(sb.toString());//aqqbctrue34
		System.out.println(sb);//println()方法会将所有要打印的数据先转成字符串再输出,对于对象会自动调用toString()方法。
	}

}

关于输出打印println()和print()方法,我们应注意:它俩会将所有要打印的数据先转成字符串再输出,对于对象会自动调用toString()方法。

删除功能

在这里插入图片描述

package cn.liayun;

public class StringBufferDemo {

	public static void main(String[] args) {
		method_delete();
	}

	private static void method_delete() {
		StringBuffer sb = new StringBuffer("abcde");
		//需求:我要删除bc这个字符串,肿么办?
//		sb.delete(1, 3);
		//需求:清空缓冲区,肿么办?
//		sb.delete(0, sb.length());
		//需求:我要删除c这个字符,肿么办?
		sb.deleteCharAt(2);
		System.out.println(sb);
	}

}

获取功能

在这里插入图片描述

替换功能

在这里插入图片描述

package cn.liayun;

public class StringBufferDemo {

	public static void main(String[] args) {
		method_update();
	}

	private static void method_update() {
		StringBuffer sb = new StringBuffer("abcde");
		// 需求:我要把"bcd"这个数据替换为"java"
//		sb.replace(1, 4, "java");
		// 需求:我要把字符'c'替换为字符'k'
		sb.setCharAt(2, 'k');
		System.out.println(sb);
	}

}

反转功能

在这里插入图片描述

package cn.liayun;

public class StringBufferDemo {

	public static void main(String[] args) {
		method_reverse();
	}

	private static void method_reverse() {
		StringBuffer sb = new StringBuffer();
		sb.append("侠美美是我");
		System.out.println(sb);
		sb.reverse();
		System.out.println(sb);
	}

}

StringBuffer类的内部原理——可变长度的数组

查看API帮助文档,我们发现StringBuffer类有一个空参构造方法,如下:
在这里插入图片描述
API帮助文档对其的解释是:

构造一个其中不带字符的字符串缓冲区,其初始容量为16个字符。

说明字符串缓冲区中维护了一个”可变长度的数组”,所谓”可变长度的数组”其实就是超出内部数组长度后,新建数组长度要是原数组的1.x(1.5或者1.75等)倍数,并将原数组的数据复制到新数组中,并将新的元素也添加到新数组中。

StringBuffer类的练习题

练习一,通过缓冲区,将要打印的矩形组成元素*进行存储后,一次性返回,并输出。

public class StringBufferTest {

    public static void main(String[] args) {
        String rec = draw(8, 5);
        System.out.println(rec);
    }

    /*
     * 画矩形的功能
     * 将需要组成矩形的元素进行临时存储
     */
    public static String draw(int row, int col) {
        // 定义一个临时容器
        StringBuffer sb = new StringBuffer();

        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                sb.append("*");
            }
            sb.append("\n");
        }
        return sb.toString();
    }
}

练习二,将int数组的元素转成字符串,格式为[34, 12, 67]。

public class StringBufferTest {

    public static void main(String[] args) {
        int[] arr = {34, 12, 67, 43, 69};
        String s = toString(arr);
        System.out.println(s);
    }

    /*
     * int数组转成字符串,通过StringBuffer
     */
    public static String toString(int[] arr) {
        StringBuffer sb = new StringBuffer();
        sb.append("[");
        for (int i = 0; i < arr.length; i++) {
            if (i != arr.length - 1) 
                sb.append(arr[i] + ",");
            else 
                sb.append(arr[i] + "]");
        }
        return sb.toString();
    }
}

练习三,以下程序代码,会打印输出什么?

public class StringBufferTest {

    public static void main(String[] args) {
        StringBuffer buf1 = new StringBuffer("hello");
        StringBuffer buf2 = new StringBuffer("java");
        test(buf1, buf2);
        System.out.println(buf1 + "..." + buf2);
    }

    public static void test(StringBuffer buf1, StringBuffer buf2) {
        buf1.append(buf2);
        buf1 = buf2;
    }
}

好久都没分析对象内存结构图了,瞬间就懵逼了,画了如下的一张图之后,才醒悟过来,惭愧!!!
在这里插入图片描述
所以,以上程序运行会在控制台中输出:

hellojava…java

StringBuilder

JDK1.5版本之后,出现了StringBuilder,它和StringBuffer用法一样,所以就不再过多讲解了。不过,StringBuffer与StringBuilder的区别是StringBuffer是线程同步的,而StringBuilder是线程不同步的。
在实际开发中,一般可以建议选择StringBuilder,因为其速度快。但是将StringBuilder的实例用于多个线程时是不安全的。如果需要这样的同步,则建议使用StringBuffer。

猜你喜欢

转载自blog.csdn.net/yerenyuan_pku/article/details/82904410