String、StringBuffer和StringBuilder的使用和理解

一、String类表示字符串。Java程序中的所有字符串文字(如“abc”)都作为此类的实例实现。 字符串是常量;它们的值在创建后不能更改。字符串缓冲区支持可变字符串。因为字符串对象是不可变的,所以它们可以共享。例如:

字符串str=“abc”; 相当于: char data[]={'a','b','c'};

因为字符串的底层是基于char数组实现,所以一些基于数组的操作模式字符串也是拥有的,例如:

    public static void main(String[] args) {
        String str = "中华人民共和国";
        //字符串的长度
        System.out.println(str.length());
        //根据下标查询对应的字符
        System.out.println(str.charAt(1));
        //查询字符串首次出现的下标
        System.out.println(str.indexOf("人"));
        //截取字符串
        System.out.println("str.substring(2,4) = " + str.substring(2,4));
        
    }

以上便是基于数组的特性来衍生的功能。更多关于字符串的操作请参考源码或者官方文档。

需要注意的是,因为字符串是不可修改的常量,所以每次对字符串的修改都是创建了一个新的字符串,并将其对象的引用地址重新指向了新的字符串。

二、StringBuffer 是线程安全的可变字符序列。字符串缓冲区类似于字符串,但可以修改。在任何时间点,它都包含一些特定的字符序列,但序列的长度和内容可以通过某些方法调用来更改。

它提供的方法都经过synchronized关键字进行了修饰,意味着它是多线程情况下是线程安全的。

部分源码如下:

 public final class StringBuffer
    extends AbstractStringBuilder
    implements java.io.Serializable, Comparable<StringBuffer>, CharSequence
{    

    @Override
    public synchronized int length() {return count;}
    @Override
    public synchronized int capacity() {return super.capacity();}
    @Override
    public synchronized void ensureCapacity(int minimumCapacity) {
        super.ensureCapacity(minimumCapacity);
    }

    @Override
    public synchronized void trimToSize() { super.trimToSize();}

    @Override
    public synchronized void setLength(int newLength) {
        toStringCache = null;
        super.setLength(newLength);
    }
    @Override
    public synchronized char charAt(int index) {return super.charAt(index);}
    
    @Override
    public synchronized StringBuffer append(Object obj) {
        toStringCache = null;
        super.append(String.valueOf(obj));
        return this;
    }

    @Override
    @IntrinsicCandidate
    public synchronized StringBuffer append(String str) {
        toStringCache = null;
        super.append(str);
        return this;
    }
}

StringBuffer继承于AbstractStringBuilder类,其本质是一个字节数组。部分源码如下:

abstract class AbstractStringBuilder implements Appendable, CharSequence {
    /**
     * The value is used for character storage.
     */
    byte[] value;

    /**
     * The id of the encoding used to encode the bytes in {@code value}.
     */
    byte coder;

    /**
     * The count is the number of characters used.
     */
    int count;

    private static final byte[] EMPTYVALUE = new byte[0];

    /**
     * This no-arg constructor is necessary for serialization of subclasses.
     */
    AbstractStringBuilder() {
        value = EMPTYVALUE;
    }

    /**
     * Creates an AbstractStringBuilder of the specified capacity.
     */
    AbstractStringBuilder(int capacity) {
        if (COMPACT_STRINGS) {
            value = new byte[capacity];
            coder = LATIN1;
        } else {
            value = StringUTF16.newBytesFor(capacity);
            coder = UTF16;
        }
    }

    public AbstractStringBuilder append(String str) {
        if (str == null) {
            return appendNull();
        }
        int len = str.length();
        ensureCapacityInternal(count + len);
        putStringAt(count, str);
        count += len;
        return this;
    }
}

注:该类的设计和集合中ArrayList设计思路一致。

三、StringBuilder类和StringBuffer实现方法一样,唯一区别的是StringBuilder得调用方法没有被synchronized关键字修饰,提高了字符串的操作效率,也意味着StringBuilder在多线程情况是线程不安全的。

部分源码如下:

public final class StringBuilder
    extends AbstractStringBuilder
    implements java.io.Serializable, Comparable<StringBuilder>, CharSequence
{

    @Override
    public int compareTo(StringBuilder another) {
        return super.compareTo(another);
    }

    @Override
    public StringBuilder append(Object obj) {
        return append(String.valueOf(obj));
    }

    @Override
    @IntrinsicCandidate
    public StringBuilder append(String str) {
        super.append(str);
        return this;
    }

    
    public StringBuilder append(StringBuffer sb) {
        super.append(sb);
        return this;
    }

    @Override
    public StringBuilder append(CharSequence s) {
        super.append(s);
        return this;
    }

    /**
     * @throws     IndexOutOfBoundsException {@inheritDoc}
     */
    @Override
    public StringBuilder append(CharSequence s, int start, int end) {
        super.append(s, start, end);
        return this;
    }

    @Override
    public StringBuilder append(char[] str) {
        super.append(str);
        return this;
    }

    /**
     * @throws IndexOutOfBoundsException {@inheritDoc}
     */
    @Override
    public StringBuilder append(char[] str, int offset, int len) {
        super.append(str, offset, len);
        return this;
    }

    @Override
    public StringBuilder append(boolean b) {
        super.append(b);
        return this;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
StringStringBufferStringBuilder都是Java中用于处理字符串的类。 String是一个不可变的字符串类,也就是说一旦创建了一个String对象,它的值就不能被修改。每次对String进行修改操作时,都会创建一个新的String对象,这样会浪费内存空间和时间。因此,当需要频繁地对字符串进行修改时,使用String并不高效。 StringBufferStringBuilder是可变的字符串类,它们可以被用来进行字符串的修改操作。StringBufferStringBuilder的主要区别在于StringBuffer是线程安全的,而StringBuilder是非线程安全的。这意味着在多线程环境下,如果有多个线程同时访问一个StringBuffer对象,它们是安全的;而多个线程同时访问一个StringBuilder对象时,可能会导致数据错乱。 使用StringBufferStringBuilder的场景通常是在需要频繁地对字符串进行修改的情况下。例如,在循环中拼接字符串、在递归函数中修改字符串等情况下,使用StringBufferStringBuilder可以提高性能。 如果需要将StringBufferStringBuilder转换为String对象,可以使用两种方式。一种是调用它们的toString()方法,将其转换为String对象。另一种是使用String的构造器String(StringBuffer buffer)来创建一个新的String对象,将StringBufferStringBuilder的内容复制到新的String对象中。 总结起来,String是不可变的字符串类,而StringBufferStringBuilder是可变的字符串类,适用于需要频繁修改字符串的场景。转换为String对象可以通过调用toString()方法或使用String的构造器来实现。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值