面接でよく聞く集合内容

5874 ワード

文章の出所https://yq.aliyun.com/articles/78788?spm=5176.8.25205.0576.5907.3 znXNM 5という大きな会社のJAVA面接の問題を見ましたが、JAVA集合類の使用に対して重視しているような気がします。自分はこの面では本当に少ないです。暇を見つけても勉強しましょう。
java.utilパケットには一連の重要な集合クラスが含まれていますが、集合クラスについては主にその内部構造と、集合を巡回する反復モードを把握する必要があります。
インターフェース:Collection
Collectionは最も基本的な集合インターフェースであり、一つのCollectionはObjectのセット、すなわちCollectionの要素を表す。いくつかのCollectionは同じ要素を許容し、他のいくつかはだめです。いくつかは並べ替えができますが、他のものはだめです。Java SDKは、直接Collectionから継承されるクラスを提供しない。Java SDKが提供するクラスは、ListおよびSetのようなCollectionから継承される「サブインターフェース」である。
Collectionインターフェースを実現するすべてのクラスは、2つの標準的なコンストラクタを提供しなければならない。パラメータなしのコンストラクタは、空のCollectionを作成するために使用され、Collectionパラメータのコンストラクターは、新しいCollectionを作成するために使用され、この新しいCollectionは、着信したCollectionと同じ要素を持つ。後のコンストラクタは、ユーザーがCollectionをコピーすることを可能にする。
主なインターフェース方法:book add(Ojbect c)はbollanを返しますが、添加成功を表しているのではなく、この戻り値はadd()が実行された後、集合の内容が変更されましたか?似たようなaddAll、remove、removeAll、remanAllも同じです。Javaを勉強したいなら、この群に来てもいいです。まず第二に、第四に、最後は九零です。中には大量の学習資料がダウンロードできます。
Iteratorモードでエルゴード集合を実現します。
Collectionには、集合のすべての要素を巡回するための重要な方法があります。Iteratorモードは、クライアントにセットの内部構造を露出することを避けるために、異なるセットからアクセスロジックを抽象化することができる。典型的な使い方は以下の通りです。
Iterator it = collection.iterator(); //       
while(it.hasNext()) {
 Object obj = it.next(); //       
}
集合した「ポインタ」をメンテナンスする必要はなく、すべての内部状態はIteratorによって維持されますが、このIteratorは集合類によって工場法によって生成されます。
各集合の種類ごとに戻ってくるIteratorの具体的なタイプは違っても、Iteratorインターフェースを実現しています。だから、どのタイプのIteratorなのかに関心を持たなくてもいいです。
プロセスを経てスムーズに完了するためには、集合の内容(Iteratorのremove()方法を変更しないように遍歴する必要があります。したがって、信頼できる原則は、一つのスレッドの中でのみこのセットを使用するか、またはマルチスレッドの中でコードを巡回して同期することです。
Collectionインターフェースから派生された2つのインターフェースはListとSetである。
Listインターフェース
Listは秩序化されたCollectionであり、このインターフェースを使用して各要素の挿入位置を正確に制御することができる。ユーザは、インデックス(List中の要素の位置、配列の下付きと似ている)を使用してList中の要素にアクセスすることができ、これはJavaの配列と類似している。以下に述べるSetとは違って、Listは同じ要素を持つことができる。
Collectionインターフェースに必要なiterator()方法の他に、ListIterator()方法を提供し、ListIteratorインターフェースを返します。標準的なIteratorインターフェースに比べて、ListIteratorはいくつかのadd()が多くなりました。このような方法で、追加、削除、設定要素ができます。
Listインターフェースを実現するのによく使われるのは、Linked List、ArayList、Vector、Stckです。
Linked Listクラス
Listインターフェースを実現し、null要素を許可する。さらに、Linked Listは、Linked Listのヘッダまたは末尾にinsert方法を追加のget、removeを提供する。これらの動作は、LinkdListをスタック、キュー、または双方向キューとして使用することができる。
Linked Listは同期方法がないように注意してください。複数のスレッドが同時にListにアクセスする場合は、自分でアクセス同期を実現しなければならない。一つの解決方法は、Listを作成する際に同期したList:List list=Collection.synchronized List(new LinkdList);
ArayList類
ArayListは可変サイズの配列を実現した。nullを含むすべての要素を許可します。ArayListは同期していない。size,isEmpty,get,set方法の運転時間は定数です。しかし、add法は、割り当てられた定数としてオーバーヘッドされ、n個の要素を追加するには、O(n)の時間が必要である。その他の方法の運転時間は線形です。
各ArayList例は、要素を格納するための配列のサイズである容量(Capacity)を有する。この容量は常に新しい要素を追加すると自動的に増加することができるが,成長アルゴリズムは定義されていない。大量の要素を挿入する必要がある場合、挿入前にensureCapacity方法を呼び出すことができ、挿入効率を向上させるためにArayListの容量を増加させる。
Linked Listと同様に、ArayListも非同期です。
Vectorクラス
Vectorはアラーリストによく似ていますが、Vectorは同期しています。Vectorによって作成されたIteratorは、ArayListによって作成されたIteratorと同じインターフェースですが、Vectorは同期していますので、Iteratorが作成されて使用されています。他のスレッドはVectorの状態(例えば、いくつかの要素を追加または削除しています。)を変更して、Iteratorの方法を呼び出すと、Contercuntindiction Moptcationが呼び出されます。この異常は必ず捕獲されます。
スタック類
StockはVectorから引き継ぎ、後進先のスタックを実現します。Stockは5つの追加的な方法を提供し、Vectorをスタックとして使用することができる。基本的なpushとpop方法、そしてpeek方法はスタックの一番上の要素を得て、empty方法はスタックが空かどうかをテストして、search方法はスタックの中の元素の位置を検出します。Stockが作成された直後は空スタックです。
Setインターフェース
Setは、重複する要素を含まないCollectionであり、つまり、任意の2つの要素e 1とe 2は、e 1.equals(e 2)=falseであり、Setは最大1つのnull要素を持つ。
Setの構造関数には制約条件があり,導入されたCollectionパラメータには重複要素が含まれないことが明らかである。
注意してください。可変オブジェクトを慎重に操作しなければなりません。一つのセットの中の可変要素が自身の状態を変えたら、Object.equals=trueがいくつかの問題を引き起こします。
Mapインターフェース
MapはCollectionインターフェースを継承しておらず、Mapはkeyからvalueへのマッピングを提供しています。一つのMapには同じkeyが含まれていません。各keyは一つのvalueだけ写像できます。Mapインターフェースは、3つのセットのビューを提供し、Mapのコンテンツは、セットのkeyとして、valueのセット、またはセットのkey-valueマッピングとして使用することができる。
Hashtable類
HashtableはMapインターフェースを継承し、key-valueマッピングのハッシュ・テーブルを実現する。任意の非空(non-null)のオブジェクトは、keyまたはvalueとして使用することができます。
データを追加してput(key,value)を使用して、データを取り出してget(key)を使用して、この2つの基本的な動作の時間オーバーヘッドは定数です。
Hashtableはinitial capacityとload factorの二つのパラメータで性能を調整します。デフォルトのロードファクトは通常0.75で時間と空間のバランスが良く実現されます。load factorを増大させることは、スペースを節約することができますが、それに応じて検索時間が増大し、これはgetやputのような操作に影響します。
Hashtableを使用する簡単な例は、1,2,3をHashtableに置くと、彼らのkeyはそれぞれ「one」、「two」、「three」である。numbers.put(「one」,new Integer(1));numbers.put(「two」、new Integer(2));numbers.put(“three”,new Integer(3));
一つの数を取り出します。例えば2、該当するkey:Integer n=(Integer)numbers.get("two")を使います。System.out.println("two="+n);
keyのオブジェクトとしては、そのハッシュ関数を計算することにより対応するvalueの位置を決定するので、任意のkeyのオブジェクトとしてhashCodeおよびequals方法を実装しなければならない。hashCodeとequals方法はルートObjectから継承されています。もしあなたがカスタムクラスをkeyとするなら、かなり注意してください。ハッシュ関数の定義によると、2つのオブジェクトが同じであれば、obj 1.equals(obj 2)=trueは、それらのhashCodeは同じでなければなりません。このような現象は競合と呼ばれ、衝突はハッシュ・テーブルを操作する時間的なオーバヘッドを増大させるので、できるだけ良いhashCodeを定義する方法で、ハッシュ・テーブルの動作を加速させることができる。
同じオブジェクトが異なるhashCodeがあると、ハッシュテーブルの操作に予想外の結果が現れる(期待されるget方法はnullに戻る)ので、このような問題を避けるには、equals方法とhashCode方法を同時にコピーして、その中の一つだけを書かないように心がける必要があります。
hashtableは同期です。
HashMap類
HashMapとHashtableは似ていますが、違いはhashMapが非同期であり、null、つまりnull valueとnull keyが許可されています。しかし、HashMapをCollectionとして扱う場合、そのローズマリー操作時間オーバヘッドとhashMapの容量が比例します。したがって、反復動作の性能が重要であれば、HashMapの初期化容量を過剰に設定したり、ロードfactorを低すぎたりしないでください。
[WeakhashMap]
クラス
WeakhashMapは改善されたHashMapであり、keyに対して「弱引用」を実行しています。もしkeyが外部から引用されなくなったら、keyはGCによって回収されます。
Javaを勉強したいなら、この群に来てもいいです。まず第二に、第四に、最後は九零です。中には大量の学習資料がダウンロードできます。
締め括りをつける
スタック、キュー等の操作に関しては、Listを用いて、迅速な挿入、削除が必要な場合は、LinkdListを使用すべきであり、迅速なランダムアクセスが必要であれば、ArayListを使用すべきである。
プログラムが単一スレッド環境にある場合、または1つのスレッドだけにアクセスして、非同期クラスを考慮して、効率が高い場合、複数のスレッドが同じクラスで動作してもよいなら、同期クラスを使用すべきです。
特にハッシュ・テーブルの動作に注意して、keyの対象としてequalsとhashCodeの方法を正確に複写します。
ArayListではなくListに戻るように、インターフェースをできるだけ返します。このように、今後、ArayListをLinked Listに換える必要があるなら、クライアントコードは変更されません。これは抽象的なプログラミングに対するものです。