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) 

public AbstractStringBuilder append(double d) 

添加double 型数据。

 

删除

public AbstractStringBuilder delete(int start, int end) 

删除字符序列中从start开始,end结束的子序列。

 

插入

insert(int offset, String str)

public AbstractStringBuilder insert(int offset, String str)

在指定的偏移位置插入字符串。

源码:

    public AbstractStringBuilder insert(int offset, String str) {
        if ((offset < 0) || (offset > length()))
            throw new StringIndexOutOfBoundsException(offset);
        if (str == null)
            str = "null";
        int len = str.length();
        int newCount = count + len;
        if (newCount > value.length)
            expandCapacity(newCount);
        System.arraycopy(value, offset, value, offset + len, count - offset);//移位
        str.getChars(value, offset);//插入
        count = newCount;
        return this;
    }

偏移量小于0或越界则抛出异常;待插入字符串为null,则赋值为"null";然后容量不足则扩容,最后将待插入字符串插入指定的偏移位置。

测试:

        StringBuffer sb = new StringBuffer("12345");
        String s = null;
        System.out.println("字符串:" + sb.insert(3, s));// 字符串:123null45

insert(int offset, Object obj) 

public AbstractStringBuilder insert(int offset, Object obj) 

在指定的偏移位置插入Object对象。

源码:

    public AbstractStringBuilder insert(int offset, Object obj) {
        return insert(offset, String.valueOf(obj));
    }

内部调用的 insert(int offset, String str),在指定偏移位置插入Object对象的string形式。

insert(int offset, boolean b) 

public AbstractStringBuilder insert(int offset, boolean b) 

内部调用的 insert(int offset, String str),在指定偏移位置插入boolean数据的string形式。

insert(int offset, int i) 

public AbstractStringBuilder insert(int offset, int i) 

内部调用的 insert(int offset, String str),在指定偏移位置插入int数据的string形式。

insert(int offset, long l)

public AbstractStringBuilder insert(int offset, long l)

内部调用的 insert(int offset, String str),在指定偏移位置插入long 数据的string形式。

insert(int offset, float f)

public AbstractStringBuilder insert(int offset, float f)

内部调用的 insert(int offset, String str),在指定偏移位置插入float 数据的string形式。

insert(int offset, double d)

public AbstractStringBuilder insert(int offset, double d)

内部调用的 insert(int offset, String str),在指定偏移位置插入double 数据的string形式。

insert(int offset, char c)

public AbstractStringBuilder insert(int offset, char c)

在指定偏移位置插入一位字符。

insert(int offset, char str[])

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

在指定偏移位置插入多位字符。

insert(int dstOffset, CharSequence s)

public AbstractStringBuilder insert(int dstOffset, CharSequence s)

在指定偏移位置插入字符序列。

源码:

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

若待插入的字符序列是string类型,则调用insert(int offset, String str);否则调用insert(int dstOffset, CharSequence s,int start, int end)。

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

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

将待插入数组str从offset开始,长度为len的子数组插入目标数组指定的偏移位置(index)。

部分代码:

        System.arraycopy(value, index, value, index + len, count - index);//移位
        System.arraycopy(str, offset, value, index, len);//插入

测试:

        StringBuffer sb = new StringBuffer("12345");
        char str[] = { 'a', 'b', 'c', 'd' };
        System.out.println("字符串:" + sb.insert(3, str, 2, 2));// 字符串:123cd45

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

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

将字符序列s从start开始,end结束的子序列插入指定的偏移位置(dstOffset)。

部分代码:

        System.arraycopy(value, dstOffset, value, dstOffset + len, count
                - dstOffset);//移位
        for (int i = start; i < end; i++)
            value[dstOffset++] = s.charAt(i);//插入

测试:

        StringBuffer sb = new StringBuffer("12345");
        String s = "abcd";
        System.out.println("字符串:" + sb.insert(3, s, 2, 4));// 字符串:123cd45

 

获取索引

indexOf(String str, int fromIndex)

public int indexOf(String str, int fromIndex)

从源字符序列fromIndex索引处开始,若有与给定字符串str相同的子序列,则返回子序列的开始索引;若没有,则返回-1。

源码:

    public int indexOf(String str, int fromIndex) {
        return String.indexOf(value, 0, count, str.toCharArray(), 0,
                str.length(), fromIndex);
    }

测试:

        StringBuffer s = new StringBuffer("123123");
        System.out.println(s.indexOf("2", 0));// 1
        System.out.println(s.indexOf("2", 3));// 4
        System.out.println(s.indexOf("2", s.length()));// -1

indexOf(String str)

public int indexOf(String str)

源字符序列中若有与给定字符串str相同的子序列,则返回子序列的开始索引;若没有,则返回-1。

源码:

    public int indexOf(String str) {
        return indexOf(str, 0);
    }

此方法内部调用的indexOf(String str, int fromIndex)方法。

测试:

        System.out.println(s.indexOf("2"));// 1
        System.out.println(s.indexOf("5"));// -1

lastIndexOf(String str, int fromIndex)

public int lastIndexOf(String str, int fromIndex)

返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索。

