java之AbstractStringBuilder类详解

Posted SQP51312

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java之AbstractStringBuilder类详解相关的知识,希望对你有一定的参考价值。

目录

AbstractStringBuilder类

字段

构造器

方法
  public abstract String toString()
扩充容量 void  expandCapacity(int minimumCapacity)
  public int  length()
  public int  capacity()
  public void  ensureCapacity(int minimumCapacity)
反转 public AbstractStringBuilder reverse()
添加 public AbstractStringBuilder  append(String str)

public AbstractStringBuilder  append(StringBuffer sb)

public AbstractStringBuilder  append(Object obj)

public AbstractStringBuilder  append(CharSequence s)

public AbstractStringBuilder  append(CharSequence s, int start, int end) 

public AbstractStringBuilder  append(char str[])

public AbstractStringBuilder  append(char str[], int offset, int len)

public AbstractStringBuilder  append(boolean b)

public AbstractStringBuilder  append(char c)

public AbstractStringBuilder  append(int i) 

public AbstractStringBuilder  append(long l)

public AbstractStringBuilder  append(float f)

public AbstractStringBuilder append(double d) 

删除 public AbstractStringBuilder  delete(int start, int end) 
插入

public AbstractStringBuilder insert(int offset, String str)

public AbstractStringBuilder insert(int offset, Object obj) 

public AbstractStringBuilder insert(int offset, boolean b) 

public AbstractStringBuilder insert(int offset, int i) 

public AbstractStringBuilder insert(int offset, long l)

public AbstractStringBuilder insert(int offset, float f)

public AbstractStringBuilder insert(int offset, double d)

public AbstractStringBuilder insert(int offset, char c)

public AbstractStringBuilder insert(int offset, char str[])

public AbstractStringBuilder insert(int dstOffset, CharSequence s)

public AbstractStringBuilder insert(int index, char str[], int offset,int len)

public AbstractStringBuilder insert(int dstOffset, CharSequence s,int start, int end)

替换 public AbstractStringBuilder replace(int start, int end, String str)
获取子序列

public String substring(int start, int end)

public String substring(int start)

public CharSequence subSequence(int start, int end)

调整空间

public void trimToSize()

设置长度

public void setLength(int newLength)

获取字符

public char charAt(int index)

修改字符

public void setCharAt(int index, char ch)

删除字符

public AbstractStringBuilder deleteCharAt(int index)

 

public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin)

 

public int codePointAt(int index)

 

public int codePointBefore(int index)

 

public int codePointCount(int beginIndex, int endIndex) 

 

public int offsetByCodePoints(int index, int codePointOffset)

 

public AbstractStringBuilder appendCodePoint(int codePoint)

相关链接  

 

AbstractStringBuilder类

位置:java.lang包中

声明 abstract class AbstractStringBuilderimplements Appendable, CharSequence 

AbstractStringBuilder 类有abstract 修饰,可知它不能被实例化。

AbstractStringBuilder 类有两个子类:StringBuilder和StringBuffer。

字段

        /**
         * The value is used for character storage.
         */
        char value[];
        /**
         * The count is the number of characters used.
         */
        int count;

 

构造器

1、无参构造器

    AbstractStringBuilder() {
    }

2、创建abstractstringbuilder实现类的对象时指定缓冲区大小为capacity。

    AbstractStringBuilder(int capacity) {
        value = new char[capacity];
    }

当子类StringBuilder或StringBuffer实例化时,会在构造器中调用此构造器。

扩充容量

void expandCapacity(int minimumCapacity)

此方法有包访问权限,类中有多个方法会调用此方法,在容量不足时扩充容量。

源码:

    void expandCapacity(int minimumCapacity) {
        int newCapacity = (value.length + 1) * 2;
        if (newCapacity < 0) {
            newCapacity = Integer.MAX_VALUE;
        } else if (minimumCapacity > newCapacity) {
            newCapacity = minimumCapacity;
        }
        value = Arrays.copyOf(value, newCapacity);
    }

将缓冲区长度加1乘2的值赋予变量newCapacity, 然后将此值与指定的值比较,将较大值确定为缓冲区的新容量;然后调用Arrays类的copyof方法,此方法会创建一个新数组,然后将原数组中的字符全部复制进新数组中。

 

ensureCapacity(int minimumCapacity)

public void ensureCapacity(int minimumCapacity)

确保容量至少等于指定的最小值。如果当前容量小于指定值,则创建新数组,新数组的容量为指定值的两倍加2;如果当前容量不小于指定值,则直接不做处理。

源码:

    public void ensureCapacity(int minimumCapacity) {
        if (minimumCapacity > value.length) {
            expandCapacity(minimumCapacity);
        }
    }

测试:

        StringBuffer s = new StringBuffer();
        System.out.println("容量:" + s.capacity());// 容量:16
        s.ensureCapacity(10);
        System.out.println("容量:" + s.capacity());// 容量:16
        s.ensureCapacity(30);
        System.out.println("容量:" + s.capacity());// 容量:34
        s.ensureCapacity(80);
        System.out.println("容量:" + s.capacity());// 容量:80

 

