StringBuffer、String、StringBuilder的用法以及他们的区别

StringBuffer的作用是什么呢?
我们知道String是final类型的,是不可变的对象,我们如果对字符串进行拼接操作,每次拼接,都会构建一个新的String对象,不仅耗时,而且还浪费空间。但是使用 StringBuffer 类时,每次都会对 StringBuffer 对象本身进行操作,而不是生成新的对象并改变对象引用,节省了内存。因此在字符串需要经常改变内容的时候,我们通常不适用String,而是使用StringBuffer。


String和StringBuffer之间如何相互转换?
1、把String转换为StringBuffer:

//法一:通过构造函数
String s = "hello";
StringBuffer sb = new StringBuffer(s);
//法二:通过append()方法
String s = "hello";     
StringBuffer sb2 = new StringBuffer();
sb2.append(s);

2、把StringBuffer转换成String

StringBuffer sb2 = new StringBuffer("love you baby");
sb2.append("假的呢");

String str1 = new String(sb2);      //法一:通过构造方法
String str2 = sb2.toString();       //法二:通过toString()方法

注意:不可以把字符串直接赋值给StringBuffer


StringBuilder和StringBuffer的区别是什么?
java.lang 类 StringBuffer:线程安全的可变字符序列。

public final class StringBuffer extends Object implements Serializable, CharSequence

java.lang 类 StringBuilder:线程不安全的可变的字符序列。

public final class StringBuilder extends Object implements Serializable, CharSequence

StringBuilder提供一个与 StringBuffer 兼容的 API,也就是他们的用法都是一样的。他们的唯一区别就是StringBuilder不保证同步,线程不安全,但是速度快。因此StringBuilder类被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候,因为在大多数实现中,它比 StringBuffer 要快。


String、StringBuffer、StringBuilder的区别是什么呢?
1、String是内容不可变的,而StringBuilder、StringBuffer都是内容可变的。
2、StringBuffer是同步的,数据安全,效率低
3、StringBuilder是不同步的,数据不安全,效率高。

StringBuffer和数组的区别是什么?
都可以看成一个容器,用来装其他的数据。但是StringBuffer的数据最终都会变成一个字符串数据。
而数组可以放置多种数据,比如int型数组、String类型数组、char类型数组等。但数组内部的数据必须是同一种数据类型。



String作为参数传递和StringBuffer作为参数传递有什么区别?
形式参数:
                基本类型:形式参数的改变不影响实际参数
                引用类型:形式参数的改变直接影响实际参数

public class StringBufferDemo {
    public static void main(String[] args) {
        String s1 = "hello";
        String s2 = "you";
        System.out.println(s1 + "---" + s2);            // hello----you
        change(s1, s2);
        System.out.println(s1 + "---" + s2);            // hello----you

        StringBuffer sb1 = new StringBuffer("hello");
        StringBuffer sb2 = new StringBuffer("you");
        System.out.println(sb1 + "---" + sb2);          // hello---you
        change(sb1, sb2);
        System.out.println(sb1 + "---" + sb2);          // hello----youyou

    }

    private static void change(StringBuffer sb1, StringBuffer sb2) {
        sb1 = sb2;
        sb2.append(sb1);
    }

    private static void change(String s1, String s2) {
        s1 = s2;
        s2 = s1 + s2;
    }
}

字符串是常量值,它是一种特殊的引用类型(在这里可以把它当做基本类型来看),它的形参改变对实参没有影响。
而对于StringBuffer的change()方法中直接赋值sb1 = sb2是不会影响sb1的,只有调用append()方法才会影响。
我们可以通过断点调试来看其中的细节:
这里写图片描述

这里写图片描述



StringBuffer的一些方法:
StringBuffer() :构造一个其中不带字符的字符串缓冲区,其初始容量为 16 个字符。

StringBuffer sb = new StringBuffer();
System.out.println("sb:" + sb);                                     //sb:
System.out.println("sb.capacity():"+sb.capacity());                 //sb.capacity():16
System.out.println("sb.length():"+sb.length());                     //sb.length():0


StringBuffer(int capacity) :构造一个不带字符,但具有指定初始容量的字符串缓冲区。

StringBuffer sb1 = new StringBuffer(50);
System.out.println("sb1:" + sb1);                               //sb1:
System.out.println("sb1.capacity():"+sb1.capacity());           //sb1.capacity():50
System.out.println("sb1.length():"+sb1.length());               //sb1.length():0


StringBuffer(String str) :构造一个字符串缓冲区,并将其内容初始化为指定的字符串内容。

