blog

このJDKのソースコード解析は、本当に詳しく書かれているので、何度も見ることをお勧めする!

1.一般 このメソッドを呼び出すと、現在の文字数がchar配列のサイズより小さい場合、縮小して配列のコピーを開始します。余分な領域を解放するには、String コンストラクタを呼び出して部分文字列をイ...

Mar 29, 2020 · 8 min. read
シェア

概要

CharSequence は文字シーケンスへのインターフェースで、以下のメソッドを提供します。

このインタフェースは、実装する文字シーケンスの長さを指定します: length(); 添え字が index である文字を取得できます: charAt(int index); 文字シーケンスの後続を取得できます: subSequence(int start, int end); 親オブジェクトの toString() をオーバーライドします: toString(); Appendable 追加のルールを定義します。): toString(); Appendable 追加のルールを定義します。

クラス図

属性

char[] value; 文字を記録するスペース int count; char 配列内の実際の文字数

施工方法

デフォルトコンストラクタ AbstractStringBuilder()

AbstractStringBuilder(int capacity)

入力されたパラメータに従って、char配列空間を初期化します。

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

リターンの長さ/サイズ

長さ

public int length() {
		return count;
}

容量()

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

length() は、char 配列の実際の文字数を返します。

capacity は、配列の空き容量を返します。

拡張

確保容量(int 最小容量)

		public void ensureCapacity(int minimumCapacity) {
 if (minimumCapacity > 0)
 ensureCapacityInternal(minimumCapacity);
 }
		private void ensureCapacityInternal(int minimumCapacity) {
 // overflow-conscious code
 if (minimumCapacity - value.length > 0)//入力パラメータが現在の配列のスペースより大きい場合、それを展開する。
 expandCapacity(minimumCapacity);
 }
		void expandCapacity(int minimumCapacity) {
 int newCapacity = value.length * 2 + 2;//新しいスペースは*2
 if (newCapacity - minimumCapacity < 0)//ハートのスペースが入力引数より小さい場合、新しいスペースが入力引数になる。
 newCapacity = minimumCapacity;
 if (newCapacity < 0) {//新しいスペースが0 // intを越えると0より小さくなることがある。
 if (minimumCapacity < 0) // は、入力パラメータも0より小さい場合、例外を投げる。
 throw new OutOfMemoryError();
 newCapacity = Integer.MAX_VALUE;//新しいスペースをintの最大値に設定する。
 }
 value = Arrays.copyOf(value, newCapacity);//配列をコピーする
 }

setLength(int newLength)

		public void setLength(int newLength) {
 if (newLength < 0)
 throw new StringIndexOutOfBoundsException(newLength);
 ensureCapacityInternal(newLength);
 if (count < newLength) {
 Arrays.fill(value, count, newLength, '\0');
 }
 count = newLength;
 }

これは、secureCapacityInternalの呼び出しによって内部的に実装される拡張メソッドでもあります。

その後、配列の空の位置に

収縮

trimToSize()

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

文字数がchar配列のサイズより小さい場合は、縮小して配列のコピーを開始します。余分な領域の解放

キャラクター獲得

charAt(int index)

添え字に対応する文字を直接返すか、範囲外の場合は例外をスローします。

部分文字列/部分シーケンスの取得

substring(int開始)/substring(int開始,int終了)/subSequence(int開始,int終了)

		public String substring(int start) {
 return substring(start, count);
 }
		public CharSequence subSequence(int start, int end) {
 return substring(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);
 }

Stringのコンストラクタ・メソッドを呼び出し、部分文字列のインターセプトを実装します。

文字の修正

setCharAt(int index,char ch)

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

replace(int start, int end, String str)

先頭から末尾までの文字を文字列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
 end = count;
 int len = str.length();
 			//todo なぜ展開するのか
 int newCount = count + len - (end - start);
 ensureCapacityInternal(newCount);
				// 配列をコピーする replace
 System.arraycopy(value, end, value, start + len, count - end);
 str.getChars(value, start);
 count = newCount;
 return this;
 }

文字列の追加

