JDK源码-StringBuffer类

上文我们介绍过JDK源码-StringBuilder类StringBuffer同StringBuilder类类似,也是为了解决大量拼接字符串时产生很多中间对象问题,但是它和StringBuilder不同的是所有修改数据的方法都加上了synchronized,保证了线程安全,StringBuilder是线程不安全的,但是保证了线程安全是需要性能的代价的。使用场景:在多线程情况下,如有大量的字符串操作情况,应该使用StringBuffer。如HTTP参数解析和封装等。


一、实现接口

StringBuffer和StringBuilder一样,大部分方法中都会调用父类AbstractStringBuilder方法或属性,实现了Serializable和CharSequence接口。

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

二、成员变量

toStringCache变量用于存储StringBuffer对象维护的字符数组,并且被transient声明,成员变量不参与序列化过程。

 private transient char[] toStringCache;

三、构造方法

StringBuffer构造方法同StringBuilder类类似

	//构造一个空的字符串缓冲区,并且初始化为 16 个字符的容量。
	public StringBuffer() {
        super(16);
    }
    //创建一个空的字符串缓冲区,并且初始化为指定长度 length 的容量。
    public StringBuffer(int capacity) {
        super(capacity);
    }
	//创建一个字符串缓冲区,并将其内容初始化为指定的字符串内容 str,字符串缓冲区的初始容量为 16 加上字符串 str 的长度。
    public StringBuffer(String str) {
        super(str.length() + 16);
        append(str);
    }

    public StringBuffer(CharSequence seq) {
        this(seq.length() + 16);
        append(seq);
    }

四、其他方法

1、writeObject、readObject方法

writeObject(java.io.ObjectOutputStream s)在进行序列化的时候保存StringBuffer对象的状态到一个流中,加了synchronized关键词,保证线程安全。
readObject(java.io.ObjectInputStream s)反序列化时从流中获取StringBuffer对象序列化之前的状态。

	private synchronized void writeObject(java.io.ObjectOutputStream s)
        throws java.io.IOException {
        java.io.ObjectOutputStream.PutField fields = s.putFields();
        fields.put("value", value);
        fields.put("count", count);
        fields.put("shared", false);
        s.writeFields();
    }
    
    private void readObject(java.io.ObjectInputStream s)
        throws java.io.IOException, ClassNotFoundException {
        java.io.ObjectInputStream.GetField fields = s.readFields();
        value = (char[])fields.get("value", null);
        count = fields.get("count", 0);
    }

2、toString()

此方法重写了父类的toString()方法,创建了一个新的字符串对象,加了synchronized关键词,保证线程安全。

	@Override
    public synchronized String toString() {
        if (toStringCache == null) {
            toStringCache = Arrays.copyOfRange(value, 0, count);
        }
        return new String(toStringCache, true);
    }

3、reverse()

此方法重写了父类的reverse(),调用父类的方法实现反转此字符串,toStringCache=null,目的是让其指向一块空内存,保证返回的对象不被StringBuffer的操作所影响。

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

4、delete(int start, int end)

该方法重写了父类的delete方法,调用父类方法指定删除StringBuffer对象中指范围内的子串。该类中还有deleteCharAt(int index),根据角标删除字符,不再一一赘述。toStringCache=null,目的是让其指向一块空内存,保证返回的对象不被StringBuffer的操作所影响。

 	@Override
    public synchronized StringBuffer delete(int start, int end) {
        toStringCache = null;
        super.delete(start, end);
        return this;
    }

5、insert(int index, char[] str, int offset, int len)

该方法接受四个参数,第一个参数表示要插入的索引位置,第二个参数表示要插入的字符数组或者字符串,第三个参数和第四个参数用于截取该原字符数组。toStringCache=null;目的是让其指向一块空内存,保证返回的对象不被StringBuffer的操作所影响。

	@Override
    public synchronized StringBuffer insert(int index, char[] str, int offset, int len){
        toStringCache = null;
        super.insert(index, str, offset, len);
        return this;
    }
    
	public AbstractStringBuilder insert(int index, char[] str, int offset, int len){
        if ((index < 0) || (index > length()))
            throw new StringIndexOutOfBoundsException(index);
        if ((offset < 0) || (len < 0) || (offset > str.length - len))
            throw new StringIndexOutOfBoundsException(
                "offset " + offset + ", len " + len + ", str.length "
                + str.length);
        ensureCapacityInternal(count + len);
        System.arraycopy(value, index, value, index + len, count - index);
        System.arraycopy(str, offset, value, index, len);
        count += len;
        return this;
    }