StringBuffer sb2 = new StringBuffer("helloya");
System.out.println("sb2:" + sb2);                               //sb2:helloya
System.out.println("sb2.capacity():"+sb2.capacity());           //sb2.capacity():23  
System.out.println("sb2.length():"+sb2.length());               //sb2.length():7

输出:这里的容量为什么是23呢?23=16+7,初始容量+字符串的长度。看下面的源码就更清楚了。


public int capacity():返回当前容量。容量指可用于最新插入的字符的存储量,超过这一容量就需要再次进行分配。
public int length():返回长度(字符数)。
我们可以看一下不同的构造方法对应的源码,方便我们理解容量的概念。

public StringBuffer() {
  super(16);
}
public StringBuffer(int capacity) {
   super(capacity);
}
public StringBuffer(String str) {
    super(str.length() + 16);
    append(str);
}


public StringBuffer append(String str):可以把任意类型数据添加到字符串缓冲区里面。并返回字符串缓冲区本身
无论是boolean还是int等其他类型的参数,参数都将被转换成字符串,就好象使用了 String.valueOf 方法一样。然后,将所得字符串中的字符追加到此序列。
注意:进行append方法拼接之后返回的是字符串缓冲区本身。

StringBuffer sb = new StringBuffer();
StringBuffer sb1 = sb.append("hello");
StringBuffer sb2 = sb.append(123);
sb.append(true).append(34.12).append("hi");

System.out.println("sb:" + sb);                 //sb:hello123true34.12hi
System.out.println("sb1:" + sb1);               //sb1:hello123true34.12hi
System.out.println("sb2:" + sb2);               //sb2:hello123true34.12hi
System.out.println(sb == sb1);                  //true
System.out.println(sb == sb2);                  //true


public StringBuffer insert(int offset,String str):将字符串插入此字符序列中。
按顺序将 String 参数中的字符插入此序列中的指定位置,将该位置处原来的字符向后移,此序列将增加该参数的长度。如果 str 为 null,则向此序列中追加 4 个字符 “null”。
可以将任意类型的数据插入到字符串缓冲区里面,并返回字符串缓冲区本身。

StringBuffer sb = new StringBuffer();

sb.insert(0, "null");                               
System.out.println(sb);                             //null

sb.insert(1, "hehe");
System.out.println(sb);                             //nheheull


public StringBuffer deleteCharAt(int index):删除指定位置值的字符,并返回字符串缓冲区本身。

StringBuffer sb = new StringBuffer();
sb.append("hello").append("girl!");
sb.deleteCharAt(1);                     // 删除字符e
sb.deleteCharAt(1);                     // 删除字符l(因为上面的e已经被删除了,因此l字符就跑到了索引为1的位置上了)
System.out.println(sb);                 //hlogirl!


public StringBuffer delete(int start, int end):移除此序列的子字符串中的字符。该子字符串从指定的 start 处开始,一直到索引 end - 1 处的字符,如果不存在这种字符,则一直到序列尾部。如果 start 等于 end,则不发生任何更改。

StringBuffer sb = new StringBuffer();
sb.append("hello").append("girl!");

sb.delete(5, 9);                            //删除girl这个单词            
System.out.println("sb:"+sb);               //sb:hello! 

sb.delete(0, sb.length());                  //删除所有数据
System.out.println("sb:"+sb);               //sb:


public StringBuffer replace(int start,int end, String str):使用给定 str 替换此序列从指定的 start 处开始,一直到索引 end - 1 处的字符,如果不存在这种字符,则一直到序列尾部。先将子字符串中的字符移除,然后将指定的 String 插入 start。(如果需要,序列将延长以适应指定的字符串。)

StringBuffer sb = new StringBuffer();
sb.append("hello").append("girl!");

sb.replace(0, 5, "hi");                 // 把hello替换成hi
System.out.println("sb:" + sb);         // sb:higirl!


public StringBuffer reverse()将此字符序列用其反转形式取代。

StringBuffer sb = new StringBuffer();
sb.append("hello").append("girl!");

sb.reverse();
System.out.println("sb:" + sb);         //sb:!lrigolleh


public String substring(int start):返回一个新的 String,它包含此字符序列当前所包含的字符子序列。该子字符串始于指定索引处的字符,一直到此字符串末尾。 注意:返回的是一个String,但是字符串缓冲区本身不变的。

StringBuffer sb = new StringBuffer();
sb.append("hello").append("girl!");

String str = sb.substring(5);
System.out.println("str:"+str);         //girl!
System.out.println("sb:" + sb);         //sb:hellogirl!     


public String substring(int start, int end)返回一个新的 String,它包含此序列当前所包含的字符子序列。该子字符串从指定的 start 处开始,一直到索引 end - 1 处的字符。
用法同上。我就不举例了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值