第六章 6.2 StringBuilder

基本知识点 

源码解析

StringBuilder继承了父类AbstractStringBuilder,实现了接口:Appendable:可添加的;Comparable:可比较的字符串;CharSequence:可排序的字符穿;
public final class StringBuilder
    extends AbstractStringBuilder
    implements Appendable, java.io.Serializable, Comparable<StringBuilder>, CharSequence

构造方法:默认容量为16;通过StringBuilder的构造方法传给父类的构造方法

public StringBuilder(int capacity) {
        super(capacity);
    }
AbstractStringBuilder(int capacity) {
        if (COMPACT_STRINGS) {
            value = new byte[capacity];
            coder = LATIN1;
        } else {
            value = StringUTF16.newBytesFor(capacity);
            coder = UTF16;
        }
    }
  •  构造函数定义: - AbstractStringBuilder(int capacity) 是构造函数,接受一个整数参数 capacity ,表示初始容量。
  • 条件判断 if (COMPACT_STRINGS) - COMPACT_STRINGS 是一个静态常量,通常用来指示是否使用紧凑字符串表示。在 Java 9 及以后的版本中,引入了紧凑字符串(Compact Strings)特性,目的是为了节省内存。当 COMPACT_STRINGStrue 时,表示使用紧凑字符串表示。
  • 紧凑字符串的处理: - value = new byte[capacity]; :如果使用紧凑字符串, value 数组被初始化为一个字节数组,大小为 capacity 。这意味着每个字符将使用一个字节来表示,适用于拉丁字符(如英文字母和数字)。 - coder = LATIN1;coder 变量被设置为 LATIN1 ,表示当前使用的编码方式是 Latin-1 编码。
  • 非紧凑字符串的处理: - value = StringUTF16.newBytesFor(capacity); :如果不使用紧凑字符串, value 将被初始化为 UTF-16 编码的字节数组。 StringUTF16.newBytesFor(capacity) 是一个方法,用于根据给定的容量返回适合 UTF-16 的字节数组。 - coder = UTF16;coder 变量被设置为 UTF16 ,表示当前使用的编码方式是 UTF-16 编码。

 append()方法源码解析

测试代码:判断是否扩容

public class Tesr2 {
    public static void main(String[] args) {
        StringBuilder stringBuilder = new StringBuilder();

        stringBuilder.append("hello");
        System.out.println(stringBuilder);
    }
}

第一步:进入StringBuilder的append方法:将hello传递给这个方法

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

第二步:进入父类的这个方法:

                获取hello的长度,count是指目前数组中存储的数量。

                minimumCapacity:目前真实存储的+刚传进来的

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

第三步:进入ensureCapacticyInteral()方法。

                判断是否扩容

coder讲解:

 1. LATIN1:这种编码方式使用一个字节表示一个字符,适用于 ASCII 字符和一些西欧字符。其值通常为 0

2. UTF16:这种编码方式使用两个字节表示一个字符(大部分常用字符),其值通常为 1

coder 的作用 :内存优化:通过使用 coderAbstractStringBuilder 可以根据实际的字符编码方式来优化内存使用。例如,对于只包含 Latin-1 字符的字符串,可以使用更少的内存(一个字节)来存储字符,而对于包含更复杂字符的字符串,则使用 UTF-16 编码(两个字节)。

容量计算:在代码中, coder 被用来计算当前字符数组的实际容量。例如,oldCapacity 的计算是通过右移操作来实现的:

int oldCapacity = value.length >> coder;

如果 coder0 (即 LATIN1 ), oldCapacity 等于 value.length

如果 coder1 (即 UTF16 ), oldCapacity 等于 value.length / 2

原理:二进制右移运算符。

private void ensureCapacityInternal(int minimumCapacity) {
        // overflow-conscious code
        int oldCapacity = value.length >> coder; //计算旧数组的容量
        if (minimumCapacity - oldCapacity > 0) { //如果九数组容量小于最小数组存储量,则扩容
            value = Arrays.copyOf(value,
                    newCapacity(minimumCapacity) << coder);
        }
    }

字符串扩容为:原来的容量*2+2; (没超16按这个算法,超过了按传的字符串扩容,比如:43就扩容到43)

mincapacity为现存储容量;

oldLength = 16;

newLength = 现存储容量;

growth 为增加容量;

length为新的数组容量;

private int newCapacity(int minCapacity) {
        int oldLength = value.length;
        int newLength = minCapacity << coder;
        int growth = newLength - oldLength;
        int length = ArraysSupport.newLength(oldLength, growth, oldLength + (2 << coder));
        if (length == Integer.MAX_VALUE) {
            throw new OutOfMemoryError("Required length exceeds implementation limit");
        }
        return length >> coder;
    }

进入newLength方法:传入参数举例:16,(27,18)最大值。 = 16+27 = 43

 int prefLength = oldLength + Math.max(minGrowth, prefGrowth);

构造方法 

常用方法:增删改,可查看帮助文档。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值