源码:

    public int lastIndexOf(String str, int fromIndex) {
        return String.lastIndexOf(value, 0, count, str.toCharArray(), 0,
                str.length(), fromIndex);
    }

测试:

        StringBuffer s = new StringBuffer("123123");
        System.out.println(s.lastIndexOf("2", 0));// -1
        System.out.println(s.lastIndexOf("2", 3));// 1
        System.out.println(s.lastIndexOf("2", s.length()));// 4

lastIndexOf(String str)

public int lastIndexOf(String str)

返回指定子字符串在此字符串中最后一次出现处的索引,从结尾处开始反向搜索。

源码:

    public int lastIndexOf(String str) {
        return lastIndexOf(str, count);
    }

此方法内部调用的lastIndexOf(String str, int fromIndex)方法。

测试:

        StringBuffer s = new StringBuffer("123123");
        System.out.println(s.lastIndexOf("2"));// 1
        System.out.println(s.lastIndexOf("5"));// -1

 

替换

public AbstractStringBuilder replace(int start, int end, String str)

用字符串str替换原字符序列中从start开始,end结束的子序列。

部分代码:

        if (end > count)
            end = count;
        int len = str.length();
        int newCount = count + len - (end - start);
        if (newCount > value.length)
            expandCapacity(newCount);

        System.arraycopy(value, end, value, start + len, count - end);
        str.getChars(value, start);
        count = newCount;
        return this;

 

获取子序列

substring(int start, int end)

public String substring(int start, int end)

获取字符序列从start开始,end结束的子序列。

部分代码:

        return new String(value, start, end - start);

可知此方法中创建了String对象。

substring(int start)

public String substring(int start)

获取字符序列从start开始到结束的子序列。

源码:

    public String substring(int start) {
        return substring(start, count);
    }

此方法内部调用的substring(int start, int end)方法。

subSequence(int start, int end)

public CharSequence subSequence(int start, int end)

获取字符序列从start开始到结束的子序列。

此方法内部调用的substring(int start, int end)方法。

 

调整空间

public void trimToSize()

试图减少字符序列的存储。如果缓冲区是大于必要的保持其当前的字符序列,然后可调整到更加节省空间。

源码:

    public void trimToSize() {
        if (count < value.length) {
            value = Arrays.copyOf(value, count);
        }
    }

 

测试:

        StringBuffer sb = new StringBuffer("12345");
        System.out.println("字符串:" + sb + ";sb容量:" + sb.capacity());// 字符串:12345;缓冲区大小:21
        sb.trimToSize();
        System.out.println("字符串:" + sb + ";sb容量:" + sb.capacity());// 字符串:12345;缓冲区大小:5

 

 

设置长度

public void setLength(int newLength)

指定字符序列新长度为newLength。

源码:

    public void setLength(int newLength) {
        if (newLength < 0)
            throw new StringIndexOutOfBoundsException(newLength);
        if (newLength > value.length)
            expandCapacity(newLength);

        if (count < newLength) {
            for (; count < newLength; count++)
                value[count] = '\0';
        } else {
            count = newLength;
        }
    }

 

测试:

        StringBuffer s = new StringBuffer("123456");
        System.out.println("字符串:" + s + ";长度:" + s.length());// 字符串:123456;长度:6
        s.setLength(3);
        System.out.println("字符串:" + s + ";长度:" + s.length());// 字符串:123;长度:3
        s.setLength(9);
        System.out.println("字符串:" + s + ";长度:" + s.length());// 字符串:123 ;长度:9

 

 

获取字符

public char charAt(int index)

返回指定索引处的代码单元。

注意:此方法返回的并不一定是字符,因为对于Unicode增补字符1个代码点对应2个代码单元。

源码:

    public char charAt(int index) {
        if ((index < 0) || (index >= count))
            throw new StringIndexOutOfBoundsException(index);
        return value[index];
    }

 

 

修改字符

public void setCharAt(int index, char ch)

修改指定索引处(index)的代码单元为指定的代码单元(ch)。

源码:

    public void setCharAt(int index, char ch) {
        if ((index < 0) || (index >= count))
            throw new StringIndexOutOfBoundsException(index);
        value[index] = ch;
    }

 

 

删除字符

public AbstractStringBuilder deleteCharAt(int index)

删除字符序列中指定索引处的代码单元。

源码:

    public AbstractStringBuilder deleteCharAt(int index) {
        if ((index < 0) || (index >= count))
            throw new StringIndexOutOfBoundsException(index);
        System.arraycopy(value, index + 1, value, index, count - index - 1);
        count--;
        return this;
    }

 

 

getChars

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

源数组value从srcBegin开始,srcEnd结束的字符序列依次覆盖目的数组dst中从dstBegin开始的连续(srcEnd - srcBegin)个代码单元。

注意:覆盖的字符序列不能越界。

源码:

    public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) {
        if (srcBegin < 0)
            throw new StringIndexOutOfBoundsException(srcBegin);
        if ((srcEnd < 0) || (srcEnd > count))
            throw new StringIndexOutOfBoundsException(srcEnd);
        if (srcBegin > srcEnd)
            throw new StringIndexOutOfBoundsException("srcBegin > srcEnd");
        System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);
    }

 

