コード上の騒ぎ、
クラス名の先頭から1(私はそう甘いよ、自分でこのようなポイントを与えます)
パブリック クラスアレイ<E>
ファーストクラスはジェネリックの配列を必要とする、これは非常に述べています。ことに注意してくださいJavaでは、配列は、単一のタイプを保持することができます。
2.メンバ変数
プライベート int型のサイズ; // 配列の要素の数 プライベート E []データ; // 配列宣言
:余談を挿入
私はすべてのインデックス配列の最初の、トラブルのアレイを学習し始めたときに、大きさ及びインデックスについてインデックスのサイズは、グループの要素であるが、ゼロであり
、その後、数、配列は三つの要素を有していると仮定サイズ= 3、および指数は0.1でした。彼らは貧しい一つであり、かつ、設計の魔法私はサイクルの時に境界条件を書くたびに聞かせて
、常にそれを変換します。
例えば、アレイのすべての要素を横切ります
以下のために(int型 i = 0; iは、サイズ<; iは++){}
私の考え方はこれです:
まず、最初のステップは、最後の要素のインデックスは、forループで来ることになっているし、私はする必要があり、最後に、0から始まる、最後の要素のインデックス位置を希望の
最後未満で要素の次のインデックス位置、それがインデックスよりも大きな規模の大きさ、ああ、のために、それはサイズである必要があり、誰であるか、次の最後の要素の後、インデックス
ので、私はサイズを<すべきである;
それぞれのために書く場合サイクル境界は、我々は精神的なアフガニスタンの無駄な消費、考えなければならないとき。それはちょうど私が愚かです。
最後に、私のアプローチはして変換するマップ念頭に置いておきます。あなたは直接の心を使用するたびにこの図の外に出てきます。
学習の自然は複雑な物事を簡素化することです。
前記構成方法は、
アレイのユーザ指定の初期容量は、
ユーザは、アレイの初期容量を指定していません
公共配列(int型の容量){ データ =(E [])新しいオブジェクト[容量]。 サイズ = 0 。 } パブリックアレイ(){ この(10); // 別のコンストラクタを呼び出すと、デフォルトの容量は10です }
必要な基本の4家
// の配列番号得る 公共 INT のgetSize(){ 戻りサイズを、 } // 配列の長さを取得 公共 INT getCapacity(){ 戻りdata.lengthと、 } // 配列がnull得る パブリック ブールのisEmpty(){ 戻りサイズ== 0 。 }
5.メソッドを追加します。
自然は、アレイに追加するだけです。後ろから指定されたインデックスに、各要素は新しい場所のための余地を作るために、グリッドを後退します。
フォーカス:奥から手前に
// 配列要素指定された場所に加え、指定されたインデックスのインデックスは、eは追加の値である 公共 ボイド追加(int型のインデックス、E E){ // インデックス位置がブラインド挿入することができないが、屈折率が負である、又はジャンプグリッド補間が、ではありません。 IF(インデックス<0 ||インデックス> サイズ){ スロー 新新はIllegalArgumentException( "追加が失敗、必要とインデックスIS <0 ||インデックス>サイズ" ); } // アレイ容量はフルタイム、それは配列の二倍の現在の長さに拡張され、拡張メソッドを呼び出すとき。 IF(data.length == サイズ){ この .resize(data.length * 2 )。 } のための(int型 I =サイズ- 1; I> =指数; i-- ){ データ[I +1] = データ[I]; } // 新しい吸気ピット データ[インデックス] = E; // メンテナンスのサイズの 大き++ ; }
//は、最初の配列要素に加え 公共 ボイドaddFirst(E E)は{ // 直接多重化方法は、追加費やす この .add(0 、E)を、 } // 最後の要素を配列に追加 公共 ボイドaddLast(E E){ // 同様に 、この.add(サイズ、E)。 }
6.削除方法(私の個人的な値に基づいて削除を削除するインデックスによって、2つのに分けます)
自然は削除しますとコントラストを追加し、次の位置からインデックスが前方ピットの所持が続く、最後の要素のインデックス位置の最後に、削除します。
重要:前面から背面へトラバースするとき
// 削除する要素を返すための要素を削除するインデックス 公共 E削除(int型のインデックス){ IF(インデックス<0 ||インデックス> = サイズ){ スロー 新新「(例外:IllegalArgumentException削除は失敗が、必要とインデックスIS <0 ||インデックス>サイズ= " ); } // 最初の要素は、最大保存削除する、またはそのカバーを与えるだろう。 値= E DATA [インデックス]; のための(INT。I =インデックス+ 1; Iは、サイズ<; I ++は){ データ[I -1] = データ[I]; } // サイズの維持 -サイズは; // 汎用的な理由は、アレイに格納されているクラスのオブジェクトに渡されるため、ここでなぜ、ガベージコレクタができず、参照アドレスである、常時開口引用し、nullに設定リサイクル。 データ【サイズ] = NULL ; // 体積の減少は、アレイ素子の数が四半期配列の長さに等しいとき、体積が減少する
IF(data.lengthサイズ== / 4 && data.length / 2 = 0!){ // の配列の長さの半分の体積減少 この .resize(data.length / 2 )。 } 戻り値; }
疑問は、なぜそれの半分の体積の減少ではない、でしょうか?しかし、それの四分の一?
ここでは、脳震盪の問題、より極端な例複雑になります:
例えばアレイ容量10、
この時点で、アレイが一杯である、素子アレイの拡張に来るために、この時間は、この時の状況は、20のアレイ容量に要素の追加が完了しました
インサイド11個の要素があります。
この時点で、私は削除後の配列要素を削除したいと思い、10への配列要素の数、アレイの丁度半分の長さ、
次いで、自動音量の低減など、操作が繰り返され、時間複雑さの各拡張ボリュームの減少はO(N)であり、ここで適用されるので、遅延された溶液
配列の要素の数は、配列の長さの四分の一まで、さらに体積の減少を待つことである場合には、この問題は回避されます。
// 削除された要素の値 公共 ボイドremoveByValue(E E){ // 要素の値を見つけることによる多重化方法は、インデックス(以下、この方法)を返す int型のインデックス= この.getByElement(E)を、 IF(インデックス=! -1 ){ // 多重化インデックスの削除方法によれば 、この.remove(インデックス) } } //は、最初の要素削除 パブリックE removeFirstと(){ リターンを この .remove(0 )。 } // の最後の要素を削除 パブリック)E removeLastを({ 返す これ .remove(サイズ- 1 )。 }
7.ルックアップ方法は、(再度値に従ってインデックスによって、2つのに分けます)
// インデックスによる素子アレイの戻り値を見つけるために パブリック E getByIndex(int型のインデックス){ 場合(インデックス<0 ||インデックス> = サイズ){ スロー 新しいはIllegalArgumentExceptionが( "取得失敗で、インデックス<0 ||インデックス> =サイズが必要" )。 } 戻りデータ[インデックス]。 }
// 値は、素子アレイをルックアップのインデックス戻り 公共 INT getByElement(E E){ // 性質:配列トラバース整列されている ため(INT I = 0;私は<サイズ; Iは++ ){ IF (DATA [I]を。等号(E)){ 戻りIと、 } } 返す -1 ; }
// 要素が含まれているかどうかを パブリック ブールを含み(E E){ // 性質:配列トラバース整列されている ため(int型 I = 0; Iは、サイズ<; Iは++ ){ IF (データ[I] .equals(E)){ 返す trueに。 } } 返す 偽; }
変形例に記載の方法
// 配列の要素変更 公共 ボイド SET(int型のインデックス、E E)を{ 場合(インデックス<0 ||インデックス> = サイズ){ スロー 新しい、IllegalArgumentExceptionを( "セットは、失敗<0 ||インデックス> =サイズインデックス必要である" )と、 } データ[インデックス] = E。 }
9.容量拡張
自然の拡張:つまり、古い配列の過去の内容をコピーし、新しい配列を開くために
プライベート ボイドサイズ変更(int型newCatacity){ E []あるnewData =(E [])新しいオブジェクト[newCatacity]。 以下のために(int型 i = 0; iは、サイズ<; iは++ ){ あるnewData [I] =のデータ[I]; } (メモリマップの説明の後ろに)新たな基準に再割り当て//メンバ変数データ データ = あるnewData; }
基準変換拡張メモリマップを描きます
テストコード
パブリック 静的 ボイドメイン(文字列[]引数){ アレイ <整数>配列= 新しいアレイ(5 )。 array.addLast( 1 )。 array.addLast( 2 )。 array.addLast( 3 )。 array.addLast( 4 )。 array.addLast( 5 )。 }
10.toString方法
エッセンスは:StringBuilderオブジェクトを作成し、メソッドを追加するために、配列トラバーサルの内容は、StringBuilderオブジェクトを追加します。
@Override パブリック文字列のtoString(){ StringBuilderのStringBuilderの = 新しい新規のStringBuilder(); // フォーマット(文字列、オブジェクト、オブジェクト)が指定された2つのオブジェクト・インスタンスのテキスト文字列同等の値で指定されたフォーマットを置き換え。 StringBuilder.Append(String.Formatの( "サイズ=%のD、D容量=%\ N-" 、サイズ、data.length))。 stringBuilder.append( '[' )。 以下のために(int型 i = 0; iは、サイズ<; iは++ ){ stringBuilder.append(データ[I])。 もし(私!=サイズ-1 ){ stringBuilder.append( '' ); } } stringBuilder.append(']'); return stringBuilder.toString(); }
最后,
浮于表面看千遍,
不如自己思一遍,
希望这篇文章能够对你起到帮助。