java中String类、StringBuilder、StringBuffer的区别(部分API)

String类内部是一个不可变的字符序列,以jdk7为例,String类源代码如下:

public final class String  {
/** The value is used for character storage. */
private final char value[];
public String() {
        this.value = new char[0];
}
public String(String original) {
        this.value = original.value;
}
public String(char value[]) {
        this.value = Arrays.copyOf(value, value.length);
}
public int length() {
        return value.length;
}
public boolean isEmpty() {
        return value.length == 0;
}
public char charAt(int index) {
        if ((index < 0) || (index >= value.length)) {
            throw new StringIndexOutOfBoundsException(index);
        }
        return value[index];
}
public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof String) {
            String anotherString = (String) anObject;
            int n = value.length;
            if (n == anotherString.value.length) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                while (n-- != 0) {
                    if (v1[i] != v2[i])
                            return false;
                    i++;
                }
                return true;
            }
        }
        return false;
 }

}

通过jdk源代码可以发现String类的内部是通过char[] value即字符数组实现的。String类本身是final类型的,不可以被其他类继承;内部的字符数组也是final类型的,只能赋值一次。

String类提供了查找功能相关方法:endsWith, startsWith, indexOf,lastIndexOf。

提供比较功能的方法:equals, equalsIgnoreCase,  compareTo。

将基本类型数据转为字符串类型:public static String valueOf(…)。

可以调用String类的方法创建并返回一个新的字符串:concat, replace,  substring, toLowerCase, toUpperCase, trim。

在使用过程中尽量避免在for里面进行"+"操作

String gh = new String("a");
for(int i=0;i<1000;i++){
    gh += i;
}
System.out.printf(gh);

这种拼接字符串的代码很浪费空间,每个线程都会在for里面产生n个对象;另外new String("a")会在堆空间里面产生2个对象,分别是堆空间new出来的String对象,还有常量池里面的"a"对象。

StringBuilder特点:线程不安全、效率高。

StringBuffer特点:线程安全、效率低。由于一般情况下我们使用的是局部变量,所以推荐使用效率高的StringBuilder。

两者都是抽象类AbstractStringBuilder的子类,AbstractStringBuilder内部是char[] value实现的,该字符数组并没有使用private final进行修饰(即可变)。源代码如下:

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

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

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

    /**
     * Creates an AbstractStringBuilder of the specified capacity.
     */
    AbstractStringBuilder(int capacity) {
        value = new char[capacity];
    }

所以两者都是可变字符序列。查看StringBuffer的源代码,

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

    /**
     * A cache of the last value returned by toString. Cleared
     * whenever the StringBuffer is modified.
     */
    private transient char[] toStringCache;

    /** use serialVersionUID from JDK 1.0.2 for interoperability */
    static final long serialVersionUID = 3388685877147921107L;

    /**
     * Constructs a string buffer with no characters in it and an
     * initial capacity of 16 characters.
     */
    public StringBuffer() {
        super(16);
    }

通过其构造函数可见StringBuffer默认是16位长度的字符数组。如果需要存放特别长(超过16位)的子字符串时怎么办的呢,具体的扩容机制在AbstractStringBuilder类,源代码是:

    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;
    }

之所以认为StringBuffer是线程安全的,是因为它里面的方法都是同步方法,源代码如下:

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

这两个类中每调用一次处理字符串的方法都会返回一次this属性,即返回char数组本身,说明了这两个类都是可变字符序列,这两个类中的方法是支持链式调用的,源代码见append方法返回值:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值