Java Collection Framework には、データ構造を操作するためにそれらを実装する非常に便利なインターフェイスとクラスが含まれています。これは、JDK フレームワークの中で最も重要なものの 1 つであると言えます。List インターフェイスは非常に人気があります。なぜなら、プログラミングにおいてあらゆる種類のリストが不可欠だからです。この記事では、このインターフェイス、Java List メソッドおよび実装について説明します。
Java リスト インターフェイス
リストについて最も重要なことは、リストが順序付けられたコレクションであるということです。シーケンスと呼ぶこともできます。Java では、リストは同種です。つまり、リストの要素は同じデータ型です。Java List インターフェイスは Collection を継承し、そのすべての操作を継承します。これらに加えて、List では次の操作も可能です。- 位置アクセス。各要素にはインデックスがあり、その位置に基づいて操作できます。リストにあります。つまり、要素を追加、除外、および変更できます。
- 検索。内容によってリスト内の要素を検索し、そのインデックスを返すことができます。
- 反復。List の逐次的な性質により、反復メソッド (listIterator) の使用が可能になります。
- レンジビュー。sublist メソッドは、リストに対して任意の範囲操作を実行します。
Java リスト メソッド
上記の操作は、Java List インターフェイスのメソッドで公開されます。以下にその一部を示します。方法 | 説明 |
---|---|
add(E要素) | このメソッドは、このリストの末尾にelement要素を追加します。 |
add(int インデックス, 要素) | このメソッドは、リスト内の特定のインデックスに要素を追加します。必要なパラメータが渡されると、リストの最後に要素が追加されます。 |
addAll(int インデックス, Collection コレクション) | 指定されたコレクション内のすべての要素をリストに追加します。単一のパラメーターが渡されると、指定されたコレクションのすべての要素がリストの最後に追加されます。 |
サイズ() | リストのサイズ (リスト内の要素の量) を返します。 |
get(int インデックス) | 指定されたインデックスにある要素を返します。 |
set(int インデックス, 要素) | 指定されたインデックスの要素を新しい要素に置き換え、新しい要素に置き換えられた要素を返します。 |
削除(int インデックス) | 指定されたインデックスから要素を削除します。 |
削除(要素) | リスト内の指定された要素の最初の出現を削除します。 |
クリア() | リストからすべての要素を削除します。 |
IndexOf(要素) | 指定された要素の最初の出現を返します。要素がリストに存在しない場合は、-1を返します。 |
lastIndexOf(要素) | 指定された要素の最後の出現を返します。要素がリストに存在しない場合は、-1を返します。 |
等しい(要素) | 指定された要素とリストの要素が等しいかどうかを比較します。 |
ハッシュコード() | 指定されたリストのハッシュコード値を返します。 |
isEmpty() | リストが空かどうかを確認します。リストが空の場合は true を返します。 |
含む(要素) | リストに要素が含まれているかどうかを確認します。リストに要素が含まれている場合は true を返します。 |
containsAll(コレクションコレクション) | リストに要素のすべてのコレクションが含まれているかどうかを確認します。 |
ソート(コンパレータ比較) | 指定されたコンパレータに基づいてリストの要素を並べ替えます。 |
subList(int fromIndex, int toIndex) | このリストの、指定された fromIndex (両端を含む) と toIndex (両端を除く) の間の部分のビューを返します。 |
リストの実装
List はインターフェイスであるため、プログラムはその具体的な実装を作成する必要があります。Java Collections API では、次の List 実装から選択できます。- java.util.ArrayList
- java.util.LinkedList
- java.util.Vector
- java.util.スタック
リストインターフェイス宣言
次のいずれかの方法で Java プログラムでリストを宣言できます。List<String> myList = new ArrayList();
List myList1 = new ArrayList();
List myList3 = new ArrayList<String>();
ArrayList arrayList = new ArrayList();
インターフェイスを介して新しいリストを宣言するのが最善です。同様に、List の他の実装を宣言できます。最短の方法:
Vector myVector = new Vector;
LinkedList linkedList = new LinkedList();
Stack stack = new Stack();
このような宣言を使用すると、リストの要素のデータ型はリストの初期化中、つまりリストに要素が追加されるときに決定されます。
List myList = new ArrayList<String>();
Vector myVector = new Vector();
LinkedList linkedList = new LinkedList();
Stack stack = new Stack();
stack.add("Paul");
linkedList.add(1);
myVector.add(1.2f);
myList.add('a');
現在、スタックには文字列のみを追加でき、整数はlinkedListに、浮動小数点はmyVectorに追加できます。myListは文字のリストです。
ArrayList の仕組み
通常の配列にすでに慣れている場合は、ArrayList にもある程度慣れているはずです。実際、ArrayList は動的配列であり、その内部には通常の配列があります。この配列はデータ ストアとして機能します。ArrayList には、参照型、サードパーティのクラス、文字列、出力ストリーム、その他のコレクションを含むオブジェクトのみが格納されます。ラッパー クラスは、ArrayList にプリミティブ データ型を格納するために使用されます。リストを作成するときに、そのサイズをすぐに設定できますが、ほとんどの場合は設定しません。デフォルトでは、ArrayList サイズ = 10 です。ArrayList に新しい要素を追加するとどうなるでしょうか? まず、内部配列に十分なスペースがあるかどうか、およびもう 1 つの要素が適合するかどうかを確認するためのチェックが開始されます。スペースがある場合、新しい要素はリストの最後、つまり最後の要素の次のセルに追加されます。そのインデックスは arraylist.size() になります。作成したばかりのリストが空の場合、これは arrayList.size() = 0 を意味します。したがって、インデックス 0 のセルに新しい要素が追加されます。十分なスペースがないことが判明した場合は、新しい要素が追加されます。配列は、(OldArray のサイズ * 1.5) + 1 のサイズで ArrayList 内に作成されます。同じ原理により、リストの途中で挿入が行われますが、同時に、挿入された要素に続くすべての要素が作成されます。右に移動しました。したがって、配列に 5 つの要素があり、セル番号 2 (つまり 3 番目) に要素を挿入する必要がある場合、0 と 1 の配列要素はそのまま残り、新しい要素がセル 2 に表示されます。その前のセルは 3 番目のセルに移動し、以下同様に続きます。新しい要素はインデックス 0 のセルに追加されます。十分なスペースがないことが判明した場合は、ArrayList 内にサイズ (OldArray のサイズ * 1.5) + 1 の新しい配列が作成されます。原則として、挿入はリストの中央に行われますが、同時に、挿入された要素に続くすべての要素は右にシフトされます。したがって、配列に 5 つの要素があり、セル番号 2 (つまり 3 番目) に要素を挿入する必要がある場合、0 と 1 の配列要素はそのまま残り、新しい要素がセル 2 に表示されます。その前のセルは 3 番目のセルに移動し、以下同様に続きます。新しい要素はインデックス 0 のセルに追加されます。十分なスペースがないことが判明した場合は、ArrayList 内にサイズ (OldArray のサイズ * 1.5) + 1 の新しい配列が作成されます。原則として、挿入はリストの中央に行われますが、同時に、挿入された要素に続くすべての要素は右にシフトされます。したがって、配列に 5 つの要素があり、セル番号 2 (つまり 3 番目) に要素を挿入する必要がある場合、0 と 1 の配列要素はそのまま残り、新しい要素がセル 2 に表示されます。その前のセルは 3 番目のセルに移動し、以下同様に続きます。挿入はリストの中央に行われますが、同時に、挿入された要素に続くすべての要素が右にシフトされます。したがって、配列に 5 つの要素があり、セル番号 2 (つまり 3 番目) に要素を挿入する必要がある場合、0 と 1 の配列要素はそのまま残り、新しい要素がセル 2 に表示されます。その前のセルは 3 番目のセルに移動し、以下同様に続きます。挿入はリストの中央に行われますが、同時に、挿入された要素に続くすべての要素が右にシフトされます。したがって、配列に 5 つの要素があり、セル番号 2 (つまり 3 番目) に要素を挿入する必要がある場合、0 と 1 の配列要素はそのまま残り、新しい要素がセル 2 に表示されます。その前のセルは 3 番目のセルに移動し、以下同様に続きます。Java リストの例 (配列リストの実現)
import java.util.*;
public class ArrayListExample2 {
public static void main(String[] args) {
List<String> myFriendsList = new ArrayList();
//we created list of some objects
System.out.println( "the size of myList before init = " + myFriendsList.size());
myFriendsList.add("Alex");
myFriendsList.add("Tanya");
myFriendsList.add("Veloxy");
myFriendsList.add("Alex");
myFriendsList.add("Andrew");
System.out.println(myFriendsList);
System.out.println( "the size of myList after init = " + myFriendsList.size());
myFriendsList.add("Ihor");
System.out.println(myFriendsList);
System.out.println("the size of my list = " + myFriendsList.size());
//here the program will print out the first appearance of "Alex" element
System.out.println(myFriendsList.indexOf("Alex"));
//program will print out the first appearance of "Alex" element starting from the element 0
myFriendsList.remove(3);
System.out.println(myFriendsList.get(3));
System.out.println("after removing one of Alex's there is only one Alex: " + myFriendsList);
System.out.println(myFriendsList.get(1));
myFriendsList.clear();
System.out.println("the size of the vector after clear method = " + myFriendsList.size());
}
}
このプログラムの出力は次のとおりです。
初期化前の myList のサイズ = 0 [Alex、Tanya、Veloxy、Alex、Andrew] 初期化後の myList のサイズ = 5 [Alex、Tanya、Veloxy、Alex、Andrew、Ihor] リストのサイズ = 6 0 Andrew 初期化後のAlex の 1 つを削除すると、Alex は 1 つだけになります: [Alex, Tanya, Veloxy, Andrew, Ihor] Tanya クリア後のベクトルのサイズ = 0 プロセスは終了コード 0 で終了しました
LinkedList の仕組み
LinkedList では、要素は実際には同じチェーン内のリンクです。各要素には、保存されるデータに加えて、前後の要素へのリンクがあります。これらのリンクを使用すると、ある要素から別の要素に移動できます。イテレータは両方向のトラバースをサポートします。リストの先頭、中間、および末尾で取得、削除、および挿入するためのメソッドを実装します。null を含む任意の要素を追加できます。LinkedList は、List だけでなく Deque という 2 つのインターフェイスを実装します。これにより、任意の要素 (null も含む) から双方向キューを作成できるようになります。リンクリストに配置された各オブジェクトがノード(ノード)です。各ノードには要素、つまり前後のノードへのリンクが含まれています。実際、リンク リストは一連のノードで構成されており、各ノードは、作成時に定義されたタイプのオブジェクトを格納するように設計されています。コード例
import java.util.*;
public class LinkedListTest {
public static void main(String args[]){
List myLinkedList= new LinkedList<Integer>();
myLinkedList.add(1);
myLinkedList.add(2);
myLinkedList.add(4);
System.out.println("three added elements: " + myLinkedList);
myLinkedList.add(5);
myLinkedList.remove(1);
System.out.println(myLinkedList);
myLinkedList.size(); //3
//add new element at the specified position:
myLinkedList.add(2,7);
System.out.println(myLinkedList);
}
}
出力は次のとおりです。
3 つの追加要素: [1, 2, 4] [1, 4, 5] [1, 4, 7, 5]
ベクトルコードの例
Vector も動的配列の実現であり、ArrayList に非常に似ていますが、同期されており、コレクション フレームワークに含まれていないレガシー メソッドがいくつかあります。このクラスの使用法の簡単な例を次に示します。import java.util.Vector;
public class VectorExample1 {
public static void main(String[] args) {
Vector vector = new Vector();
System.out.println("the size of the empty vector = " + vector.size());
vector.add("Alex");
vector.add("Tanya");
vector.add("Andrew");
System.out.println(vector);
vector.add("Alex");
vector.add("Ihor");
System.out.println(vector);
System.out.println("the size of the vector = " + vector.size());
System.out.println("the first element of the vector = " + vector.firstElement());
//here the program will print out the first appearance of "Johnny" element
System.out.println(vector.indexOf("Andrew"));
//program will print out the first appearance of "Johnny" element starting from the element 1
System.out.println(vector.indexOf("Alex", 1));
System.out.println(vector);
vector.clear();
System.out.println("the size of the vector after clear method = " + vector.size());
}
}
出力は次のとおりです。
空のベクトルのサイズ = 0 [Alex, Tanya, Andrew] [Alex, Tanya, Andrew, Alex, Ihor] ベクトルのサイズ = 5 ベクトルの最初の要素 = Alex 2 3 [Alex, Tanya, Andrew, Alex、Ihor] メソッドクリア後のベクトルのサイズ = 0 プロセスは終了コード 0 で終了しました
Javaスタッククラスコードの例
import java.util.Stack;
public class StackTest {
public static void main(String[] args) {
Stack stack = new Stack();
System.out.println(stack.isEmpty());
stack.add("Paul");
stack.add("Johnny");
stack.add("Alex");
System.out.println(stack.isEmpty());
stack.push("Andrew");
System.out.println(stack);
stack.pop();
System.out.println(stack);
}
}
Stack にはadd()メソッドとremove()メソッド だけでなく、push メソッドと Pop メソッドもあり、このようなデータ構造では古典的です。スタックは「先入れ後出し」のルールに従います。これは非常にアンチキューです。したがって、pop 操作はスタックに最後に配置された要素をポップします。この例の出力は次のとおりです。
true false [ポール、ジョニー、アレックス、アンドリュー] [ポール、ジョニー、アレックス]
GO TO FULL VERSION