length()

public int length()

返回缓冲区中的代码单元数。

注意:此方法返回的并不是字符的数量,因为对于Unicode增补字符1个代码点对应2个代码单元。可以通过codePointCount方法获取字符数。

源码:

    public int length() {
        return count;
    }

Unicode标量值测试:

        StringBuffer s = new StringBuffer();
        System.out.println(s.append(\'a\').append(\'b\').length());// 2
        System.out.println(s.codePointCount(0, s.length()));// 2

Unicode增补字符测试:

        StringBuffer s = new StringBuffer();
        System.out.println(s.append(\'\\ud800\').append(\'\\udc00\').length());// 2
        System.out.println(s.codePointCount(0, s.length()));// 1

 

capacity()

public int capacity()

返回数组value的容量。

源码:

    public int capacity() {
        return value.length;
    }

测试:

        System.out.println(s.capacity());// 10
        System.out.println(s.length());// 0

反转

public AbstractStringBuilder reverse()

将字符序列反转。

问题:我们知道对于Unicode 标量值只需要1个char变量即可表示,但对于增补字符却需要2个char变量,反转时如何正确的处理这些字符?

查看reverse源码:

    public AbstractStringBuilder reverse() {
        boolean hasSurrogate = false;
        int n = count - 1;
        for (int j = (n - 1) >> 1; j >= 0; --j) {
            char temp = value[j];
            char temp2 = value[n - j];
            if (!hasSurrogate) {
                hasSurrogate = (temp >= Character.MIN_SURROGATE && temp <= Character.MAX_SURROGATE)
                        || (temp2 >= Character.MIN_SURROGATE && temp2 <= Character.MAX_SURROGATE);
            }
            value[j] = temp2;
            value[n - j] = temp;
        }
        if (hasSurrogate) {
            // Reverse back all valid surrogate pairs
            for (int i = 0; i < count - 1; i++) {
                char c2 = value[i];
                if (Character.isLowSurrogate(c2)) {
                    char c1 = value[i + 1];
                    if (Character.isHighSurrogate(c1)) {
                        value[i++] = c1;
                        value[i] = c2;
                    }
                }
            }
        }
        return this;
    }

可知此方法主要有两步:

1、用一个循环反转序列;并在每次循环时判断调换的两个字符是否有一个字符在\\uD800和\\uDFFF之间,如果有则置hasSurrogate的值为true。

2、若hasSurrogate的值为true,则进入第二个循环,调用Character类的isLowSurrogate和isHighSurrogate方法判断,将反转的增补字符再次反转,以此可确保字符的正确性。

 

添加

 

append(String str)

public AbstractStringBuilder append(String str)

添加指定的字符串到字符序列。                    

源码:

    public AbstractStringBuilder append(String str) {
        if (str == null)
            str = "null";
        int len = str.length();
        if (len == 0)
            return this;
        int newCount = count + len;
        if (newCount > value.length)
            expandCapacity(newCount);
        str.getChars(0, len, value, count);
        count = newCount;
        return this;
    }

此方法内部处理流程:

1、当待加入字符串str为null时,赋值:str == "null";

2、当str为空串时,return this;

3、判断缓冲区目前的空余空间能否容下待加入字符串str,如果不能则扩容;并指定容量为新字符串的长度(count + len),但此容量并非最终容量,还需往下判断,详见expandCapacity方法

4、调用String类中getChars方法将待加入的字符串str复制进新缓冲区中。

5、更改AbstractStringBuilder实现类对象的状态count,并返回当前对象的引用,所以可实现多个append方法连用。

append(StringBuffer sb)

public AbstractStringBuilder append(StringBuffer sb)

源码:

    public AbstractStringBuilder append(StringBuffer sb) {
        if (sb == null)
            return append("null");
        int len = sb.length();
        int newCount = count + len;
        if (newCount > value.length)
            expandCapacity(newCount);
        sb.getChars(0, len, value, count);
        count = newCount;
        return this;
    }

此方法与上一个方法代码上有些差异,但思路类似。

append(Object obj)

public AbstractStringBuilder append(Object obj)

追加对象参数的字符串表示形式。

源码:

    public AbstractStringBuilder append(Object obj) {
        return append(String.valueOf(obj));
    }

内部调用的append(String str)方法,添加Object 对象的字符串形式。

append(CharSequence s)

public AbstractStringBuilder append(CharSequence s)

添加字符序列。

源码:

    public AbstractStringBuilder append(CharSequence s) {
        if (s == null)
            s = "null";
        if (s instanceof String)
            return this.append((String) s);
        if (s instanceof StringBuffer)
            return this.append((StringBuffer) s);
        return this.append(s, 0, s.length());  
    }

append(CharSequence s, int start, int end) 

public AbstractStringBuilder append(CharSequence s, int start, int end) 

追加指定字符序列s从start开始,到end结束的子序列。

append(char str[])

public AbstractStringBuilder append(char str[])

追加指定字符数组str。

append(char str[], int offset, int len)

public AbstractStringBuilder append(char str[], int offset, int len)

添加字符数组str从偏移量offset开始,长度为end的子数组。

append(boolean b)

public AbstractStringBuilder append(boolean b)

添加布尔型数据。

源码:

    public AbstractStringBuilder append(boolean b) {
        if (b) {
            int newCount = count + 4;
            if (newCount > value.length)
                expandCapacity(newCount);
            value[count++] = \'t\';
            value[count++] = \'r\';
            value[count++] = \'u\';
            value[count++] = \'e\';
        } else {
            int newCount = count + 5;
            if (newCount > value.length)
                expandCapacity(newCount);
            value[count++] = \'f\';
            value[count++] = \'a\';
            value[count++] = \'l\';
            value[count++] = \'s\';
            value[count++] = \'e\';
        }
        return this;
    }

此方法判断:若为真值则添加"true"并将计数器加4,若为假值则添加"false"并将计数器加5;若容量不足,则扩容。

append(char c)

public AbstractStringBuilder append(char c)

添加一位字符。

部分代码:

value[count++] = c;

append(int i) 

public AbstractStringBuilder append(int i) 

添加int型数据。

源码:

    public AbstractStringBuilder append(int i) {
        if (i == Integer.MIN_VALUE) {
            append("-2147483648");
            return this;
        }
        int appendedLength = (i < 0) ? stringSizeOfInt(-i) + 1
                : stringSizeOfInt(i);
        int spaceNeeded = count + appendedLength;
        if (spaceNeeded > value.length)
            expandCapacity(spaceNeeded);
        Integer.getChars(i, spaceNeeded, value);
        count = spaceNeeded;
        return this;
    }

处理流程:

1、当整数i 为Integer.MIN_VALUE时,添加"-2147483648",并返回对象引用;

2、当整数i 为正数时,调用stringSizeOfInt方法,

    static int stringSizeOfInt(int x) {
        for (int i = 0;; i++)
            if (x <= sizeTable[i])
                return i + 1;
    }
    final static int[] sizeTable = { 9, 99, 999, 9999, 99999, 999999, 9999999,
            99999999, 999999999, Integer.MAX_VALUE };

从代码中可知stringSizeOfInt方法的作用为快速确定待加入数字的位数。如加入数字123,此方法返回3。

当整数i 为负数时,也调用stringSizeOfInt方法,不过是将反值作为入参。

3、调用Integer类的getChars方法,关于此方法详见……

4、容量不足则扩容,并更改状态count,最后返回当前对象引用。

测试1:

        StringBuffer s = new StringBuffer();
        int n = Integer.MIN_VALUE;
        System.out.println("字符串:" + s.append(n) + ";长度:" + s.length());// 字符串:-2147483648;长度:11

测试2:

        StringBuffer s = new StringBuffer();
        int n = 123;
        System.out.println("字符串:" + s.append(n) + ";长度:" + s.length());// 字符串:123;长度:3

测试3:

        StringBuffer s = new StringBuffer();
        int n = -123;
        System.out.println("字符串:" + s.append(n) + ";长度:" + s.length());// 字符串:-123;长度:4

append(long l)

public AbstractStringBuilder append(long l)

添加long型数据。

源码:

    public AbstractStringBuilder append(long l) {
        if (l == Long.MIN_VALUE) {
            append("-9223372036854775808");
            return this;
        }
        int appendedLength = (l < 0) ? stringSizeOfLong(-l) + 1
                : stringSizeOfLong(l);
        int spaceNeeded = count + appendedLength;
        if (spaceNeeded > value.length)
            expandCapacity(spaceNeeded);
        Long.getChars(l, spaceNeeded, value);
        count = spaceNeeded;
        return this;
    }

此方法与上一个方法思路类似,可对照上一方法,最大的差异在于对数字位数的判断,调用的stringSizeOfLong方法:

    static int stringSizeOfLong(long x) {
        long p = 10;
        for (int i = 1; i < 19; i++) {
            if (x < p)
                return i;
            p = 10 * p;
        }
        return 19;
    }

long型最多19位,此方法每次变量p自乘10,与待加入数字比较,循环次数即可反映数字位数。

append(float f)

public AbstractStringBuilder append(float f)

添加float型数据。

append(double d) 

以上是关于java之AbstractStringBuilder类详解的主要内容,如果未能解决你的问题,请参考以下文章

java基础之java程序基础之字符和字符串

Java面向对象之异常详解

尚硅谷全套课件整理:Java前端大数据安卓面试题

java之spring之配置讲解

java的nio之:java的nio系列教程之DatagramChannel

java基础之java程序基础--之浮点运算

(c)2006-2024 SYSTEM All Rights Reserved IT常识