1。ジャワのコレクション
Javaのコレクションクラスは、Javaプログラミングで最も頻繁に使用され、最も便利なクラスです。コンテナクラスとして、コレクションクラスはあらゆるタイプのデータを保存できます。もちろん、指定されたタイプをジェネリックと組み合わせて保存することもできます(ただし、ジェネリックはコンピレーション期間中にのみ有効であり、実行時に消去されます)。コレクションクラスに保存されているのは、オブジェクト自体への参照ではなく、オブジェクトへの参照にすぎません。コレクションクラスの容量は、操作中に動的に拡張できます。また、コレクションの組合を見つけるなど、多くの便利な方法を提供します。
2。コレクションクラス構造
Javaのコレクションには、リンクリスト、キュー、ハッシュテーブルなどの複数のデータ構造が含まれます。クラスの継承構造に関して、2つのカテゴリに分割できます。 1つはコレクションインターフェイスから継承されます。このタイプのコレクションには、リスト、セット、キューなどのコレクションクラスが含まれます。他のクラスは、主にハッシュテーブルに関連するコレクションクラスを含むマップインターフェイスから継承されます。これら2つのカテゴリの継承構造図を見てみましょう。
1。リスト、設定、キュー
図の緑色の点線は実装を表し、緑色の実線はインターフェイス間の継承を表し、青い固形線はクラス間の継承を表します。
(1)リスト:ArrayListやLinkedListなど、より多くのリストを使用します。これら2つの違いも非常に明白であり、名前から見ることができます。基礎となるアレイリストはアレイを介して実装されるため、ランダムアクセス速度は比較的高速ですが、頻繁な追加と削除が必要な場合の効率は比較的低いです。 LinkedListの場合、基礎となるレイヤーはリンクされたリストを介して実装されるため、追加と削除操作の完了が容易になりますが、ランダムアクセスの効率は比較的低いです。
まず、両方の挿入効率を見てみましょう。
package com.paddx.test.collection;import java.util.ArrayList;import java.util.LinkedList;public class ListTest {public static void main(String[] args) {for(int i=;i<;i++){}long start = System.currentTimeMillis();LinkedList<Integer> linkedList = new linkedlist <integer>(); for(int i =; i <; i ++){linkedlist.add(、i);} long end = system.currenttimemillis(); system.out.println(end -start); arraylist <integer> arraylist = new arraylist <integer> for( i =; i <; i ++){arraylist.add(、i);} system.out.println(system.currenttimemillis() - end);}}}ローカル実行の結果は次のとおりです。
23
1227
この場合、LinkedListの挿入効率はArrayListの挿入効率よりもはるかに高いことがわかります。もちろん、これは比較的極端な状況です。 2つの間のランダムアクセスの効率を比較しましょう。
パッケージcom.paddx.test.collection; import java.util.arraylist; import java.util.linkedlist; import java.util.random; public class listtest {public static void main(string [] args){random random = new random(); linkedlist <integer>(); for(int i =; i <; i ++){linkedlist.add(i);} arraylist <integer> arraylist = new arraylist <integer>(); for(int i =; i <; i ++){arraylist.add(i);} long start = system.currenttimemillis(); for(int i =; i <; i ++){int j = random.nextint(i+); int k = linkedlist.get(j);} long end = system.currenttimemillis(); system.out.println(end -start); arraylist.get(j);} system.out.println(system.currenttimemillis() - end);}}}これが私の実行の結果です:
5277
6
ArrayListのランダムアクセス効率がLinkedListよりも数桁高いことは明らかです。これらの2つのコードを通して、LinkedListとArrayListと適応シナリオの違いをより明確に知ることができるはずです。 Vectorについては、ArrayListのスレッドセーフバージョンであり、スタックはスタックデータ構造に対応しています。これら2つはあまり頻繁ではないので、ここでは例を挙げません。
(2)キュー:通常、LinkedListを使用して直接実行できます。また、LinkedListがDequeから継承する上記のクラス図から見ることができるため、LinkedListには両端のキューの機能があります。 PriorityQueueは、各要素に優先度を提供することで特徴付けられ、優先度の高い要素にはキューから優先度が与えられます。
(3)セット:セットとリストの主な違いは、セットが要素を繰り返すことを許可しないことですが、リストを繰り返すことができるということです。要素の繰り返しを判断するには、オブジェクトのハッシュメソッドと等しい方法に基づいて決定する必要があります。これが、通常、ハッシュコードメソッドをオーバーライドし、コレクションの要素クラスのメソッドに等しい理由でもあります。セットとリストの違い、およびハッシュコードメソッドの役割と等しい方法を確認してみましょう。
パッケージcom.paddx.test.collection; import java.util.arraylist; import java.util.hashset; import java.util.set; public static void main(string [] args){人P1 =新しい人( "lxp"、10); person p2 = new person( "lxp" "人( "lxp"、20); arraylist <serpures> list = new arraylist <serson>(); list.add(p1); system.out.println( "-------------"); list.add(p2); out.out.println( "------------------"); list.add(list.add(p3); system.out.println( " list.size()); system.out.println( "---------------"); set <serpures> set = new hashset <person>(); set.add(p1); system.out.println( "-----------"); set.add(p2); system.out.out.println( "---------------"); set.add(pp3); size = "+set.size();} static class person {private string name; private int age; public person(this.name name){this.name = name; this.age = age;}@overridepublic boolean equals(object o){system.out.println(" call name(); call name; if()if(of = = = = = = = = = = = = = = = nul nam getClass()!= o.getClass())return false; person person =(person)o; return name.equals(person.name);}@overridepublic int hashcode(){system.out.println( "call ="+age); return age;}}}}}}上記のコードの実行結果は次のとおりです。
------------
------------
リストサイズ= 3
----分割線----
hashcode()、age = 10を呼び出します
------------
hashcode()、age = 10を呼び出します
equals(); name = lxpを呼び出します
------------
HashCode()、Age = 20を呼び出します
SET SIZE = 2
結果から、要素がリストに追加され、繰り返される場合、追加の操作は実行されません。セットに参加する前に、最初にハッシュコードメソッドを実行する必要があります。セットに返された値が既に存在する場合、Equalsメソッドを実行し続ける必要があります。 equalsメソッドによって返される結果もtrueである場合、要素が既に存在し、新しい要素が古い要素によって上書きされることを証明します。返されたハッシュコード値が異なる場合、セットを直接追加します。ここでは、コレクションの要素の場合、異なるハッシュコード値を持つ要素は不平等でなければなりませんが、不均等な要素の場合、ハッシュコード値は同じかもしれません。
ハッシュセットとLinkedHashsetの違いは、後者がセットに挿入された要素の順序が出力の順序と一致することを保証できることです。トレセットの違いは、その種類がコンパレータでソートされ、デフォルトでは、文字の自然な順序で昇順で配置されることです。
(4)反復可能:この図から、コレクションクラスが繰り返し可能であることがわかります。このインターフェイスの機能は、要素トラバーサルを提供することです。つまり、すべてのコレクションクラス(マップ関連クラスを除く)が要素トラバーサル関数を提供します。 Iterableにはイテレーターのイテレーターが含まれており、そのソースコードは次のとおりです。 Iteratorモードに精通している場合は、簡単に理解できるはずです。
public interface iterator <e> {boolean hasnext(); e next(); void remove();}2。マップ:
MAPタイプコレクションの最大の利点は、その検索効率が比較的高く、O(1)の時間の複雑さが理想的に達成できることです。最も一般的に使用されるマップはハッシュマップです。 LinkedHashmapとHashmapの違いは、前者がセットに挿入された要素の順序が出力順と一致することを保証できることです。これら2つとTreemapの違いは、Treemapが重要な値に従ってソートされることです。もちろん、その根本的な実装にも本質的な違いがあります。たとえば、Hashmapの基礎となる層はハッシュテーブルですが、Treemapの基礎となる層は木です。 TreemapとLinkedhashmapの違いを見てみましょう。
パッケージcom.paddx.test.collection; import java.util.iterator; import java.util.linkedhashmap; import java.util.map; import java.util.treemap; public static void main(string [] args){map <string> treemap < linkedMap = new LinkedHashMap <String、String>(); Treemap.put( "b"、null); treemap.put( "c"、null); treemap.put( "a"、null); for(iterator <string> iter = treemap.keyset()。iterator(); iter.hasnext();){system.out.println( "treemap ="+iter.next();} system.out.prin tln( "----------分割线----------"); linkedMap.put( "b"、null); linkedMap.put( "c"、null); linkedMap.put( "a"、null); for (iterator <string> iter = linkedmap.keyset()。iterator(); iter.hasnext();){system.out.println( "linkedhashmap ="+iter.next();}}}}}}上記のコードを実行すると、実行結果は次のとおりです。
treemap = a
treemap = b
treemap = c
------------------------------
LinkedHashmap = b
LinkedHashmap = c
linkedhashmap = a
実行中の結果から、TreemapとLinkedhashmapの違いがはっきりと見られることは明らかです。前者は文字列ソートで出力され、後者は挿入順序によって出力されます。慎重な読者は、ハッシュマップとTreemapの違いが、前述のハッシュセットとツリーセットの違いと一致していることがわかります。将来ソースコード分析を実施するとき、ハッシュセットとツリーセットがそれぞれHashmapとTreemapによってそれぞれ本質的に実装されていることがわかります。したがって、それらの違いは自然に同じです。ハッシュテーブルが現在使用されていません。ハッシュマップとの主な違いは、ハッシュテーブルがスレッドセーフであることですが、その効率が低いため、ハッシュマップが通常使用されます。マルチスレッド環境では、通常、CurrentHashmapが代わりに使用されます。
3。概要
この記事では、Java Collection Frameworkとその相続関係全体を紹介します。上記のクラスに加えて、コレクションはコレクションと配列の2つのツールクラスも提供します。さらに、コレクションのソートは、比較可能なコンパレータと密接に関連しています。後続の記事では、JDKの上記のクラス実装ソースコードを詳細に分析します。