こんにちは!フリーランスのオータケです。
みなさんJavaプログラミングを楽しんでいますか?Javaにはコレクションという大きさを決めない配列のようなものがあります。
そして、コレクションの中にはListというインタフェースがあります。
皆さんはListとArrayListの違いを知っていますか?そして使い分けについてどのようにしていますか?
もしわからないと思った貴方にはこの記事は必見です!
この記事を見ればListがどういったものかArrayListとの違いは何かを学ぶことができます!
この記事では、コレクションとListについて
- コレクションとは
- Listとは
- ArrayListとは
- 宣言の型はListとArrayListのどちらを使うべきか
など基本的な内容から具体的な内容についても解説していきます。
今回はコレクションとListについて、使い方をわかりやすく解説します!
なお、Javaの記事については、こちらにまとめています。
コレクションとは
コレクションとは、大きさが決まっていないが配列のように多数の値をまとめて操作できるものと考えるとよいでしょう。
大きさが決まっていませんので、必要な分の数だけデータを格納することができます。
コレクション・フレームワークとは
コレクションには下記のように用途に応じて主に3種類が用意されています。
- リスト(List) 順序通りに並べて格納
- セット(Set) 順序があるとは限らず格納
- マップ(Map) ペアで対応づけて格納
このように種類が用意され柔軟に扱うことを考えられているのがコレクション・フレームワークです。
コレクション・フレームワークは1つのクラスだけでなく、多くのクラスとインターフェースから構成されています。
コレクションクラスとは
「List」「Set」「Map」はインターフェースとして用意されています。
実際に使用する際には、これらのインターフェースを実装したクラスを使用します。
よく使われるのはListのArrayListなどです。Listはインターフェースで、ArrayListはListを実装したクラスになります。
ArrayListのようにコレクション・フレームワークのインターフェースを実装したクラスのことをコレクションクラスといいます。
それではよく使われるListやArrayListについて詳しく解説してきます!
Listとは
Listはインターフェースと呼ばれる抽象メソッドのみをもったクラス的なものです。
このインタフェースは単体では使うことができないため実装という手順が必要になります。
インタフェースを実装することで実装したクラスを使うことができるようになります。
ArrayListとは
ArrayListとはListインタフェースを実装したコレクションクラスです。
Arrayという名にあるように配列のような感覚で扱えます。
ちなみにListを実装したクラスには他にもLinkedListやStackといったクラスが存在しています。
宣言の型はListとArrayListのどちらを使うべきか
前項まではListとArrayListのそれぞれについて説明を行いました。
一見すると同じように見える両者ですがListとArrayListでは大きな違いがあります。
まずListはあくまでもインタフェースであるためインスタンスの生成ができません。
例えば、
List<Integer> list = new List<Integer>();
とすることは出来ません。
これはListがインタフェースであり、抽象メソッド(一言で中身がないメソッド)しか保持していないという理由があります。
ただし、次のコードのように宣言側の型として使うことはできます。
List<Integer> list = new ArrayList<Integer>();
このような書き方は可能です。
これに対し、ArrayListはListの実装クラスであり抽象メソッドの処理内容が定義されているため、ArrayListは下のような書き方をすることができます。
ArrayList<Integer> list = new ArrayList<Integer>();
とどちらを使うべきでしょうか?
例えば、宣言をListでインスタンス生成をArrayListで行った場合は
メリット
- ArrayListからLinkedList等別のコレクション(データ型)に変更したい場合宣言時のListには手を加えなくても良い
デメリット
- ArrayListにしかないメソッドを使いたい場合、宣言はListであるため型キャストをするなど一手間必要になる
といったことがあり筆者としてはケースバイケースでその時の状況にあった形で使い分けをすべきではないかと思います。
それでは、宣言の型にListを使う方がいい場合とArrayListを使う方がいい場合、それぞれの場合についてサンプルコードで確認していきましょう!
Listを使う場合
宣言の型にListを使う方がいい場合は、例えばArrayListからLinkedList等別のコレクションに変更したい場合などでした。
サンプルコードで確認していきましょう。
なおListで宣言する場合は、java.util.Listをインポートする必要があります。ArrayListで定義する場合は、java.util.ArrayListをインポートする必要があります。
LinkedListで定義する場合は、java.util.LinkedListをインポートする必要があります。
import java.util.ArrayList; import java.util.LinkedList; import java.util.List; public class Main { public static void main(String[] args) { List<Integer> foo = new ArrayList<Integer>(); foo.add(10); foo.add(20); foo.add(30); // ArrayListからLinkedListへの変換 LinkedList<Integer> ll = new LinkedList<Integer>(foo); for(Integer i : ll) { System.out.println(i); } } }
実行結果:
10 20 30
このサンプルコードでは、ArrayListからLinkedListへ変換しています。変換元のオブジェクトはListで宣言しているので、特に手を加える必要はありません。
ちなみに、LinkedListはArrayListと似ていますが、要素がどのように並んでいるか別で管理しているために、要素を追加したり削除したりする場合にArrayListと比べて高速に動作するというメリットがあります。
しかし、要素を先頭から順にたどるため要素を検索する場合はArrayListと比較して遅くなるというデメリットもあります。
ArrayListを使う場合
宣言の型にArrayListを使う方がいい場合は、例えばArrayListにしかないメソッドを使いたい場合などでした。
Listのメソッドにはなくて、ArrayListにしかないメソッドとしてListをコピーするcloneメソッドがあります。
cloneメソッドを使用するサンプルコードで確認していきましょう。
import java.util.ArrayList; public class Main { public static void main(String[] args) { ArrayList<Integer> foo = new ArrayList<Integer>(); foo.add(10); foo.add(20); foo.add(30); // ArrayListのコピー ArrayList<Integer> bar = (ArrayList<Integer>)foo.clone(); for(Integer i : bar) { System.out.println(i); } } }
実行結果:
10 20 30
このサンプルコードではArrayListクラスのcloneメソッドを使用してArrayListのオブジェクトをコピーしています。
なお、Listのコピーについての詳しい解説はこちらも参考にしてくださいね!
まとめ
ここでは、コレクションやコレクションクラスについて解説してきました。
またコレクションの中でもよく使われるListやArrayListについて詳しく解説しました。
ListはインタフェースでありArrayListはそのインタフェースの実装クラスであることをお伝えしました。
そして、ArrayListを定義する際に受け取り側の方をListにする方法があり、なぜそのようにするべきかはケースバイケースであることも解説をしました。
もしListとArrayListの違いを忘れたらこの記事を思い出して下さい!