このクラスは、append() にいくつかの

		public AbstractStringBuilder append(Object obj) {
 return append(String.valueOf(obj));
 }
		public AbstractStringBuilder append(String str) {
 if (str == null)//文字列が空の場合
 return appendNull();//の代わりに"null"文字列の配列に変換する
 int len = str.length();
 ensureCapacityInternal(count + len);
 str.getChars(0, len, value, count);
 count += len;
 return this;
 }
		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;
 }
 // Documentation in subclasses because of synchro difference
 public AbstractStringBuilder append(StringBuffer sb) {
 if (sb == null)
 return appendNull();
 int len = sb.length();
 ensureCapacityInternal(count + len);
 sb.getChars(0, len, value, count);
 count += len;
 return this;
 }
		/**
 * @since 1.8
 */
 AbstractStringBuilder append(AbstractStringBuilder asb) {
 if (asb == null)
 return appendNull();
 int len = asb.length();
 ensureCapacityInternal(count + len);
 asb.getChars(0, len, value, count);
 count += len;
 return this;
 }
 // Documentation in subclasses because of synchro difference
 @Override
 public AbstractStringBuilder append(CharSequence s) {
 if (s == null)
 return appendNull();
 if (s instanceof String)
 return this.append((String)s);
 if (s instanceof AbstractStringBuilder)
 return this.append((AbstractStringBuilder)s);
 return this.append(s, 0, s.length());
 }
		public AbstractStringBuilder append(char[] str) {
 int len = str.length;
 ensureCapacityInternal(count + len);
 System.arraycopy(str, 0, value, count, len);
 count += len;
 return this;
 }
		public AbstractStringBuilder append(boolean b) {//対応する文字の式に変換するためにBooleanが追加される。
 if (b) {
 ensureCapacityInternal(count + 4);
 value[count++] = 't';
 value[count++] = 'r';
 value[count++] = 'u';
 value[count++] = 'e';
 } else {
 ensureCapacityInternal(count + 5);
 value[count++] = 'f';
 value[count++] = 'a';
 value[count++] = 'l';
 value[count++] = 's';
 value[count++] = 'e';
 }
 return this;
 }
 public AbstractStringBuilder append(char c) {
 ensureCapacityInternal(count + 1);
 value[count++] = c;
 return this;
 }
		// int long float double. すべてを列挙するつもりはない。
		public AbstractStringBuilder append(int i) {
 if (i == Integer.MIN_VALUE) {
 append("-");
 return this;
 }
 int appendedLength = (i < 0) ? Integer.stringSize(-i) + 1
 : Integer.stringSize(i);
 int spaceNeeded = count + appendedLength;
 ensureCapacityInternal(spaceNeeded);
 Integer.getChars(i, spaceNeeded, value);
 count = spaceNeeded;
 return this;
 }

パラメータ・タイプが異なるだけで、ほとんど同じです。の後に、元の値[]の実際のカウントに直接リンクします。

つまり、AbstractStringBuilderオブジェクト.append(パラメータ1).append(パラメータ2).append(パラメータ3).............;

文字列の挿入

最後に文字列を追加するだけでなく、任意の位置に文字列を挿入することもできます。

配列 str の一部を、[offset,offset+len) の範囲内の value[] の添え字の位置インデックスに挿入します;

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;
 return this;
 }

原理は同じで、容量を拡張し、それを指定された位置に挿入、つまり配列をコピーします。

また、以下のような挿入もあります:

insert(int offset, Object obj) insert(int offset, String str) insert(int offset, char str[]) insert(int dstOffset, CharSequence s)/insert(intinsert(int offset, charSequence s,int start, int end):文字列の挿入 基本型の挿入 insert(int offset, boolean b)/insert(int offset, char c)/insert(int offset, int i)/insert(int offset, float f)/insert(int offset, float f)insert(intオフセット, float f)/insert(int オフセット, double d)

削除

		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;
 }

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;
 }

見つける

indexOf(文字列str): value[]内の文字列strを探し、見つかった場合は最初の文字列の最初の文字の添え字を返します。

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

lastIndexOf(String str):後ろから前に検索します。

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

Stringのlookupメソッドがすべてです。

ストリングを反転

reverse 文字列の先頭と末尾を逆にします。

		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;
 }
		private void reverseAllValidSurrogatePairs() {
 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;
 }
 }
 }
 }

究極

ここで見ていただきありがとうございます、あなたが理解できないものを読んだ後、コメント欄で私に尋ねることができ、記事は私に承認のうなずきを与えることを忘れないであなたに役立つと思いますが、毎日Java関連の技術記事や業界情報を共有し、記事に注意を払うと転送することを歓迎します!

Read next

cxuan読者のためのアウトソーシングの旅

.\nI. マイス\n左結合\nテーブルaはテーブルbに左結合され、テーブルbはテーブルcに左結合され、テーブルcはテーブルaに左結合されます。\n1 つのフィールドはマークと呼ばれ、もう 1 つのフィールドはグループ名と呼ばれます。

Mar 29, 2020 · 7 min read

todoList

Mar 29, 2020 · 3 min read

Numpy配列

Mar 29, 2020 · 18 min read