Java Listインタフェース

JavaのListは、Java Collections Frameworkに属するインタフェースです。

java.util.Collectionを継承しており、Collectionが提供するメソッドを利用することができます。Listインタフェースは、複数の要素を順序付けをして格納することができ、要素の重複を許容するという特徴があります。配列のように添字で要素の順序を管理しますが、配列と違って要素数は動的で要素の追加、削除が自由にできます。

Listのインタフェースですから、実装はそのサブクラスが担っています。実装クラスは以下のようなものがあります。

ArrayListはサイズ変更可能な可変長配列として実装されており、リストへの要素の追加や削除に応じて動的に拡大・縮小することができます。要素へのアクセスは高速ですが、リストの途中からの要素の挿入や削除に時間がかかることがあります。

一方、LinkedListは連結リストとして実装されており、要素を含むノードの集合と、リスト内の前後のノードへの参照で構成されています。LinkedListは要素の挿入と削除は高速に行うことができますが、要素へのアクセスは遅くなってしまいます。

Vectorは、ArrayListと同様に可変長配列です。スレッドセーフなコレクションなのでマルチスレッド環境を要しない限りArrayListを使うほうがパフォーマンスが良くなります。

Java Listインターフェースの実装

インタフェースから直接オブジェクトを作成することができないので、Listインタフェースを利用するには実装したクラスを使います。例えば、ArrayListクラスを使うと、次のようなリストを作成することができます。

class Main {
    public static void main(String[] args) {
        // ArrayListを初期化しList型で扱うリストの作成
        java.util.List<Integer> list = new java.util.ArrayList<>();        
    }
}

この例では、ArrayListクラスを使って新しいインスタンスを作成し、それをList型で扱うことを宣言しています。ArrayListやListなどのコレクションはjava.utilパッケージに属しています。java.util.Listやjava.util.ArrayListは完全修飾クラス名といい、一般的には完全修飾クラス名を使わず、それぞれimportして利用します。

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

class Main {
    public static void main(String[] args) {
        // ArrayListを初期化しList型で扱うリストの作成
        List<Integer> arrayList = new ArrayList<>();    

        // LinkedListを初期化しList型で扱うリストの作成
        List<Integer> linkedList = new LinkedList<>();        
    }
}

ArrayListとLinkedListはどちらもListインターフェースを実装したクラスで、Listインターフェースのメソッドの具体的な実装を提供します。これらのクラスのいずれかを使用してリストを作成し、コード内で使用することができます。

Java Listインターフェースのメソッド

Listインタフェースには、リスト内の要素を操作するためのメソッドがいくつか用意されています。最もよく使われるメソッドをいくつか紹介します。

  • add(element): 要素をリストの末尾に追加します。
  • add(index, element): リストの指定されたインデックスに要素を追加します。
  • get(index):リスト中の指定されたインデックスの要素を返します。
  • remove(index): リスト中の指定されたインデックスの要素を削除します。
  • set(index, element): リスト中の指定されたインデックスの要素を指定された要素で置き換 えます。
  • size(): リストが持つ要素数を返します。

ここでは、これらのメソッドの一部を使用する例を紹介します。

import java.util.ArrayList;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("Apple");
        list.add("Banana");
        list.add("Orange");

        System.out.println(list.get(1)); // "Banana"

        list.remove(2);
        System.out.println(list); // "[Apple, Banana]"

        list.set(0, "Mango");
        System.out.println(list); // "[Mango, Banana]"
    }
}

Java Listインタフェースで拡張for文を使う

Listインタフェースが継承しているCollectionインタフェースは、Iterableインタフェースを継承しています。Iterableインタフェースは拡張for文を使うために用意されています。Listをforでループするには、通常のfor文よりも拡張for文を使ったほうがパフォーマンスが良くなります。

import java.util.ArrayList;
import java.util.List;

class Main {
    public static void printList(List<String> list) {
        for(String s: list) {
            System.out.println(s);
        }
    }
    public static void main(String[] args) {
        List<String> fruits = new ArrayList<String>();
        fruits.add("apple");
        fruits.add("banana");
        fruits.add("orange");
        fruits.add("kiwi");

        printList(fruits);
    }
}

Java Listインタフェースで扱うメリット

先ほどArrayListで作成したコードをLinkedListに変更してみましょう。

import java.util.LinkedList;
import java.util.List;

class Main {
    public static void printList(List<String> list) {
        for(String s: list) {
            System.out.println(s);
        }
    }
    public static void main(String[] args) {
        List<String> fruits = new LinkedList<String>();
        fruits.add("apple");
        fruits.add("banana");
        fruits.add("orange");
        fruits.add("kiwi");

        printList(fruits);
    }
}

このコードではInteger型の要素を扱うLinkedListを初期化し、それをList型のfruitsという変数で扱うと宣言するように変更されました。ArrayListからLinkedListに変更しましたが、List型で扱うと宣言しているためリストを操作する処理を変更する必要はありません。利用する側のコードを変更することなく仕様変更に対応できる点が、List型で宣言するメリットです。

この記事を書いた人

著者の画像

Jeffry Alvarado

Ex-Facebook Engineer 大学ではコンピュータサイエンスを専攻し、在学中に複数のインターンシップを経験。コンピュータサイエンスが学習できるプラットフォームRecursionを創業し、CTOとしてカリキュラム作成、ソフトウェア開発を担当。


ツイート