私はしばしば、過去のインタビューでそのような質問に遭遇しました。悲しいかな、私は恥ずかしいです、財団はあまりにも貧弱です、方法はありません、私は不当な扱いをします
次に、これら3つの違いと接続について話す必要があります。これら3つはリストインターフェイスを実装し、すべてリストインターフェイスで定義されたメソッドを持ち、コレクションインターフェイスのメソッドもあります。
ArrayList:Arrayメソッドを使用してデータを保存し、クエリと変更速度は高速ですが、追加と削除速度は遅くなります
LinkedList:リンクリストの方法を使用してデータを保存します。クエリと変更速度は遅いですが、追加と削除速度は高速です。
ベクトル:Java 1.2の前にベクトルを使用していましたが、Java 1.2の後に使用され、同時に効率が低下します。イテレーター、列挙、get(int index)、およびindexof(int index)ですが、arraylistには列挙はありません
アレイリストとベクトルは、この配列の要素の数が大きいため、直接シーケンス番号インデックス要素を追加しますが、配列要素と他のメモリを移動するように設計する必要があります。操作は、データが速くなるため、同期された方法ですまたは後方のトラバーサルですが、データを挿入するときはこのアイテムのみが必要なので、数度をより速く挿入します。
線形テーブル、リンクされたリスト、およびハッシュテーブルは、一般的に使用されるデータ構造です。JDKは、基本的なデータ構造を実装するための一連の対応するクラスを提供しています。これらのクラスはすべてjava.utilパッケージにあります。この記事では、読者に各クラスの役割と、簡単な説明を通じて正しく使用する方法を説明しようとします。
コレクション├list├linkedList│rayList│vector│STACK└STACK├Hashtable├hashmap
コレクションインターフェイス
コレクションは、最も基本的なコレクションインターフェイスです。つまり、コレクションの要素(要素)を表します。一部のコレクションは同じ要素を許可しますが、他のコレクションはそうではありません。ソートできる人もいれば、できない人もいます。 Java SDKは、Java SDKが提供するクラスはすべて、リストやセットなどのコレクションから継承されるクラスを提供しません。
コレクションインターフェイスを実装するすべてのクラスは、2つの標準コンストラクターを提供する必要があります。パラメーターレスコンストラクターは、空のコレクションを作成するために使用され、コレクションパラメーターコンストラクターが新しいコレクションを作成します同じ要素。後者のコンストラクターを使用すると、ユーザーはコレクションをコピーできます。
コレクション内のすべての要素を反復する方法は?コレクションの実際のタイプに関係なく、ITERATOR()メソッドをサポートします。Iterator()メソッドは、Iteratorを返し、このイテレーターを使用してコレクション内の各要素に1つずつアクセスします。典型的な使用法は次のとおりです。
iterator it = collection.iterator();
コレクションインターフェイスから派生した2つのインターフェイスはリストとセットです。
リストインターフェイスをリストします
リストは順序付けられたコレクションであり、このインターフェイスを使用すると、各要素挿入の位置を正確に制御できます。ユーザーは、インデックス(リスト内の要素の位置、アレイサブスクリプトと同様)を使用して、Javaの配列に似たリスト内の要素にアクセスできます。
以下のセットとは異なり、リストは同じ要素を許可します。
必要なコレクションインターフェイスを持つIterator()メソッドに加えて、ListはListIterator()メソッドも提供します。要素を削除、設定し、前方または後方に移動することもできます。
リストインターフェイスを実装する一般的なクラスには、LinkedList、ArrayList、Vector、Stackが含まれます。
LinkedListクラス
LinkedListはリストインターフェイスを実装し、null要素を許可します。さらに、LinkedListは、LinkedListのヘッダーまたはテールに追加の取得、削除、挿入、挿入を提供します。これらの操作により、LinkedListはスタック、キュー、または双方向キューとして使用できます。
LinkedListには同期方法がないことに注意してください。複数のスレッドが同時にリストにアクセスする場合、自分でアクセス同期を実装する必要があります。 1つの解決策は、それを作成するときに同期リストを構築することです。
リストリスト= collections.synchronizedList(new LinkedList(...));
ArrayListクラス
ArrayListは可変サイズの配列を実装します。 nullを含むすべての要素が可能になります。 ArrayListは同期されていません。
サイズの実行時間、ISEMPTY、GET、SETメソッドは一定です。ただし、ADDメソッドのオーバーヘッドは償却定数であり、N要素を追加するのにO(n)時間がかかります。他の方法には線形実行時間があります。
各ArrayListインスタンスには容量があり、これは要素を保存するために使用される配列のサイズです。この容量は、新しい要素が絶えず追加されると自動的に増加する可能性がありますが、成長アルゴリズムは定義されていません。多数の要素を挿入する必要がある場合、挿入効率を向上させるためにアレイリストの容量を増やすために挿入する前に、surecapacityメソッドを呼び出すことができます。
LinkedListと同様に、ArrayListも同性化されていません。
ベクトルクラス
ベクトルはArrayListに非常に似ていますが、Vectorは同期しています。ベクトルによって作成されたイテレーターは、アレイリストによって作成されたイテレーターによって作成されましたが、アレイリストによって作成されたイテレーターと同じインターフェイスです。これは、1つのイテレーターが作成されて使用されているときに、ベクトルが同期されるため、別のスレッドがベクトルのステータスを変更するため(たとえば、追加の追加を変更します。または、いくつかを削除する)この時点で、Iteratorメソッドが呼び出されると同時モジオ化エクセプトがスローされるため、例外をキャッチする必要があります。
スタッククラス
スタックはベクトルから継承し、最終的な最初のスタックを実装します。 Stackは、ベクトルをスタックとして使用できるようにする5つの追加方法を提供します。基本的なプッシュメソッドとピークメソッドは、スタックの上部に要素を取得し、空のメソッドはスタックが空であるかどうかをテストし、検索方法はスタック内の要素の位置を検出します。スタックは作成されたばかりで、空のスタックです。
インターフェイスを設定します
SETは、重複要素を含むコレクションです。つまり、E1とE2にはE1.Equals(E2)= Falseがあり、SETには最大1つのnull要素があります。
明らかに、Setのコンストラクターには制約があり、合格したコレクションパラメーターには重複要素を含めることはできません。
注意:可変オブジェクトは注意して操作する必要があります。セット内の可変要素が独自の状態を変更すると、Object.equals(オブジェクト)=いくつかの問題を引き起こすためにtrueを引き起こします。
マップインターフェイス
MAPはコレクションインターフェイスを継承しておらず、MAPはキーから値へのマッピングを提供することに注意してください。マップには同じキーを含めることはできません。各キーは1つの値のみをマッピングできます。マップインターフェイスは、コレクションの3種類のビューを提供します。
ハッシュテーブルクラス
ハッシュテーブルはマップインターフェイスを継承し、キー価値マッピングを備えたハッシュテーブルを実装します。非ヌルオブジェクトは、キーまたは値として使用できます。
Put(key、value)を使用して、データ(キー)を使用してデータを取得します。
ハッシュテーブルは、初期容量と負荷因子パラメーターを通じてパフォーマンスを調整します。通常、デフォルトの負荷係数0.75は、時間とスペースのバランスをより適切に実現できます。負荷係数を増やすとスペースを節約できますが、対応する検索時間は増加し、GetやPutなどの操作に影響します。
ハッシュテーブルを使用する簡単な例は次のとおりです。1、2、および3をハッシュテーブルに入れ、それらのキーはそれぞれ「1」、「2」、「3」です。
ハッシュテーブル番号= new Hashtable();
numbers.put( "one"、new Integer(1));
numbers.put( "2"、new Integer(2));
numbers.put( "3"、new Integer(3));
2などの番号を取得するには、対応するキーを使用します。
integer n =(integer)numbers.get( "2");
System.out.println( "2 =" + n);
キーとしてのオブジェクトは、ハッシュ関数を計算することにより対応する値の位置を決定するため、キーとしてのオブジェクトはハッシュコードを実装し、メソッドに等しくなります。ハッシュコードとルートクラスをキーとして使用する場合は、2つのオブジェクトが同じである場合、obj1.equals( )=それらのハッシュコードは同じでなければなりませんが、2つのオブジェクトが異なる場合、2つの異なるオブジェクトのハッシュコードが同じである場合、この現象は競合と呼ばれますしたがって、ハッシュテーブルを操作するには、ハッシュテーブルの動作を高速化するために、ハッシュコード()メソッドを定義してみてください。
同じオブジェクトに異なるハッシュコードがある場合、ハッシュテーブルの操作には予期しない結果があります(予想されるメソッドはnullを回避する必要があります。同じ時間を書くだけではありません。
ハッシュテーブルは同期されます。
ハッシュマップクラス
ハッシュマップはハッシュテーブルに似ていますが、違いは、ハッシュマップが非同期であり、null、つまりヌル値とヌルキーを可能にすることです。 、しかし、ハッシュマップがコレクション(値()メソッドがコレクションを返すことができる)と見なされる場合、その反復サブオペレーション時間オーバーヘッドはハッシュマップの容量に比例します。したがって、反復操作のパフォーマンスが非常に重要である場合、ハッシュマップの初期化容量を高すぎるように設定しないか、負荷係数が低すぎないようにしないでください。
WeakHashmapクラス
Weakhashmapは、キーを外部から参照しなくなった場合、キーをGCによってリサイクルできるようにする改善されたハッシュマップです。
要約します
スタック、キュー、その他の操作が関係している場合は、迅速に挿入して削除する必要があります。
プログラムが1つのスレッドにある場合、1つのスレッドのみである場合、非同期クラスを考慮して、複数のスレッドが同時にクラスを操作する場合は、同期クラスを使用する必要があります。
ハッシュテーブルの操作に特に注意してください。
この方法では、ArrayListの代わりにリストを返すなど、実際のタイプの代わりにインターフェイスを返すようにしてください。これは抽象的なプログラミング用です。
同期
ベクトルは同期です。このクラスのいくつかの方法では、ベクトル内のオブジェクトがスレッドセーフであることを保証します。 ArrayListは非同期であるため、ArrayListのオブジェクトはスレッドセーフではありません。同期要件は実行効率に影響を与えるため、スレッドセーフコレクションを必要としない場合、アレイリストを使用することは良い選択です。
データの成長
内部実装メカニズムから、アレイリストとベクトルは両方ともアレイ(配列)を使用してコレクション内のオブジェクトを制御します。これらの2つのタイプに要素を追加すると、要素の数が内部配列の長さを超える場合、デフォルトでは、Vectorは元の配列の長さを2回拡張しますそのため、オリジナルの50%なので、このコレクションを最後に入手したときは、実際に必要なよりも多くのスペースを占有します。したがって、コレクションに多くのデータを保存したい場合は、コレクションの初期化サイズを設定することで不要なリソースオーバーヘッドを避けることができるため、ベクターを使用することにはいくつかの利点があります。
使用モード
ArrayListとVectorでは、指定された場所から(インデックスを介して)データを見つけたり、セットの最後に要素を追加したり削除したりするのに同じ時間がかかります。ただし、セット内の他の場所に要素が追加または削除された場合、費やした時間は線形に成長します:O(NI)。Nはセット内の要素の数を表し、要素が要素を増加または除去するインデックス位置を表します。なぜこれが起こっているのですか?上記の操作を実行する場合、セット内のIthおよびIth要素の後のすべての要素が変位操作を実行する必要があると考えられています。これはすべてどういう意味ですか?
これは、特定の位置の要素を探したり、コレクションの最後に要素を追加して削除したりするだけで、VectorまたはArrayListを使用するだけで問題なくなります。別の操作の場合は、別のコレクション操作クラスを選択する方が良いでしょう。たとえば、リンクリストコレクションクラスがコレクションの任意の位置に要素を追加または削除するのにかかる時間は同じですが、要素のインデックス作成で遅い使用を使用します。アレイリストの使用も簡単です。 LinkListは、挿入された要素ごとにオブジェクトを作成し、理解する必要があるすべてのオブジェクトも追加のオーバーヘッドをもたらします。
最後に、Practical Javaの本では、Peter Haggarは、VectorまたはArrayListの代わりに単純な配列(配列)を使用することを提案しています。これは、実行効率が高いプログラムに特に当てはまります。アレイ(配列)を使用すると、同期、追加のメソッド呼び出し、およびスペース操作の不必要な再割り当てが回避されるためです。