zoukankan      html  css  js  c++  java
  • java.util.AbstractStringBuilder源码分析

    AbstractStringBuilder是一个抽象类,是StringBuilder和StringBuffer的父类,分析它的源码对StringBuilder和StringBuffer代码的理解有很大的帮助。

    先来看看该类的声明:

    abstract class AbstractStringBuilder implements Appendable, CharSequence {}

    该类实现Appendable和CharSequence接口。

    成员变量:

    char[] value;//字符数组用来存储字符串
    int count;//值是字符串数组被使用的长度。注意,字符数组被使用长度不等于字符数组长度

    构造器:

    AbstractStringBuilder() {//无参构造器
    }
    
    AbstractStringBuilder(int capacity) {//带一个int参数构造器,capacity是字符串数组的大小,相当于字符串容器的大小
            value = new char[capacity];
    }

    方法:

    //返回字符串实际大小
    public
    int length() { return count; }
    //返回容器容量
    public int capacity() { return value.length; }
    //确保容器的大小比minimumCapcipty大
    public void ensureCapacity(int minimumCapacity) { if (minimumCapacity > 0) ensureCapacityInternal(minimumCapacity); } private void ensureCapacityInternal(int minimumCapacity) { // overflow-conscious code if (minimumCapacity - value.length > 0)//如果minimumCapacity比容器大 expandCapacity(minimumCapacity);//扩容 } void expandCapacity(int minimumCapacity) { int newCapacity = value.length * 2 + 2;//新容量是(原容量大小+1)*2 if (newCapacity - minimumCapacity < 0)//如果扩容后仍然不够minimumCapacity newCapacity = minimumCapacity;//那么新容量就是minimumCapacity if (newCapacity < 0) { if (minimumCapacity < 0) // overflow throw new OutOfMemoryError(); newCapacity = Integer.MAX_VALUE; } value = Arrays.copyOf(value, newCapacity);//创建新容器 }
    //这个方法是让容器的大小变成跟字符串大小一样
    public void trimToSize() { if (count < value.length) { value = Arrays.copyOf(value, count); } }
    //设置字符串的长度,如果比原来长,多出来的部分填充'',如果比原来短,截断
    public void setLength(int newLength) { if (newLength < 0) throw new StringIndexOutOfBoundsException(newLength); ensureCapacityInternal(newLength); if (count < newLength) { Arrays.fill(value, count, newLength, ''); } count = newLength; }
    //返回index位置的字符
    public char charAt(int index) { if ((index < 0) || (index >= count)) throw new StringIndexOutOfBoundsException(index); return value[index]; }
    //注意下面的append方法,重载的方法很多,支持各种类型参数的append,仅列出部分
    //在字符串末尾添加一个字符串,该字符串由obj的toString方法决定
    public AbstractStringBuilder append(Object obj) { return append(String.valueOf(obj)); }
    //在字符串末尾添加一个字符串str
    public AbstractStringBuilder append(String str) { if (str == null) return appendNull(); int len = str.length(); ensureCapacityInternal(count + len); str.getChars(0, len, value, count); count += len; return this; }
    //在字符串后面添加null字符串
    private AbstractStringBuilder appendNull() { int c = count; ensureCapacityInternal(c + 4); final char[] value = this.value; value[c++] = 'n'; value[c++] = 'u'; value[c++] = 'l'; value[c++] = 'l'; count = c; return this; }
    //删除start至end的字符子串,容量不变,字符串长度减少end-start
    public AbstractStringBuilder delete(int start, int end) { if (start < 0) throw new StringIndexOutOfBoundsException(start); if (end > count) end = count; if (start > end) throw new StringIndexOutOfBoundsException(); int len = end - start; if (len > 0) { System.arraycopy(value, start+len, value, start, count-end); count -= len; } }
    //返回start至end的子串
    public String substring(int start, int end) { if (start < 0) throw new StringIndexOutOfBoundsException(start); if (end > count) throw new StringIndexOutOfBoundsException(end); if (start > end) throw new StringIndexOutOfBoundsException(end - start);
        return new String(value, start, end - start); }
    //在index位置插入str从offset开始,长度为len的子串
    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; }
    //将字符串的顺序颠倒,如"abc" reverse 成 "cba"
    public AbstractStringBuilder reverse() { boolean hasSurrogates = false; int n = count - 1; for (int j = (n-1) >> 1; j >= 0; j--) { int k = n - j; char cj = value[j]; char ck = value[k]; value[j] = ck; value[k] = cj; if (Character.isSurrogate(cj) || Character.isSurrogate(ck)) { hasSurrogates = true; } } if (hasSurrogates) { reverseAllValidSurrogatePairs(); } return this; }

    //...还有其他的方法

     可以看到AbstractStringBuilder几乎定义了所有字符串的操作,同时它接受任意类型的拼接,在一个动态数组上操作字符串,对于频繁的字符操作,相比于直接使用String来操作new一个新的String,能提高效率。

  • 相关阅读:
    linux下查找文件及查找包含指定内容的文件常用命令
    小程序与h5之前切换频繁时候,点击无反应
    vue项目微信分享之后路由链接被破坏问题
    async-await用法
    小程序input组件获得焦点时placeholder内容有重影
    es6语法在ios低版本的支持性
    h5页面避免两个页面反复跳转死循环
    小程序getLocation出现的各种问题汇总
    小程序组件跳转页面存在兼容问题
    nigix反向代理
  • 原文地址:https://www.cnblogs.com/13jhzeng/p/5572500.html
Copyright © 2011-2022 走看看