Java のコレクションは主に 2 つの部分に分かれており、1 つは java.util パッケージにあり、もう 1 つは java.util.concurrent にあります。後者は前者に基づいており、同期関数を実装するいくつかのコレクションを定義します。
この記事では主に、java.util のさまざまなコレクション オブジェクトに焦点を当てます。 Java のコレクション オブジェクトは、List、Set、Map の 3 つのカテゴリに大別できます。対応する UML 図は次のとおりです (java.util 下のほとんどのコレクション オブジェクトを含みます)。
コレクション概要
Java コレクションの List と Set はどちらも Collection から取得されており、コレクションで通常必要となる操作が含まれています。
要素の追加: add/addAll
コレクションをクリアします: クリア
要素の削除:remove/removeAll
コレクションに要素が含まれているかどうかを判断します: contains/containsAll
コレクションが空かどうかを判断します: isEmpty
コレクション内の要素の数を計算します: サイズ
コレクションを配列に変換します: toArray
イテレータの取得: イテレータ
簡単な例を見てみましょう。次のコードは、要素がランダムに生成された整数であるコレクションを返します。
返却コレクション。
}
1)イテレータを使用してコレクションを走査します。上で Collection インターフェイスを説明したときに述べたように、すべてのコレクションには、コレクションを走査するために使用できるイテレータがあります。
Java のリストは配列の効果的な拡張であり、ジェネリックスが使用されない場合は、任意の型の要素を保持できる構造です。ジェネリックスが使用されている場合は、ジェネリックスで指定された型の要素のみを保持できます。配列と比較して、List は動的に容量を拡張できます。
リスト内の要素は繰り返すことができ、内部の要素は「順序付け」されています。ここでの「順序付け」は並べ替えを意味するのではなく、コレクション内の要素の位置を指定できることを意味します。
List で一般的に使用されるコレクション オブジェクトには、ArrayList、Vector、LinkedList が含まれます。前者の 2 つは配列に基づいて格納され、後者はリンク リストに基づいて格納されます。このうち、Vector はスレッドセーフですが、他の 2 つはスレッドセーフではありません。
ジェネリックが使用されている場合でも、リストには null を含めることができます。
ArrayList は、最も一般的に使用されるコレクション オブジェクトである可能性があります。上記のコード例では、Collection オブジェクトのインスタンス化にも使用されているため、ここでは詳しく説明しません。
ベクター
Vector の例は次のとおりです。まず、Vector を生成して出力する方法を説明します。
[9、29、32、54、12]
ベクトルのサイズは3です
[29、32、54]
LinkedList はリンク リストを使用してデータを保存します。そのサンプル コードは次のとおりです。
出力は次のとおりです。
ヌル
ヌル
ヌル
リンクリストのサイズは8です
[100、84、19、57、68、26、27、47]
Set は List に似ており、どちらも単一の要素を格納するために使用され、個々の要素の数は不確かです。ただし、Set に重複した要素を含めることはできません。2 つの同一の要素が Set に挿入された場合、後者の要素は挿入されません。
Set は unsorted Set とsorted Set の 2 つに大別できます。Unsorted Set には HashSet と LinkedHashSet が含まれ、sorted Set は主に TreeSet を指します。このうち、HashSet と LinkedHashSet には null を含めることができます。
ハッシュセット
HashSet は、スレッドセーフではないハッシュ テーブルによってサポートされるコレクションです。
次の例を見てみましょう。これは、Vector を使用した最初の例と基本的に同じです。
for (int i = 0; i < 3; i++)
{
set.add(新しい整数(100));
}
set.add(null);
System.out.println("セットのサイズは " + set.size());
System.out.println(set);
}
クラスMyInteger
{
プライベート整数値。
public MyInteger(整数値)
{
this.value = 値;
}
パブリック String toString()
{
戻り値 String.valueOf(value);
}
public int hashCode()
{
1 を返します。
}
public booleanquals(Object obj)
{
true を返します。
}
}
対応するテスト方法は次のとおりです。
for (int i = 0; i < 3; i++)
{
set.add(new MyInteger(100));
}
System.out.println("セットのサイズは " + set.size());
System.out.println(set);
}
TreeSet は並べ替えをサポートする Set であり、その親インターフェイスは SortedSet です。
まず、TreeSet の基本的な操作を見てみましょう。
ランダム r = 新しいランダム();
for (int i = 0; i < 5; i++)
{
set.add(new Integer(r.nextInt(100)));
}
System.out.println(set);
System.out.println(set.first());
System.out.println(set.last());
System.out.println(set.descendingSet());
System.out.println(set.headSet(new Integer(50)));
System.out.println(set.tailSet(new Integer(50)));
System.out.println(set.subSet(30, 60));
System.out.println(set.floor(50));
System.out.println(set.ceiling(50));
}
[53、49、48、42、8]
[8、42、48、49]
[53]
[42、48、49、53]
次に、最初に Integer を再定義します。
public MyInteger2(int 値)
{
this.value = 値;
}
public int CompareTo(オブジェクト arg0)
{
MyInteger2 temp = (MyInteger2)arg0;
if (temp == null) は -1 を返します。
if (temp.value > this.value)
{
1 を返します。
}
else if (temp.value < this.value)
{
-1 を返します。
}
0を返します。
}
public booleanquals(Object obj)
{
戻り値比較(obj) == 0;
}
パブリック String toString()
{
戻り値 String.valueOf(value);
}
}
Map には「キーと値のペア」が格納されます。Set と同様に、Java には 2 つのタイプの Map があり、ソートされていないものには HashMap、Hashtable、LinkedHashMap が含まれ、ソート済みには TreeMap が含まれます。
未分類の地図
HashMap と Hashtable は両方ともハッシュ テーブルの形式で保存されます。HashMap はスレッド セーフではありませんが、HashMap は Hashtable の「簡易」バージョンとみなすことができます。
HashMap は、Key または Value に関係なく null を格納できます。ハッシュテーブルには null を格納できません。
HashMap または Hashtable に関係なく、そのコンストラクターを観察すると、initialCapacity とloadFactor の 2 つのパラメーターを持つことができます。デフォルトでは、initialCapacity は 16、loadFactor は 0.75 に等しいことがわかります。これは、ハッシュ テーブルに格納できる要素の数に関連しており、要素の数がinitialCapacity*loadFactorを超えると、ハッシュ テーブルを拡張するために再ハッシュ メソッドがトリガーされます。挿入する要素が多すぎる場合は、これら 2 つのパラメータを適切に調整する必要があります。
まずは HashMap の例を見てみましょう。
map.put(new Integer(1), "a");
map.put(new Integer(2), "b");
map.put(new Integer(3), "c");
System.out.println(マップ);
System.out.println(map.entrySet());
System.out.println(map.keySet());
System.out.println(map.values());
}
マップ.put(null, null);
マップ.put(null, null);
map.put(new Integer(4), null);
map.put(new Integer(5), null);
System.out.println(マップ);
System.out.println(map.entrySet());
System.out.println(map.keySet());
System.out.println(map.values());
}
table.put(new Integer(1), "a");
table.put(new Integer(2), "b");
table.put(new Integer(3), "c");
System.out.println(テーブル);
System.out.println(table.entrySet());
System.out.println(table.keySet());
System.out.println(table.values());
}
プライベート静的 void hashTableTest2()
{
Map<Integer,String> テーブル = new Hashtable<Integer, String>();
table.put(null, null);
table.put(null, null);
table.put(new Integer(4), null);
table.put(new Integer(5), null);
System.out.println(テーブル);
System.out.println(table.entrySet());
System.out.println(table.keySet());
System.out.println(table.values());
}
ソート マップは主に TreeMap を指します。TreeMap は、要素の追加、削除、検索時に O(log(n)) の時間計算量を持ちます。スレッドセーフではありません。
その特性は TreeSet と非常に似ているため、ここでは詳しく説明しません。