StringBuilderとStringBufferは、文字列を操作するために一般的に使用される2つのクラスです。私たち全員が知っているように、StringBuilderはスレッドインセンスであり、StringBufferはスレッドセーフです。前者はJDK1.5によって追加され、後者はJDK1.0で利用可能でした。以下の内部実装を分析しましょう。
1。相続関係
パブリックファイナルクラスStringBufferExtEnds AbstractStringBuilderimplements Java.io.Serializable、CharSequencePublic Final Class StringBuildEREXTENDS AbstractStringBuilderimplements Java.io.Serializable、CharSequence
2つのクラス間の相続関係はまったく同じであることがわかります。 Serializableはシリアル化可能なフラグです。 CharSequenceインターフェイスには、charat()、length()、shindevence()、およびtoString()メソッドが含まれます。文字列クラスは、このインターフェイスも実装しています。ここでの焦点は、StringBuilderとStringBufferのほとんどの操作の実装をカプセル化する抽象クラスの抽象ストリングビルダーにあります。
2。AbstractStringBuilder
1。変数と構造方法
char [] value; int count; abstractStringBuilder(){} abstractStringBuilder(int caperage){value = new char [capuation];}AbstractStringBuilderはChar []配列を使用して文字列を保存し、建設中に初期容量の方法を指定できます。
2。容量を拡張します
public void ensurecapacity(int minimutcapacity){if(minimumcapacity> 0)ensurecapacityinternal(minimutcapacity);} private void ensurecapacityinternal(int minimumcapacity){//オーバーフロー - 意識コードnewcapacity = value.length * 2 + 2; if(newCapacity -MinimutCapacity <0)newCapacity = MinimutCapacity; if(newcapacity <0){if(minimumcapacity <0)//オーバーフローnew outofmemoryerror(); newcapacity = integer.max_value; } value = arrays.copyof(value、newcapacity);}拡張方法は、最終的にexpandCapacity()によって実装されます。この方法では、容量は最初に元の容量と2に拡張されます。この時点で指定された容量よりも小さい場合、新しい容量は最小限に設定されます。次に、それがあふれているかどうかを判断します。あふれている場合は、Integer.max_valueに容量を設定します。最後に、値の値をコピーすることは、明らかに時間のかかる操作です。
3。Append()メソッド
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;これを返します。 }append()は最も一般的に使用される方法であり、多くの形式のオーバーロードがあります。上記はそれらの1つであり、文字列を追加するために使用されます。 strがnullの場合、appendnull()メソッドが呼び出されます。この方法は、実際には「n」、「u」、「l」、「l」などの文字を追加します。 nullでない場合は、最初に容量を拡張し、次にstringのgetchars()メソッドを呼び出して、strを値の最後に追加します。最後に、オブジェクト自体が返されるため、append()は連続的に呼ばれます。
3。StringBuilder
AbstractStringBuilderは、必要なメソッドのほとんどを実装しており、StringBuilderとStringBufferを呼び出す必要のみが必要です。 StringBuilderの実装を見てみましょう。
1。コンストラクター
public stringbuilder(){super(16);} public stringbuilder(int capuation){super(capacity);} public stringbuilder(string str){super(str.length() + 16); append(str);} public stringbuilder(charsequence seq){this(seq.length() + 16); append(seq);}ご覧のとおり、StringBuilderのデフォルト容量サイズは16です。もちろん、初期容量を指定したり、既存の文字シーケンスのStringBuilderオブジェクトに初期値を割り当てることもできます。
2。Append()メソッド
public stringbuilder append(string str){super.append(str);これを返します;} public stringbuilder append(charsequence s){super.append(s);これを返します;}append()には多くのオーバーロード方法があり、そのうち2つがあります。明らかに、ここに直接呼ばれる親クラスの抽象ストリングビルダーの方法があります。
3。toString()
public string toString(){//コピーを作成し、配列を共有しないでください新しい文字列(value、0、count);}toString()メソッドは、元のオブジェクトとメモリを共有しない新しい文字列オブジェクトを返します。実際、AbstractStringBuilderのSubstring()メソッドにも同じことが言えます。
4。Sringbuffer
StiringBufferはStringBuilderに似ていますが、同期を実現するために、多くの方法では、次の方法など、lsynchronized Modificationを使用します。
public synchronized int length(){return count;} public synchronized stringbuffer append(string str){toStringcache = null; super.append(str);これを返します;} public同期void setLength(int newlength){toStringCache = null; super.setlength(newlength);}ご覧のとおり、同期はメソッドの前に実際に追加されます。
さらに、上記のappend()およびsetLength()メソッドには可変toStringCacheもあります。この変数は、toString()メソッドの最後のキャッシュに使用されます。 StringBufferが変更されると、この変数はNULLに割り当てられます。 StringBufferのトストリングは次のとおりです。
public synchronized string toString(){if(toStringCache == null){toStringCache = arrays.Copyofrange(value、0、count); }新しい文字列(toStringcache、true);}この方法では、toStringcacheの場合、最初にキャッシュされます。最終的に返された文字列オブジェクトは少し異なり、このコンストラクターにはパラメーターがあります。文字列のソースコードを見つけて、次をご覧ください。
string(char [] value、boolean share){// assert share: "unshared not supported"; this.value = value;}この構造方法によって構築された文字列オブジェクトは、実際に文字列をコピーするのではなく、構造パラメーターに値を指していることがわかります。これは、時間コピー要素を節約するためです。ただし、このコンストラクターにはパッケージアクセス許可があり、一般的には呼び出されません。
要約します
上記はこの記事に関するすべてです。 Java、StringBuilder、StringBufferで、一般的に使用される2つの操作文字列クラスを誰もが学ぶことが役立つことを願っています。