6、append方法集

StringBuffer中的append方法都是重写了父类中的append方法,toStringCache=null,目的是让其指向一块空内存,保证返回的对象不被StringBuffer的操作所影响。

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

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

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

    @Override
    public synchronized StringBuffer appendCodePoint(int codePoint) {
        toStringCache = null;
        super.appendCodePoint(codePoint);
        return this;
    }

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

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

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


五、总结

1、String是Java中基础且重要的类,由于不可变性,在拼接字符串时候会产生很多无用的中间对象,如果频繁的进行这样的操作对性能有所影响。使用场景:在字符串不经常发生变化的业务场景优先使用String(代码更清晰简洁)。如常量的声明,少量的字符串操作(拼接,删除等)。

2、StringBuffer就是为了解决大量拼接字符串时产生很多中间对象问题,所有修改数据的方法都加上了synchronized,保证了线程安全,但是保证了线程安全是需要性能的代价的。使用场景:在多线程情况下,如有大量的字符串操作情况,应该使用StringBuffer。如HTTP参数解析和封装等。

3、StringBuilder解决了大量拼接字符串时产生很多中间对象问题,并且字符串拼接操作不需要线程安全。StringBuilder和StringBuffer他们其实和String差不多,内部一样都是封装的字符数组,只不过StringBuilder实现了动态扩容机制,可以动态扩容并且可以动态更改value数组中的元素而已,但本质上都是一样的。在单线程情况下,如有大量的字符串操作情况,应该使用StringBuilder来操作字符串。使用场景:不能使用String"+"来拼接而是使用,避免产生大量无用的中间对象,耗费空间且执行效率低下(新建对象、回收对象花费大量时间)。如JSON的封装等。

极化码(Polar Code)是由土耳其科学家Erdal Arıkan在2009年提出的一种新型纠错编码技术。它通过利用信道的极化现象,将虚拟信道分为误码率接近0和接近1/2的两。在编码设计中,数据被放置在误码率极低的信道上,从而实现高效的数据传输。极化码的主要优势在于其理论编码容量能够达到香农限,并且构造方法较为简单。 MATLAB是一种功能强大的数学计算和编程工具,广泛应用于科学研究和工程领域。在极化码的研究中,MATLAB可用于构建编码和解码算法,模拟数据在不同信道条件下的传输效果,验证理论性能,并优化相关参数。 SC(Successive Cancellation,逐位取消)译码是极化码的基本解码方法。它从最可靠的比特开始,依次解码每个虚拟信道,且每个比特的解码结果会影响后续比特的解码,因为它们之间存在依赖关系。虽然SC译码的实现较为简单,但其计算复杂度较高,随着码长的增加,解码时间会线性增长。 SCL(Successive Cancellation List,逐位取消列表)译码是SC译码的改进版本。它通过引入列表机制,同时处理多个路径,从而增强了错误校正能力,并在一定程度上降低了错误率。与SC译码相比,SCL译码虽然需要消耗更多的计算资源,但能够提供更好的性能。 一个完整的MATLAB仿真资源通常包含以下内容: 编码模块:用于实现极化码的生成,包括码字构造和极化矩阵操作等。 信道模型:用于模拟各种通信信道,例如AWGN(加性高斯白噪声)信道或衰落信道。 SC/SCL译码模块:包含SC译码和SCL译码的算法实现。 误码率(BER)计算:通过比较发送和接收的码字,计算误码率,以评估编码性能。 性能曲线绘制:绘制误码率与信噪比(SNR)之间的关系曲线,展示不同译码策略的性能差异。 使用说明:指导用户如何运行仿真,理解代码结构,以及如何调整参数以进行自定义实验。 代码注
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值