AbstractStrigBuiderソース分析

44101 ワード

AbstractStrigBuiderソース分析
概要
  • この抽象類はStringBuiderとStringBufferの直接的な父類であり、多くの方法が定義されているので、この二つの種類の間でAbstractStrigBuiderの抽象類を勉強することを提案します。
  • このようなソースの注釈はJDK 1.5から最初の2つのクラスの父として存在していますが、JDK 1.8のAPIまでは、StringBuiderとStrigBufferの父はまだObject
  • です。
    クラス宣言:
    abstract class AbstractStringBuilder implements Appendable, CharSequence 
    CharSequenceという文字配列のインターフェースがよく知られている二つのインターフェースが実現されました。
  • このインターフェースは、文字シーケンスを実装する必要がある長さ:length()を規定する。
  • はindexとしてマークされた文字を取得することができます。
  • は、その文字列のサブキャラクターのシーケンスを得ることができる。
  • は、この文字列のStringバージョン(親クラスObjectのtoString():toString()を規定している。
  • Appndableインターフェースは名前の通り、追加の「ルール」を定義します。
  • apped(CharSequence csq)throws IOException:どのように1つの文字シーケンスを追加しますか?
  • apped(CharSequence csq,int start,int end)throws IOException:どのように1つの文字列の一部を追加しますか?
  • apped(char c)throws IOException:どのように1つの文字を追加しますか?
    変数:
        /**
         * The value is used for character storage.
         */
        char value[];
    
        /** 
         * The count is the number of characters used.
         */
        int count;
    valueはこの文字列の具体的な記憶であり、countは実際に記憶されている数量に注意します。valueは実際に動的配列であり、ArayListの実現と似ているところが多い)
    コンストラクタ:
        /** 
         * This no-arg constructor is necessary for serialization of subclasses.
         */
         AbstractStringBuilder() {
        }
    
        /** 
         * Creates an AbstractStringBuilder of the specified capacity.
         */
        AbstractStringBuilder(int capacity) {
            value = new char[capacity];
        }
    方法(順番は方法によってソースの中に出てくる順番ですので、繋がっていません):
    1.length():既に記憶されている実際の長さを返します。
    public int length() {
        return count;
        }
    
    2.capacity():この単語は「容量」という意味で、現在このvalue配列の実際のサイズを取得します。
     public int capacity() {
        return value.length;
        }
    3.ensureCapacity(int minimum Capacity):value配列の容量が十分かどうかを確保し、足りなければ、expandCapacity(minimum Capacity)メソッドを呼び出して拡張し、パラメータは必要な容量です。
     public void ensureCapacity(int minimumCapacity) {
        if (minimumCapacity > value.length) {
            expandCapacity(minimumCapacity);
        }
        }
    4.expandCapacity:配列を拡張し、パラメータを必要とする容量
     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の二倍(newCapacity)を必要な容量(minimum Capacity)と比較する。必要な容量より大きいと容量を+1の倍に拡大します。必要な容量より小さいなら、必要な容量に直接拡大します。Arays.co pyOf()という非常によく知られている方法を使って配列容量を動的に拡大する。
    5.trimToSize():value配列の容量が余っている場合、余分なものを全部放出します。
    public void trimToSize() {
            if (count < value.length) {
                value = Arrays.copyOf(value, count);
            }
        }
    6.set Length:実際の長さcountの大きさを強制的に増大させ、容量が足りなければexpadCapacity()で拡大する。拡大した部分を全部'\0'(ASCIIコードのnull)で初期化します。
     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;
            }
        }
    7.charAt(int index):indexと表記されている文字を得る
    public char charAt(int index) {
        if ((index < 0) || (index >= count))
            throw new StringIndexOutOfBoundsException(index);
        return value[index];
        }
    8.codePoint_At(int index):コードポイントを得る
    public int codePointAt(int index) {
            if ((index < 0) || (index >= count)) {
                throw new StringIndexOutOfBoundsException(index);
            }
            return Character.codePointAt(value, index);
        }
    9.get Chars(int srrBegin,int srrcent,char dst[],int dstBegin):value[]の[srrBegin,srcend]をdst[]配列のdesBeginの先頭にコピーする
    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);
        }
    24.substring(int start)/substring(int start,int end):サブ文字列を得る
     public String substring(int start) {
            return substring(start, count);
        }
    
    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);
        }
    25.subSequence(int start,int end):サブキャラクターシーケンスを得る
    public CharSequence subSequence(int start, int end) {
            return substring(start, end);
        }
    36.reverse():valueを倒順に置く(変化に注意するのは本valueであり、新たなAbstractStringBuiderを作成したのではなく、valueを倒順とする)
    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;
        }
    toString():唯一の抽象的な方法:toString()
        public abstract String toString();
    
    唯一のfinal方法:getValue()を取得し、value配列を取得します。直接操作できます。
    final char[] getValue() {
            return value;
        }
    CRUD操作:
    変更:
    10.set CharAt(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;
        }
    23.replace(int start,int end,String str):value配列の「start,end」部分を文字列strで置換する
     public AbstractStringBuilder replace(int start, int end, String str) {
            if (start < 0)
            throw new StringIndexOutOfBoundsException(start);
        if (start > count)
            throw new StringIndexOutOfBoundsException("start > length()");
        if (start > end)
            throw new StringIndexOutOfBoundsException("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;
        }
    
    増加(AbstractStrigBuider類とそのサブクラスの中で最も重要な操作;Appleインターフェースの具体的な実現)
    その中でappedはすべて「追加」を表し、insertはすべて「挿入」を表します。
    11.apped(Object obj):Object(または任意のオブジェクト)のtoString方法を利用して文字列に変換して、value[]に追加する。
     public AbstractStringBuilder append(Object obj) {
        return append(String.valueOf(obj));
        }
    12.apped()のコアコード:apped/apple(String str)/apped/apple/apped(CharSequence)です。value[]を直接修正して、そして'添加’という意味は元value[]の実際のcountの後ろにリンクするという意味です。
     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;
        }
    
        // Documentation in subclasses because of synchro difference
        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;
        }
    
        // Documentation in subclasses because of synchro difference
        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());
        }
    また、AbstractStringBuiderは、apped方法が連続的に無限に起動できることを意味する。すなわち、AbstractStringBuiderオブジェクト。appnd(パラメータ1)。appnd(パラメータ2)。appnd(パラメータ3)…。
    13.apped(CharSequence、int start、int end):文字列sを追加する部分のシーケンスは、「start、end」の範囲です。
     public AbstractStringBuilder append(CharSequence s, int start, int end) {
            if (s == null)
                s = "null";
        if ((start < 0) || (end < 0) || (start > end) || (end > s.length()))
            throw new IndexOutOfBoundsException(
                    "start " + start + ", end " + end + ", s.length() " 
                    + s.length());
        int len = end - start;
        if (len == 0)
                return this;
        int newCount = count + len;
        if (newCount > value.length)
            expandCapacity(newCount);
            for (int i=start; i<end; i++)
                value[count++] = s.charAt(i);
            count = newCount;
        return this;
        }
    14.apped(char str):文字配列を追加します。
    public AbstractStringBuilder append(char str[]) { 
        int newCount = count + str.length;
        if (newCount > value.length)
            expandCapacity(newCount);
            System.arraycopy(str, 0, value, count, str.length);
            count = newCount;
            return this;
        }
    15.apped(char str[],int offset,int len):1つの文字配列の一部を追加して、この部分の範囲は[offset,offset+len];
    public AbstractStringBuilder append(char str[], int offset, int len) {
            int newCount = count + len;
        if (newCount > value.length)
            expandCapacity(newCount);
        System.arraycopy(str, offset, value, count, len);
        count = newCount;
        return this;
        }
    16.ブール値を追加する。
    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;
        }
    17.apped(char c):文字を追加する
    public AbstractStringBuilder append(char c) {
            int newCount = count + 1;
        if (newCount > value.length)
            expandCapacity(newCount);
        value[count++] = c;
        return this;
        }
    18.apped(int i):整数を追加する
    public AbstractStringBuilder append(int i) {
            if (i == Integer.MIN_VALUE) {
                append("-2147483648");
                return this;
            }
            int appendedLength = (i < 0) ? stringSizeOfInt(-i) + 1 
                                         : stringSizeOfInt(i);          //stringSizeOfInt     ,         。
            int spaceNeeded = count + appendedLength;
            if (spaceNeeded > value.length)
                expandCapacity(spaceNeeded);
        Integer.getChars(i, spaceNeeded, value);
            count = spaceNeeded;
            return this;
        }
    
     final static int [] sizeTable = { 9, 99, 999, 9999, 99999, 999999, 9999999,
                                         99999999, 999999999, Integer.MAX_VALUE };
    
    
        static int stringSizeOfInt(int x) {
            for (int i=0; ; i++)
                if (x <= sizeTable[i])
                    return i+1;
        }
    19.apped(long l):長い整数のデータを追加します。原理は同じです。
    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;
        }
    
        // Requires positive x
        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;
        }
    20.apped(float f)/apped:浮動小数点を追加します。
     public AbstractStringBuilder append(float f) {
        new FloatingDecimal(f).appendTo(this);
        return this;
        }
    
     public AbstractStringBuilder append(double d) {
        new FloatingDecimal(d).appendTo(this);
        return this;
        }
    以上はアプリです
    以下はinsertです
    26.insert(int index,char str[],int offset,int len):(insertのコアコード)はvalue[]の下にindex位置として配列strの一部を挿入します。
     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);
        int newCount = count + len;
        if (newCount > value.length)
            expandCapacity(newCount);
        System.arraycopy(value, index, value, index + len, count - index);
        System.arraycopy(str, offset, value, index, len);
        count = newCount;
        return this;
        }
    27.insert(int offset、Object obj):value[]のoffset位置にObject(またはすべてのオブジェクト)のStering版を挿入します。
    public AbstractStringBuilder insert(int offset, Object obj) {
        return insert(offset, String.valueOf(obj));
        }
    
    28.insert(int offset,String str):value[]のoffset位置に文字列を挿入する
    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;
        }
    29.insert(int offset,char str[]:value[]のoffset位置に文字配列を挿入する
    public AbstractStringBuilder insert(int offset, char str[]) {
        if ((offset < 0) || (offset > length()))
            throw new StringIndexOutOfBoundsException(offset);
        int len = str.length;
        int newCount = count + len;
        if (newCount > value.length)
            expandCapacity(newCount);
        System.arraycopy(value, offset, value, offset + len, count - offset);
        System.arraycopy(str, 0, value, offset, len);
        count = newCount;
        return this;
        }
    30.0 insert(int dstOffset、CharSequence)/insert(int dstOffset、Char Sequence、int start、int end):文字列の挿入
    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());
        }
    
    
    
    public AbstractStringBuilder insert(int dstOffset, CharSequence s,
                                               int start, int end) {
            if (s == null)
                s = "null";
        if ((dstOffset < 0) || (dstOffset > this.length()))
            throw new IndexOutOfBoundsException("dstOffset "+dstOffset);
        if ((start < 0) || (end < 0) || (start > end) || (end > s.length()))
                throw new IndexOutOfBoundsException(
                    "start " + start + ", end " + end + ", s.length() " 
                    + s.length());
        int len = end - start;
            if (len == 0)
                return this;
        int newCount = count + len;
        if (newCount > value.length)
            expandCapacity(newCount);
        System.arraycopy(value, dstOffset, value, dstOffset + len,
                             count - dstOffset);
        for (int i=start; ivalue[dstOffset++] = s.charAt(i);
        count = newCount;
            return this;
        }
    31.基本タイプを挿入する:charが直接挿入される以外は、先にStringに移行して、28番のinsertメソッドを呼び出します。
     public AbstractStringBuilder insert(int offset, boolean b) {
        return insert(offset, String.valueOf(b));
        }
    
    
        public AbstractStringBuilder insert(int offset, char c) {
        int newCount = count + 1;
        if (newCount > value.length)
            expandCapacity(newCount);
        System.arraycopy(value, offset, value, offset + 1, count - offset);
        value[offset] = c;
        count = newCount;
        return this;
        }
    
    
        public AbstractStringBuilder insert(int offset, int i) {
        return insert(offset, String.valueOf(i));
        }
    
    
        public AbstractStringBuilder insert(int offset, long l) {
        return insert(offset, String.valueOf(l));
        }
    
    
        public AbstractStringBuilder insert(int offset, float f) {
        return insert(offset, String.valueOf(f));
        }
    
    
        public AbstractStringBuilder insert(int offset, double d) {
        return insert(offset, String.valueOf(d));
        }
    削除:
    21.delete(int start,int end):value配列の[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;
            }
            return this;
        }
    22.deleteCharAt(int index):indexとしてマークされたデータを削除し、後のデータを1つ前に移動します。
     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;
        }
    調べ(実はCRUDの前のいくつかの方法の中に一つか二つがあっても調べます):
    32.indexOf(String str):value[]で文字列strを探しています。見つけられたら、最初の文字列の最初の文字の下付き文字を返します。
     public int indexOf(String str) {
        return indexOf(str, 0);
        }
    33.froomIndexから、value[]で文字列のstrを探します。見つけられたら、最初の文字列の第一文字の下付き文字を返します。
    public int indexOf(String str, int fromIndex) {
            return String.indexOf(value, 0, count,
                                  str.toCharArray(), 0, str.length(), fromIndex);
        }
    34.lastIndexOf(String str):後から前へ探してください。
      public int lastIndexOf(String str) {
            return lastIndexOf(str, count);
        }
    35.lastIndexOf(String str,int from Index):前からfrom Indexまで、サブストリングを探しています。
     public int lastIndexOf(String str, int fromIndex) {
            return String.lastIndexOf(value, 0, count,
                                  str.toCharArray(), 0, str.length(), fromIndex);
        }