测试1:

        StringBuffer s = new StringBuffer("123");
        char dst[] = { 'a', 'b', 'c', 'd' };
        s.getChars(1, 2, dst, 2);
        System.out.println(dst);// ab2d

测试2:

        StringBuffer s = new StringBuffer("123");
        char dst[] = { 'a', 'b', 'c', 'd' };
        s.getChars(1, 4, dst, 2);
        System.out.println(dst);

打印:

Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 4

 

 

codePointAt(int index)

public int codePointAt(int index)

返回指定索引处的字符(Unicode code point)。

源码:

    public int codePointAt(int index) {
        if ((index < 0) || (index >= count)) {
            throw new StringIndexOutOfBoundsException(index);
        }
        return Character.codePointAt(value, index);
    }

 

标量值测试:

        StringBuffer s = new StringBuffer();
        s.append('1').append('2');
        for (int i = 0; i < s.length(); i++) {
            System.out.println(s.codePointAt(i));
        }

打印:

49
50

增补字符测试:

        StringBuffer s = new StringBuffer();
        s.append('\ud800').append('\udc00');
        for (int i = 0; i < s.length(); i++) {
            System.out.println(s.codePointAt(i));
        }

打印:

65536
56320

从测试中可以看出当字符序列中都是标量值字符时,直接输出对应的码点;当有增补字符时,那么,当索引指向的是高代理项时,就会输出整个增补字符的码点,当索引指向的是低代理项时,就会返回对应代码单元的码点。

 

codePointBefore(int index) 

public int codePointBefore(int index)

返回指定索引前的字符(Unicode code point)。

部分源码:

        return Character.codePointBefore(value, index);

标量值测试:

        StringBuffer s = new StringBuffer();
        s.append('1').append('2').append('3');
        for (int i = 0; i < s.length(); i++) {
            if (i == 0)
                continue;
            System.out.println(s.codePointBefore(i));
        }

打印:

49
50

增补字符测试:

        StringBuffer s = new StringBuffer();
        s.append('\ud800').append('\udc00').append('1');
        for (int i = 0; i < s.length(); i++) {
            if (i == 0)
                continue;
            System.out.println(s.codePointBefore(i));
        }

打印:

55296
65536

从测试中可以看出当字符序列中都是标量值字符时,输出指定索引处的码点;当有增补字符时,那么,当索引指向的是高代理项时,就会输出对应代码单元的码点;当索引指向的是低代理项时,就会返回整个增补字符的码点。

 

codePointCount(int beginIndex, int endIndex)  

public int codePointCount(int beginIndex, int endIndex) 

返回在指定的文本范围的Unicode代码点的数量。

源码:

    public int codePointCount(int beginIndex, int endIndex) {
        if (beginIndex < 0 || endIndex > count || beginIndex > endIndex) {
            throw new IndexOutOfBoundsException();
        }
        return Character.codePointCountImpl(value, beginIndex, endIndex
                - beginIndex);
    }

测试1:

        StringBuffer s = new StringBuffer("123123");
        System.out.println(s.codePointCount(0, s.length()));// 6

测试2:

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

从测试中可知对于Unicode标量值1个代码点对应1个char,对于Unicode增补字符1个代码点对应2个char。

 

offsetByCodePoints(int index, int codePointOffset) 

public int offsetByCodePoints(int index, int codePointOffset)

返回从给定的index处偏移codePointOffset个代码点的索引。

源码:

    public int offsetByCodePoints(int index, int codePointOffset) {
        if (index < 0 || index > count) {
            throw new IndexOutOfBoundsException();
        }
        return Character.offsetByCodePointsImpl(value, 0, count, index,
                codePointOffset);
    }

测试:

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

打印:

1
2
4

 

 

appendCodePoint(int codePoint) 

public AbstractStringBuilder appendCodePoint(int codePoint)

添加指定代码点对应的字符。            

源码:

    public AbstractStringBuilder appendCodePoint(int codePoint) {
        if (!Character.isValidCodePoint(codePoint)) {
            throw new IllegalArgumentException();
        }
        int n = 1;
        if (codePoint >= Character.MIN_SUPPLEMENTARY_CODE_POINT) {
            n++;
        }
        int newCount = count + n;
        if (newCount > value.length) {
            expandCapacity(newCount);
        }
        if (n == 1) {
            value[count++] = (char) codePoint;
        } else {
            Character.toSurrogates(codePoint, value, count);
            count += n;
        }
        return this;
    }

 

标量值测试:

        StringBuffer s = new StringBuffer();
        s.appendCodePoint(49);
        System.out.println(s);
        System.out.println(s.length());

打印:

1
1

增补字符测试:

        StringBuffer s = new StringBuffer();
        s.appendCodePoint(65536);
        System.out.println(s);
        System.out.println(s.length());

打印:

 

 


相关链接:

java之StringBuilder类详解

java之StringBuffer类详解

posted @ 2016-12-19 19:06  SQP51312  阅读(1301)  评论(0编辑  收藏  举报