StringBuilder append方法源码分析

本文分析了Java中StringBuilder的append方法,揭示了其在处理字符串连接时如何通过避免中间变量提高性能。通过查看AbstractStringBuilder的源码,了解到数据存储在char数组中,并详细解释了append方法的工作流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >



问题来源:在Java中,使用String str = “a" + "b" + “c"的时候,编译器会自动优化,使用StringBuilder来完成连接操作,那么,StringBuffer为什么比起String性能更高呢?

首先,以上字符串的连接,按照Java中字符串是常量不可更改的特性,理应是先有一个新的变量指向"a",而后再创建一个变量,指向"a + b",依次类推。但是按照这种方法,会产生很多没用的中间变量,严重影响了性能,所以实际中,编译器会自动创建StringBuilder优化性能。

StringBuilder中的append方法源码:

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

在AbstractStringBuilder中,数据是放在一个 char[ ] value的数组里的。 

由于StringBuffer继承自AbstractStringBuilder,所以查看父类的append方法:

 public AbstractStringBuilder append(String str) {
        if (str == null)
            return appendNull();
        int len = str.length();
        ensureCapacityInternal(count + len);<span style="white-space:pre">		</span>//这里传入的参数是增加字符串以后所需要的数组的最小长度
        str.getChars(0, len, value, count);
        count += len;
        return this;
    }
对该方法的进一步理解——ensureCapacityInternal()源码:

 /**
     * This method has the same contract as ensureCapacity, but is
     * never synchronized.
     */
    private void ensureCapacityInternal(int minimumCapacity) {
        // overflow-conscious code
        if (minimumCapacity - value.length > 0)<span style="white-space:pre">		</span>//如果最小长度大于原来的数据长度,则扩容
            expandCapacity(minimumCapacity);
    }

    /**
     * This implements the expansion semantics of ensureCapacity with no
     * size check or synchronization.这里是扩容的具体实现
     */
    void expandCapacity(int minimumCapacity) {
        int newCapacity = value.length * 2 + 2;<span style="white-space:pre">		</span>//注意这里的扩容不是简单的用 原始长度 + 新字符串长度
        if (newCapacity - minimumCapacity < 0)
            newCapacity = minimumCapacity;
        if (newCapacity < 0) {
            if (minimumCapacity < 0) // overflow
                throw new OutOfMemoryError();
            newCapacity = Integer.MAX_VALUE;
        }
        value = Arrays.copyOf(value, newCapacity);<span style="white-space:pre">	</span>//这里是通过Arrays的copyof方法,构造一个新的长度的数组,并把原来的数据拷贝进去
    }<span style="white-space:pre">							</span>//通过这样的方法,实现了数组的扩容
对该方法的进一步理解——String中的getChars方法:

public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) {
        if (srcBegin < 0) {
            throw new StringIndexOutOfBoundsException(srcBegin);
        }
        if (srcEnd > value.length) {
            throw new StringIndexOutOfBoundsException(srcEnd);
        }
        if (srcBegin > srcEnd) {
            throw new StringIndexOutOfBoundsException(srcEnd - srcBegin);
        }
        System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);
    }
这个方法的目的是,从数组dst[ ]的dstBegin开始,将原始数据从srcBegin开始到srcEnd-1结束的字符串拷贝进来。此处String中的value,指的是String的原始字符串,即
调用这个方法的那个字符串。

以上,即为StringBuffer中append方法的完整过程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值