長い間、コードでより頻繁に使用されるデータリストが主にリストであり、それらはすべてArrayListです。このことは十分だと感じています。 ArrayListは、動的配列を実装するために使用されるラッパーツールクラスであるため、コードを作成するときに、出入りすることができ、繰り返され、トラバースがかかります。これは非常に便利です。
HashmapやHashsetなどのツールクラスをゆっくりと開始し始めたのは、Codeに頻繁に表示されることがよくあります。 Hashmapがより一般的であり、それは古典的なインタビューの質問でもあると言われるべきです。そのため、日常生活でもっと読みます。私が最初にそれを使用し始めたとき、私はそれを単にキー価値の対応するテーブルとして理解しました、そして、キーを使用してデータを見つける方がより便利です。さらなる調査の後、私は知りました
このことには、特にJDKの新しいバージョンがハッシュマップをツリーに変更した後、コードは少し複雑です。
セットを少なく使用し始めましたが、誤ってコードでツリーセットを見つけました。このクラスには滑らかさがあることがわかりました。とても面白いと感じました。これも良いツールであることを徐々に発見しました。
コードが多すぎると、基本の重要性を感じているので、ここで短い記事を書き、コレクションに関する知識を簡単に整理します。
わかりました、簡単に整理しましょう:
•リスト:つまり、配列とリンクリストの関数をサポートし、一般に線形です。
•マップ:キーと値の間に対応する関係を保存するマッピングテーブルです。
•設定:主にデータを並べ替えてソートするために使用される設定を意味します
最初にリストを見てみましょう
リストは、次のような線形データを保存するためのウィンドウです。配列用の配列、リンクリスト用のLinkedList。
arrayList
これは配列リストですが、リストインターフェイスを実現するための自動拡張機能を提供します。外部操作は、安全で便利なインターフェイス宣言方法からアクセスされます。
ArrayListの鍵は、自動容量拡張です。オブジェクトが初期化されている場合、またはデフォルトの容量を測定できるときに、初期容量を設定できます。配列のサイズが特に明確でない場合、初期サイズを指定できません。明確な場合は、サイズを指定でき、動的拡張によって引き起こされる遅延が減少します。これについて言えば、拡張がどのように実装されているかについて話す必要があります。次のコードを見てください。
private void grow(int mincapacity){//オーバーフロー意識コードint oldcapacity = elementdata.length; int newcapacity = oldcapacity +(oldcapacity >> 1); if(newcapacity -mincapacity <0)newcapacity = mincapacity; if(newcapacity -max_array_size> 0)newcapacity = hugecapacity(mincapacity); // mincapacityは通常サイズに近いため、これはwinです。 }Growは、要素またはいくつかの簡単なチェックを追加するときにArrayListをトリガーする方法です。主なプロセス:
1.配列の長さを取得して、oldcapacity/2に相当する正しい移動し、新しい長さを取得します
2。この長さが最小容量よりも少ない場合、直接使用するのは簡単です。
3.最大よりも大きい場合は、最大値を取得します。ここでは、主にMINCAPACITYとMAX_ARRAY_SIZEを比較するために、ここで呼び出されます。 mincapacityがmax_array_sizeよりも大きい場合は、integer.max_valueを使用して、それ以外の場合はmax_array_sizeを取得します。興味深いことに、max_array_sizeはinteger.max_value -8;これを行うことの意味が何であるかわかりません
4.最後に、コピー方法を呼び出して、既存の番号を新しい配列にコピーします。
このコピープロセスのため、配列が比較的大きい場合、拡張は確かに遅れを起こします。したがって、最初から最大値を知っていて、この値に簡単に成長できる場合、開始初期化時にサイズを指定すると特定の効果があります。
LinkedList
これは、リンクリストのツールクラスです。リンクされたリストの利点は、それらが物事をより速く追加および削除することですが、それらが遅くなることがわかります。
コードに関しては、一連のポインターによってリンクされているという特別なものは何もないようです。もちろん、Javaは代わりにオブジェクトを使用してノードオブジェクトを作成します。ノード自体は、前のノードと次のノードを指します。これは、リンクされたリストの構造です。
プライベート静的クラスノード<e> {e item; node <e> next; node <e> prev; node(node <e> prev、e element、node <e> next){this.item = element; this.next = next; this.prev = prev; }}次に、2つのノードを使用して頭と尾を指して、それが完了します。次のコード:
/***最初のノードへのポインター。 * Invariant :( first == null && last == null)|| *(first.prev == null && first.item!= null) */ transient node <e> first; /***最後のノードへのポインター。 * Invariant :( first == null && last == null)|| *(last.next == null && last.item!= null) */ transient node <e> last;
追加操作を参照してください:
/*** eを最後の要素としてリンクします。 */ void linklast(e e){final node <e> l = last;最終ノード<e> newNode = new Node <>(l、e、null); last = newNode; if(l == null)first = newNode; else l.next = newNode;サイズ++; modcount ++; }過去は次のとおりです。
1。最後のノードを取得してlに入れます
2。新しいノードを作成し、このノードにデータを取得します。作成プロセスは、新しいノードの前にlを指し、チェーンに接続されます。
3。次に、この新しいノードに続きます
4.次に、Lがnullかどうかを判断します。 nullがnullの場合、それは空のリンクリストであることを意味します。新しいノードは最初の要素です。このようにして、最初はNewNodeを指す必要があります
5.空になっていない場合は、lの次のLをNewNodeに向けます
6。蓄積カウンター
削除操作は、このノードの移動操作を指すフロントノードとバックノードでもあります。
地図を見てみましょう
マップは、キーと値のマッピングテーブルのアプリケーションです。主な実装クラス:Hashmap、Hashtable、Treemap
ハッシュマップとハッシュテーブル
ハッシュマップは、キー価値マッピングにハッシュアルゴリズムを使用するものです。 Hashtableは、同期したスレッドセーフクラスです。これがそれらの主な違いです。原則は似ており、すべてバケット +チェーンの組み合わせによって達成されます。バケットはキーを保存するために使用され、値はハッシュ衝突のためにリンクリストに保存する必要があります。
•バケットの重要性は効率にあり、ハッシュ計算を1つのステップに配置できます。
•リンクリストの意味は、繰り返されるハッシュのデータにアクセスすることです
私が書いた特定の原則「研究ノート:ハッシュテーブルとハッシュマップ」
しかし、JDK1.8のハッシュマップがストレージ構造を変更し、赤と黒の木の構造を採用していることがわかりました。これにより、リンクされたリスト検索の効率が解決される可能性がありますか?詳細な研究は行われませんでした。
Treemap
Treemapのコードを読んだ後、私はまだ木の構造、赤と黒の木を使用していることがわかりました。赤と黒の木が注文されているため、自然に並べ替え機能があります。もちろん、特定のソートを達成するために、コンパレータを介して比較方法を指定することもできます。
ツリー構造は保存に使用されるため、データを追加および削除する方が面倒です。プットコードを見てみましょう。
public v put(k key、v value){entry <k、v> t = root; if(t == null){compare(key、key); //タイプ(および可能なnull)root = new entry <>(key、value、null);サイズ= 1; modcount ++; nullを返します。 } int cmp;エントリ<k、v>親; //コンパレータと比較可能なパスコンパレータ<? Super K> CPR = Comparator; if(cpr!= null){do {parent = t; cmp = cpr.compare(key、t.key); if(cmp <0)t = t.left; else if(cmp> 0)t = t.right;それ以外の場合は、t.setValue(value)を返します。 } while(t!= null); } else {if(key == null)新しいnullpointerexception(); @suppresswarnings( "unchecked")同等の<? Super K> k =(comparable <?super k>)key; {parent = t; cmp = k.compareto(T.Key); if(cmp <0)t = t.left; else if(cmp> 0)t = t.right;それ以外の場合は、t.setValue(value)を返します。 } while(t!= null); } entry <k、v> e = new entry <>(key、value、parent); if(cmp <0)parent.left = e; else parent.right = e; fixafterinsertion(e);サイズ++; modcount ++; nullを返します。 }1.最初にルートノードが存在するかどうかを確認します。存在しない場合、それは最初のデータであり、ツリーのルートとして直接使用されることを意味します。
2。コンパレータがあるかどうかを判断します。ある場合は、コンパレータを使用して、データのストレージ場所を見つけます。コンパレータリターンの結果が0未満の場合は、左を取って右に進み、それ以外の場合は現在のノードの値を直接交換します。
3.コンパレータがない場合、キーはノードのキーと直接比較されます。比較は以前の方法と同じです。
4.次のステップは、見つかった親にチャイルドノードを作成し、左または右の子ノードに配置することです。
5. fixafterinsertionは、ノードを着色することです
6。アキュムレータ処理
また、データを削除するときは少し面倒です。データの削除に加えて、赤と黒の木を再調整する必要もあります。
さらに、TreeMapはNavigableMap <K、V>インターフェイスを実装するため、データセットでの返品操作も提供します。
最後に、セットをご覧ください
主に2種類のアプリケーションを設定します:ハッシュセットとツリーセット。
ハッシュセット
文字通りの意味は、ハッシュのコレクションを使用して非常に明確です。このコレクションの特徴は、ハッシュアルゴリズムを使用してデータを保存することであるため、データは複製されず、アクセスは比較的高速です。それはどのように行われましたか?
public boolean add(e e){return map.put(e、present)== null; }マップオブジェクトがあることがわかります。地図が何であるかを見てみましょう。
プライベートトランジェントハッシュマップ<e、オブジェクト>マップ;
ハッシュマップです。 Hashmapを知っている人は、そのようなデータが繰り返されないことを理解するでしょう。オブジェクト自体は堆積したときにキーとして保存されるため、ハッシュマップには1つのコピーのみが存在します。
これや他のことを理解した後、あなたはよく理解するでしょう。
ツリーセット
このセットは、セットのソートに使用されます。つまり、重いソートをソートする機能に加えて、独自のソート機能を持つこともできます。しかし、ツリーセットのコードを見た後、私はそれがTreemapの基本に実装されていることを発見しました。より正確には、それは派生したnavigablemapの派生クラスである必要があります。 Treesetは、デフォルトでMAPを指定することなくTreeMapに基づいています。
public treeset(){this(new treemap <e、object>()); }それで、私たちがここにもっと注意を払うかもしれないのは、ツリーセットがどのように頑丈であるかということですか?追加の方法を見てみましょう:
public boolean add(e e){return m.put(e、sprest)== null; }ハッシュセットに多少似ており、どちらも重い負荷を実現するためのMAPの機能に基づいています。それは本当にシンプルで効果的です。
上記は、編集者がもたらすJavaのセット、リスト、マップの詳細な説明です。 wulin.comをもっとサポートできることを願っています〜