私は以前に文を読んだが、それはとても良かった。読み取りソースコードの使用は何ですか?特定の機能を実装し、プログラミングレベルを向上させるために、他の人のデザインのアイデアを学びます。
はい、誰もが関数を実装します。さまざまな人が異なるデザインのアイデアを持っています。一部の人々は10,000行のコードを使用し、一部の人々は5,000行を使用しています。コードを数十秒間実行する必要がある人もいれば、数秒しか必要としない人もいます。 。以下のトピックにアクセスしましょう。
この記事の主な内容:
jdk 1.8に基づくArrayListの実装に関する詳細なコメント。
iterterterterter sublist部分は詳細に説明されておらず、他のソースコード解釈に配置されます。ここでは、ArrayList自体の実装に焦点を当てます。
standard標準の注釈は使用されておらず、コードのインデントは簡単に紹介するために適切に調整されます
java.util.abstractlist; Import java.util.arrays; import java.util.bitset; import java.util.collection; Import java.util.comparator; Import java.util.concurrentModificationection; java.util.nosuchelementexception; import java.util.objects; import java.util.randomaccess; Import java.util.spliterator; import java.util.function.consumer; import java.util.function.predicate; impomtil.util.util.util.functiontator;サイズ変更できるリストインターフェイスの配列実装。すべてのオプションのリスト操作を実装し、nullを含むすべての要素を繰り返し可能にします。 *リストインターフェイスに加えて、このクラスは、配列のサイズを操作して、リストに配列のサイズを保存する方法を提供します。 * *時間の複雑さ: *メソッドサイズへの呼び出し、ISEMPTY、GET、SET、ITERATOR、LISTITERATORは一定の時間です。 *追加と削除の時間の複雑さはO(n)です。他のすべての操作は、線形時間の複雑さです。 * *容量: *各アレイリストには容量があり、容量のサイズは少なくともリスト要素の長さであり、デフォルトの初期化は10です。 *容量は自動的に増加できます。 *アレイに多くの要素があることを事前に知っている場合は、後の期間の自動容量の成長のオーバーヘッドを減らすために要素を追加する前に、EnsureCapacity()メソッドを呼び出すことにより、事前に容量を増やすことができます。 *この容量は、初期容量のコンストラクターによって初期化することもできます。 * *スレッドは安全ではありません: * arrayListはスレッド安全ではありません。 *マルチスレッドに適用する必要がある場合、同期する必要があります。 *このリストは構造的に変更されています。構造の変更とは、リストのサイズを変更するか、リストを破壊することを指し、進行中の反復が誤った結果を生成するようにします。 *このフィールドは、Iteratorとリストイテレーターの実装で使用されており、IteratorおよびListeratorメソッドによって返されます。 *このフィールドの値が誤って変更された場合、Iterator(またはList Iterator)は、次の回答に応じて同時モジオ化エクセプトをスローします。 *繰り返し中に同時の変更に直面すると、非決定的な動作ではなく、迅速な故障した動作を提供します。 *サブクラスがこのフィールドを使用するかどうかはオプションです。 *サブクラスが高速失敗イテレーター(およびリストイテレータ)を提供したい場合、このフィールドを追加(int、e)に追加し、(およびint)メソッド(およびオーバーライドするその他のメソッドを削除して、リスト構造の変更をもたらします)。 *追加(int、e)または削除(int)を追加する単一呼び出しの数は、このフィールドに1を超えてはなりません。そうしないと、iterator(およびlist Iterator)が偽のconcrurentModificiationExceptionsをスローします。 *実装が高速失敗イテレータを提供したくない場合、このフィールドは無視できます。 * * Transient: *デフォルトでは、オブジェクトのすべてのメンバー変数が持続されます。場合によっては、オブジェクトのメンバー変数の持続を避けたい場合は、過渡キーワードを使用してタグを付けます。これは、Java(JDK 1.8) */public class arraylist <e>の予約単語であり、Abstractlist <e> expend <e> exprents list <e>、randomAccess、cloneable、Java.io.io.io.io.searializable 8683452581122892189L; //デフォルトの初期容量プライベート静的最終int default_capacity = 10; //空のインスタンスと空の配列インスタンスを共有するために使用されます。 private static final object [] empty_elementData = {}; //デフォルトの空の配列private static final object [] defaultcapacity_empty_elementdata = {}; //右側の要素の配列、パッケージアクセス許可は一時的なオブジェクト[] elementDataを保存します。 //サイズ、Javaは、オブジェクトのプライベートINTサイズを作成するときにINTを0に初期化します。 //指定された数値で初期化容量のコンストラクターを設定すると、マイナス数は例外をスローしますpublic ArrayList(int initialCapacity){if(initialCapacity> 0){this.ElementData = new Object [initialCapacity]; } else if(initialCapacity == 0){this.ElementData = empty_ElementData; } else {throw new IllegalargumentException( "違法容量:"+initialcapacity); }} //デフォルトのコンストラクター、コントロール配列を使用してpublic arrayList(){this.ElementData = defaultCapacity_Empty_ElementData; } //コレクションの順序でコレクション内の要素を含むリストを作成しますパブリックアレイリスト(コレクション<?e> c){elementData = C.ToArray(); if((size = elementdata.length)!= 0){// c.toarray may(error)not return object [](java bug number 6260652)if(elementdata.getclass()!= object []。class)elementdata = arrays.copyof(elementdata、object、object []。 } else {//空の配列this.elementdata = empty_elementdata; }} //容量は多くの場合、実際の要素数よりも大きいためです。メモリがタイトな場合は、この方法を呼び出して予約位置を削除し、実際の要素数に容量を調整できます。 //要素が追加されないと確信している場合は、このメソッドを呼び出してスペースを節約することもできますpublic void trimtosize(){modcount ++; if(size <elementdata.length){elementData =(size == 0)? empty_elementData:arrays.copyof(elementdata、size); }} //指定されたパラメーターを使用して配列容量を設定しますpublic void ensurecapacity(int mincapacity){//配列が空の場合、それ以外の場合はデフォルト値(10)int minexpand =(elementdata!= defaultcapacity_empty_elementdata)? 0:default_capacity; //パラメーターがプリセット容量よりも大きい場合は、このパラメーターを使用して、(mincapacity> minexpand){suresexplicitcapacity(mincapacity); }} //要素を追加する場合、配列容量のプライベートボイドEnsureCapacity -internal(int mincapacity){//デフォルト値とより大きなパラメーターを容量プリセット値として使用します(elementData == defaultCapacity_ElementData){mincapacacity = math.max(default、mincapacacity); } suresexplicitcapacity(mincapacity); } //パラメーターが配列容量よりも大きい場合、配列容量を増やしますプライベートボイドSEVERESEXPLICTINGCAPACITY(int mincapacity){modCount ++; if(mincapacity -elementdata.length> 0)成長(mincapacity); } //配列の最大容量は、メモリオーバーフロー(VMメモリ制限)を引き起こす可能性があります。 //パラメータープライベートボイド成長(int mincapacity)で指定された要素の数を少なくとも保持できることを確認する容量を増やします{int oldcapacity = elementdata.length; //プリセット容量を半分に増やしますint newcapacity = oldcapacity +(oldcapacity >> 1); //パラメーターからより大きな値を取得する場合(newcapacity -mincapacity <0)// newcapacity <mincapacity newcapacity = mincapacity; //プリセット値がデフォルトの最大値よりも大きい場合は、(newcapacity -max_array_size> 0)newcapacity = hugecapacity(mincapacity)であふれているかどうかを確認します。 elementData = arrays.copyof(elementData、newCapacity); } //オーバーフローかどうかを確認します。オーバーフローがない場合は、最大整数値(JavaのINTは4バイトであるため、最大値は0x7ffffffffです)またはデフォルトの最大値プライベートスタティックint int ugeCapacity(int mincapacity){if(mincapacity <0)// overflow throw show new offmemoryerror(); return(mincapacity> max_array_size)? integer.max_value:max_array_size; } //配列サイズを返しますpublic int size(){return size; } //それは空ですか? } //番号が含まれているかどうか、bool public boolean contains(object o){return indexof(o)> = 0; } //アレイの最初の外観で値を返し、それがnullであるかどうかに基づいてさまざまな方法で審査されます。それが存在しない場合、それは-1を返します。時間の複雑さはo(n)public int indexof(object o){if(o == null){for(int i = 0; i <size; i ++)if(elementData [i] == null)return i; } else {for(int i = 0; i <size; i ++)if(o.equals(elementData [i]))return i; } return -1; } //配列に表示される最後に値を返します。それが存在しない場合、それは-1を返します。時間の複雑さはo(n)public int lastindexof(object o){if(o == null){for(int i = size-1; i> = 0; i-)if(elementData [i] == null)return i; } else {for(int i = size-1; i> = 0; i-)if(o.equals(elementdata [i]))return i; } return -1; } //コピーを返し、要素自体がコピーされておらず、コピープロセスの配列がpublic Object clone(){try {arraylist <?> v =(arraylist <?>)super.clone(); v.ElementData = arrays.copyof(elementData、size); v.modcount = 0; vを返します。 } catch(cloneNotsupportedexception e){新しい内部エラー(e)をスロー; }} //オブジェクト配列に変換するには、arrays.copyof()method public object [] toarray(){return arrays.copyof(elementdata、size); } //配列を返し、ランタイムを使用してタイプを決定すると、配列にはこのリストのすべての要素が含まれます(最初から最後の要素まで) arrays.copyof(elementdata、size、a.getclass()); System.ArrayCopy(elementData、0、a、0、size); if(a.length> size)a [size] = null; aを返します。 } //指定された位置の値を返します。それは配列であるため、特に高速@suppresswarnings( "unchecked")e elementData(int index){return(e)elementData [index]; } //指定された位置の値を返しますが、位置の数が配列長パブリックe get(int index){rangecheck(index)を超えるかどうかを確認します。 return elementData(index); } //指定された位置を新しい値に設定し、前の値を返します。この位置が配列長パブリックeセット(int index、e element)を超えるかどうかを確認します{rangecheck(index); e oldvalue = elementData(index); elementData [index] = element; OldValueを返します。 } //値を追加すると、最初にパブリックブールの容量を保証します(e e){ensurecapacityinternal(size + 1); elementData [size ++] = e; trueを返します。 } //指定された位置に値を追加し、追加された位置と容量パブリックボイド追加(int index、e element){rangecheckforadd(index); ensurecapacityinternal(size + 1); // public static void arraycopy(Object src、int srcpos、object dest、int destpos、int length)// src:ソースアレイ。 SRCPOS:コピーするソース配列の開始位置。 Dest:宛先配列; Destpos:宛先配列の開始位置。長さ:copy length system.arraycopy(elementData、index、elementData、index + 1、size -index); elementData [index] = element;サイズ++; } //指定された位置の値を削除し、追加された位置を確認し、以前の値パブリックe remove(int index){rangecheck(index); modcount ++; e oldvalue = elementData(index); int nummoved = size -index -1; if(nummoved> 0)System.ArrayCopy(elementData、index+1、elementData、index、nummoved); elementData [ - size] = null; //ごみ収集期間をリサイクルするのはoldvalueを返します。 } //指定された要素が最初に表示される場所を削除しますパブリックブールの削除(オブジェクトo){if(o == null){for(int index = 0; index <size; index ++)if(elementData [index] == null){fastremove(index); trueを返します。 }} else {for(int index = 0; index <size; index ++)if(o.equals(elementData [index])){fastRemove(index); trueを返します。 }} falseを返します。 } //指定された位置で値をすばやく削除します。それが高速と呼ばれる理由は、private void fastRemove(int index){modcount ++; int nummoved = size -index -1; if(nummoved> 0)System.ArrayCopy(elementData、index+1、elementData、index、nummoved); elementData [ - size] = null; // GCに作業を行わせる} //アレイをクリアし、各値をNULLに設定してガベージコレクションを容易にします(リセットとは異なり、アレイのデフォルトサイズは変更された場合にリセットされません)public void clear(){modcount ++; for(int i = 0; i <size; i ++)elementData [i] = null;サイズ= 0; } //コレクションの要素を最後に追加します。追加するコレクションが空である場合は、誤ったパブリックブールアダル(コレクション<?extends e> c){object [] a = c.toarray(); int numnew = a.length; ensurecapacityinternal(size + numnew); System.ArrayCopy(a、0、elementData、size、numnew); size += numnew; NumNew!= 0を返します。 } //関数は上記と同じです。パブリックブールアドラル(int index、collection <?extends e> c){rangecheckforadd(index); object [] a = c.toarray(); // int numnew = a.lengthを追加する配列; //追加される配列の長さは、surecapacityinternal(size + numnew); //容量int nummoved = size -index; //移動しない長さ(前の部分)の場合(nummoved> 0)//移動する必要がない場合は、それを単独でコピーして、配列の後ろ部分を正しい位置に移動します。 System.ArrayCopy(a、0、elementData、index、numnew); //変更された元の配列サイズの中央に新しい配列を追加 += numnew; NumNew!= 0を返します。 } //指定された範囲要素を削除します。パラメーターは、開始位置と終了位置が保護されたvoid removerange(int froming、int toindex){modcount ++; int nummoved = size -toindex; //後者のセクションSystem.ArrayCopy(elementData、toindex、elementData、fromindex、nummoved)によって保持されている長さ; int newsize = size-(toindex -fromindex); for(int i = newsize; i <size; i ++){elementData [i] = null; } size = newsize; } //要素を追加するときに数値が配列の長さを超えるかどうかを確認します。 } // private void rangecheckforadd(int index){if(index> size || index <0)throw new indexOutofboundSexception(outofboundsmsg(index)); } //スローされた例外の詳細プライベート文字列outofboundsmsg(int index)){return "index:"+index+"、size:"+size; } //指定されたコレクションの要素を削除してくださいパブリックブールムレム(コレクション<? } //指定されたコレクションの要素のみを保持しますpublic boolean reventhall(collection <?> c){objects.requirenonnull(c);バッチレモーブを返す(c、true); }/** * http://anxpp.com/によるソースコード解釈 * @param Complete true、指定されたコレクションの要素の値は配列から保持され、Falseの場合、指定されたコレクションの要素の値は配列から削除されます。 * @return配列内の複製要素は削除されます(1回または数回削除するのではなく)。 int r = 0、w = 0; Boolean Modified = false; {//アレイを介してtransweepを試して、このコレクションに対応する値が含まれているかどうかを確認し、値を配列の前面に保持する値を移動し、wの最後の値は保持される要素の数//単純なポイント:保持される場合、同じ要素を前のセクションに移動します。削除された場合、異なる要素を前のセクションに移動します(; r <size; r ++)if(c.contains(elementData [r])== complement)elementData [w ++] = elementData [r]; }最後に{//例外がスローされる前の部品が予想される操作を完了できることを確認しますが、トラバースされていないパーツは// r!=サイズはエラーが発生する可能性があることを意味します。 w += size -r; } // w ==サイズ:すべての要素が保持されることを意味するため、削除操作が発生しないため、falseが返されます。それ以外の場合は、trueと配列// w!=サイズが返された場合、tryブロックが例外をスローしたとしても、wは常に前の部分の長さであるため、操作がスローされます。 modcount += size -w; //変更された回数Size = w; //新しいサイズは、保存された要素の数を変更した= true; }} return modified; } //配列インスタンスの状態をストリームに保存します(つまり、シリアル化されています)。書き込みプロセスアレイが変更され、例外がプライベートボイドwriteObject(java.io.objectoutputStream s)がスローされます。 S.DefaultWriteObject(); //デフォルトの降下/シリアル化プロセスを実行します。このストリームに現在のクラスの非静的フィールドと非移植フィールドを書き込み//サイズS.WriteInt(size)に書き込みます。 //(int i = 0; i <size; i ++){s.writeObject(elementData [i]); } if(modcount!= expectsModCount){新しいconcurrentModificationException(); }} //上記が書かれている、これは読み取られます。 private void readobject(java.io.objectinputStream s)throws java.io.ioexception、classNotFoundException {elementData = empty_elementData; //デフォルトのシリアル化/降下プロセスを実行しますs.defaultreadobject(); //配列の長さを読み取りましたs.readint(); if(size> 0){ensurecapacityinternal(size); object [] a = elementData; //(int i = 0; i <size; i ++){a [i] = s.readobject();のすべての要素を読み取ります。 }}}} // return listitaterator、開始位置は指定されたパラメーターpublic Listiterator <e> listiterator(int index){if(index <0 || index> size)new indexoutofboundsecection( "index:"+index); new listitr(index)を返します。 } // return listiterator、開始位置は0 public listiterator <e> listiterator(){return new listitr(0); } //通常のiterator public Iterator <e> iterator(){return new itr(); } //一般的なイテレーターはプライベートクラスを実装しますITRはiterator <e> {int cursor; //カーソル、次の要素のインデックス、デフォルトの初期化は0 int lastret = -1です。 //最後にアクセスされた要素の位置はint expectModcount = modcount; //反復プロセスは変更された配列を実行しません。そうしないと、例外がスローされます//別のpublic boolean hasnext(){return cursor!= size; } //次の要素@suppresswarnings( "unchecked")public e next(){checkforcomodification(); //配列が変更されているかどうかを確認int i = cursor; if(i> = size)new nosuchelementexception(); object [] elementData = arrayList.this.ElementData; if(i> = elementData.length)を新しいconcurrentModificationException(); cursor = i + 1; //カーソルを後方に移動しますreturn(e)elementData [lastret = i]; //アクセス位置を設定してこの値を返します} //削除public public void remove(){if(lastret <0)throw new IllegalStateException(); checkforcomodification(); //配列が変更されているかどうかを確認してください{arraylist.this.remove(lastret); cursor = lastret;ラストレット= -1; expectsModCount = modCount; } catch(indexoutofboundsexception ex){新しいconcurrentModificationException(); }} @override @suppresswarnings( "unchecked")public void foreachremaining(consumer <?super e> consumer){objects.requirenonnull(consumer); final int size = arraylist.this.size; int i = cursor; if(i> = size){return; } final object [] elementData = arrayList.this.ElementData; if(i> = elementData.length){新しいconcurrentModificationException(); } while(i!= size && modcount == expectsmodcount){consumer.accept((e)elementData [i ++]); } cursor = i; lastret = i -1; checkforcomodification(); } //配列が変更されたかどうかを確認しますfinal void checkforcomodification(){if(modcount!= expectsModcount)new concurrentModificationException(); }} // listiterator Iteratorはプライベートクラスlistitrを実装していますextend ITR extrments listititerator <e> {listitr(int index){super(); cursor = index; } public boolean hasprevious(){return cursor!= 0; } public int nextindex(){return cursor; } public int fortion index(){return cursor -1; } @suppresswarnings( "unchecked")public e fortion(){checkforcomodification(); int i = cursor -1; if(i <0)を新しいnosuchelementexception(); object [] elementData = arrayList.this.ElementData; if(i> = elementData.length)を新しいconcurrentModificationException(); cursor = i; return(e)elementData [lastret = i]; } public void set(e e){if(lastret <0)throw new IllegalStateException(); checkforcomodification(); try {arraylist.this.set(lastret、e); } catch(indexoutofboundsexception ex){新しいconcurrentModificationException(); }} public void add(e e){checkforcomodification(); try {int i = cursor; arraylist.this.add(i、e); cursor = i + 1;ラストレット= -1; expectsModCount = modCount; } catch(indexoutofboundsexception ex){新しいconcurrentModificationException(); }}} //指定された範囲のパブリックリストのサブアレイを返す<e> sublist(int fromindex、int toindex){sublistrangecheck(fromindex、toindex、size);新しいサブリスト(this、0、fromindex、toindex)を返します。 } //セキュリティチェックstatic void sublistrangecheck(int fromindex、int toindex、int size){if(fromindex <0)throw new indexoutofboundsexception( "fromindex =" + fromindex); if(toindex> size)new indexoutofofboundsexception( "toindex =" + toindex); if(fromindex> toindex)新しいIllegalargumentException( "fromindex(" + fromindex + ")> toindex(" + toindex + ")"); } // Subarrayプライベートクラスのサブリストは、AbstractList <e>を実装しているabstractlist {private final abstractlist <e> parent;プライベートファイナルInt ParentOffset;プライベートファイナルINTオフセット。 intサイズ; sublist(abstractlist <e> parent、int offset、int fromindex、int toindex){this.parent = parent; this.parentoffset = fromindex; this.offset = offset + fromindex; this.size = toindex -fromindex; this.modcount = arraylist.this.modcount; } public e set(int index、e e){rangecheck(index); checkforcomodification(); e oldvalue = arraylist.this.elementdata(offset + index); arraylist.this.elementdata [offset + index] = e; OldValueを返します。 } public e get(int index){rangecheck(index); checkforcomodification(); return arraylist.this.elementdata(offset + index); } public int size(){checkforcomodification(); this.sizeを返します。 } public void add(int index、e e){rangecheckforadd(index); checkforcomodification(); parent.add(parentoffset + index、e); this.modcount = parent.modcount; this.size ++; } public e remove(int index){rangecheck(index); checkforcomodification(); e result = parent.remove(parentoffset + index); this.modcount = parent.modcount; this.size--;返品結果; }保護されたvoid removerange(int fromindex、int toindex){checkforcomodification(); Parent.Removerange(deriondex、fromindex、parentoffset + toindex); this.modcount = parent.modcount; this.size - = toindex -fromindex; } public boolean addall(collection <?extends e> c){return addall(this.size、c); } public boolean addall(int index、collection <?extends e> c){rangecheckforadd(index); int csize = c.size(); if(csize == 0)falseを返します。 checkforcomodification(); parent.addall(parentoffset + index、c); this.modcount = parent.modcount; this.size += csize; trueを返します。 } public Iterator <e> iterator(){return listiterator(); } public listiterator <e> listiterator(final int index){checkforcomodification(); RangeCheckforadd(index); final int offset = this.offset; new listiterator <e>(){int cursor = index; int lastret = -1; int expectsModCount = arrayList.this.modcount; public boolean hasnext(){return cursor!= sublist.this.size; } @suppresswarnings( "unchecked")public e next(){checkforcomodification(); int i = cursor; if(i> = sublist.this.size)新しいnosuchelementexception(); object [] elementData = arrayList.this.ElementData; if(offset + i> = elementData.length)を新しいconcurrentModificationException(); cursor = i + 1; return(e)elementData [offset +(lastret = i)]; } public boolean hasprevious(){return cursor!= 0; } @suppresswarnings( "unchecked")public e fortion(){checkforcomodification(); int i = cursor -1; if(i <0)を新しいnosuchelementexception(); object [] elementData = arrayList.this.ElementData; if(offset + i> = elementData.length)を新しいconcurrentModificationException(); cursor = i; return(e)elementData [offset +(lastret = i)]; } @suppresswarnings( "un -checked")public void foreachremaining(Consumer <?super e> Consumer){objects.Requirenonnull(Consumer); final int size = sublist.this.size; int i = cursor; if(i> = size){return; } final object [] elementData = arrayList.this.ElementData; if(offset + i> = elementData.length){new concurrentModificationException(); } while(i!= size && modcount == expectsmodcount){consumer.accept((e)elementData [offset+(i ++)]); } //イテレーションの終了時に1回更新して、ヒープを削減するトラフィックラストレット= cursor = i; checkforcomodification(); } public int nextindex(){return cursor; } public int fortion index(){return cursor -1; } public void remove(){if(lastret <0)throw new IllegalStateException(); checkforcomodification(); try {sublist.this.remove(lastret); cursor = lastret;ラストレット= -1; expectsModCount = arrayList.this.modcount; } catch(indexoutofboundsexception ex){新しいconcurrentModificationException(); }} public void set(e e){if(lastret <0)throw new IllegalStateException(); checkforcomodification(); try {arraylist.this.set(offset + lastret、e); } catch(indexoutofboundsexception ex){新しいconcurrentModificationException(); }} public void add(e e){checkforcomodification(); try {int i = cursor; sublist.this.add(i、e); cursor = i + 1;ラストレット= -1; expectsModCount = arrayList.this.modcount; } catch(indexoutofboundsexception ex){新しいconcurrentModificationException(); }} final void checkforcomodification(){if(expectionModCount!= arrayList.this.modcount)throw new concurrentModificationException(); }}; } public List <e> sublist(int fromindex、int toindex){sublistrangecheck(fromindex、toindex、size);新しいサブリスト(this、offset、fromindex、toindex)を返します。 } private void rangeCheck(int index){if(index <0 || index> = this.size)新しいindexOutOfOUTOUTOUPOUNDSEXCEPTION(OUTOFBOUNDSMSG(index)); } private void rangecheckforadd(int index){if(index <0 || index> this.size)新しいindexOutOutOutOutOutOutOUTOUTOUTOUT(outOfBoundSMSG(index)); } private string outofboundsmsg(int index){return "index:"+index+"、size:"+this.size; } private void checkforcomodification(){if(arraylist.this.modcount!= this.modcount)throw new concurrentModificationException(); } public Spliterator <e> splitterator(){checkforcomodification(); new arrayListspliterator <e>(arrayList.this、offset、offset + this.size、this.modcount); }} @Override public void foreach(Consumer <?super e> action){objects.requirenonnull(action); final int expectModCount = modCount; @suppresswarnings( "Unchecked")final e [] elementData =(e [])this.elementData; final int size = this.size; for(int i = 0; modcount == expectsmodcount && i <size; i ++){action.accept(elementData [i]); } if(modcount!= expectsModCount){新しいconcurrentModificationException(); }}/** * a <em> <a href = "spliterator.html#binding" rel = "external nofollow">遅延結合</a> </em> *および<em> faile-fast </em> {@link spliter}をこの *リストの要素に及ぼします。 * * <p> {@code spliterator}レポート{@link spliterator#sized}、 * {@link spliterator#subized}、および{@link spliterator#ordered}。 *オーバーライド実装では、追加の *特性値のレポートを文書化する必要があります。 * * @return a {@code spliterator}このリストの要素の上に * @since 1.8 */ @override public Spliterator <e> splitterator(){return new arraylistspliterator <>(this、0、-1、0); } /** 2つの2つのスプリット、レイジー初期化されたスプライターター * /静的最終クラスArrayListspliterator <e> spliterator <e> { / * * Arraylistsが不変であるか、構造的に不変である場合(No *追加、削除など)、Arrays.pliteratorを使用してスプリターター *を実装できます。代わりに、多くのパフォーマンスを犠牲にすることなく、トラバーサル中に実用的であると同じくらいの *干渉を検出します。主に * modcountsに依存しています。これらは、同時性 *暴力を検出することを保証されておらず、スレッド内の干渉について *過度に保守的であることがありますが、実際には価値があるために十分な問題を検出します。これを実行するために、(1)フェンスを初期化し、最新の *をチェックしている状態にコミットする必要があるということを期待しています。したがって、精度を改善します。 (これは *サブリストには当てはまりません。これは、現在の怠zy *値を持つスプリテーターを作成します)。 (2)foreach *(最もパフォーマンスに敏感な方法)の最後に、単一の * concurrentModificationExceptionチェックのみを実行します。 foreach *を使用する場合(イテレーターとは対照的に)、通常、アクション後の干渉のみを検出することができます。さらに * cme-triggeringチェックは、干渉のためにしか発生できなかったサイズ()の場合、そのサイズ()の場合、nullまたはtoo-small * elementDataアレイなど、他のすべての可能性のある *仮定の暴力に適用されます。これにより、foreachの内側ループ *がさらなるチェックなしで実行され、 *ラムダ解像度を単純化できます。これには *チェックの数が必要ですが、 * list.stream()。foreach(a)の一般的なケースでは、チェックまたはその他のコンピューティング *は、内部のforeach自体以外の場所で発生しないことに注意してください。他の *使用されていないメソッドは、これらの流れのほとんどを利用することはできません。 */プライベートファイナルアレイリスト<e>リスト;プライベートインデックス; //現在のインデックス、Advance/Split Private Int Fenceで変更されました。 // -1が使用されるまで;その後、最後の1つのインデックスプライベートintModCount。 // fence setのときに初期化/ **指定された範囲をカバーする新しいスプライターターを作成*/ arrayListspliterator(arrayList <e> list、int ovision、int fence、int speddemodcount){this.list = list; // ok nullの場合は、this.index = origin; this.fence = fence; this.expectedModCount = expectsModCount; } private int getfence(){//最初の使用時にフェンスをサイズに初期化します。 //(特殊なバリアントがMethod foreachに表示されます)arrayList <e> lst; if((hi = fence)<0){if((lst = list)== null)hi = fence = 0; else {expectsModcount = lst.modcount; hi = fence = lst.size; }} hiを返します。 } public ArrayListspliterator <e> trysplit(){int hi = getfence()、lo = index、mid =(lo + hi)>>> 1; return(lo> = mid)? null://新しいarraylistspliterator <e>(list、lo、index = mid、expectsmodcount)が小さすぎない限り、範囲を半分に除算します。 } public boolean tryAdvance(Consumer<? super E> action) { if (action == null) throw new NullPointerException(); int hi = getFence(), i = index; if (i < hi) { index = i + 1; @SuppressWarnings("unchecked") E e = (E)list.elementData[i]; action.accept(e); if (list.modCount != expectedModCount) throw new ConcurrentModificationException(); trueを返します。 } falseを返します。 } public void forEachRemaining(Consumer<? super E> action) { int i, hi, mc; // hoist accesses and checks from loop ArrayList<E> lst; Object[] a; if (action == null) throw new NullPointerException(); if ((lst = list) != null && (a = lst.elementData) != null) { if ((hi = fence) < 0) { mc = lst.modCount; hi = lst.size; } else mc = expectedModCount; if ((i = index) >= 0 && (index = hi) <= a.length) { for (; i < hi; ++i) { @SuppressWarnings("unchecked") E e = (E) a[i]; action.accept(e); } if (lst.modCount == mc) return; } } throw new ConcurrentModificationException(); } public long estimateSize() { return (long) (getFence() - index); } public int characteristics() { return Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED; } } @Override public boolean removeIf(Predicate<? super E> filter) { Objects.requireNonNull(filter); // figure out which elements are to be removed // any exception thrown from the filter predicted at this stage // will leave the collection unmodified int removeCount = 0; final BitSet removeSet = new BitSet(size); final int expectedModCount = modCount; final int size = this.size; for (int i=0; modCount == expectedModCount && i < size; i++) { @SuppressWarnings("unchecked") final E element = (E) elementData[i]; if (filter.test(element)) { removeSet.set(i); removeCount++; } } if (modCount != expectedModCount) { throw new ConcurrentModificationException(); } // shift surviving elements left over the spaces left by removed elements final boolean anyToRemove = removeCount > 0; if (anyToRemove) { final int newSize = size - removeCount; for (int i=0, j=0; (i < size) && (j < newSize); i++, j++) { i = removeSet.nextClearBit(i); elementData[j] = elementData[i]; } for (int k=newSize; k < size; k++) { elementData[k] = null; // Let gc do its work } this.size = newSize; if (modCount != expectedModCount) { throw new ConcurrentModificationException(); } modCount++; } return anyToRemove; } @Override @SuppressWarnings("unchecked") public void replaceAll(UnaryOperator<E> operator) { Objects.requireNonNull(operator); final int expectedModCount = modCount; final int size = this.size; for (int i=0; modCount == expectedModCount && i < size; i++) { elementData[i] = operator.apply((E) elementData[i]); } if (modCount != expectedModCount) { throw new ConcurrentModificationException(); } modCount++; } @Override @SuppressWarnings("unchecked") public void sort(Comparator<? super E> c) { final int expectedModCount = modCount; Arrays.sort((E[]) elementData, 0, size, c); if (modCount != expectedModCount) { throw new ConcurrentModificationException(); } modCount++; }}要約します
The above is all about ArrayList source code analysis in Java programming, and I hope it will be helpful to everyone.興味のある友人は、このサイトの他の関連トピックを引き続き参照できます。欠点がある場合は、それを指摘するためにメッセージを残してください。このサイトへのご支援をありがとうございました!