プログラミングを行う際に、複数のデータを一つのまとまりとして扱いたいケースは多々あります。
Javaにおいて、同じ種類のデータを集めて管理する場合に活用できるのが、Collectionを継承したインターフェースの1つである 「List」 です。
今回は、Javaで Listを使用する方法について、基本内容から応用的な使い方まで詳しく解説していきたいと思います。
Listとは?
Listは、順序を持ったデータ集合を扱うためのインターフェースです。
各要素は追加された順番に並び、インデックス(添字) を使用してアクセスすることができます。
また、同じく Collectionを継承したインターフェースである Setと異なり、同じ値を重複して格納できるのも Listの特徴の1つです。
Listを実際に使用する際は、ArrayList や LinkedList といった実装クラスを利用します。
Listと配列の違いとは?
Javaには、Listに似たデータ構造を持つ 「配列」 という機能も存在します。
どちらも複数のデータをまとめて扱うための仕組みですが、いくつかの異なる点が存在します。
もっとも大きな違いは、宣言後のサイズ変更が可能かどうかという点です。
配列は、一度作成すると後からサイズを変更することができない (固定長である) ため、要素の追加や削除を行うことができません。
そのため、後から要素の数を増減する場合は、新しく用意した配列に必要な要素をコピーするなどして対応する必要があります。
一方、Listは動的にサイズを変更することが可能 (可変長である) なため、追加や削除も容易に行うことができます。
データ操作に関するメソッドも豊富に用意されているため、既存のメソッドを使うだけで簡単に操作することが可能です。
要素数が事前に分からなかったり、処理内容に応じてサイズが変動することが多い場合には、Listの使用が適しています。
反対に、サイズが固定されている場合は配列の方が処理速度が速いケースもあるため、用途に応じた使い分けが重要となります。
ArrayListとLinkedListの違いとは?
Listの代表的な実装クラスに、ArrayList と LinkedList の2つがあります。
サイズが可変長である点や、メソッドによる追加や削除などが可能である点は同じですが、データを保存する際の内部構造が異なるため、使用するクラスによって得意な処理に違いがあります。
ArrayListは、配列ベースのデータ構造を持つクラスです。
連続するメモリ領域を確保して要素を格納するため、インデックスによる各要素への直接アクセスが可能であり、要素の位置に関係なく高速でデータを取得することができる特徴を持ちます。
一方で、先頭や間に要素を追加したり、反対に削除したりする場合には、後続する要素の位置を移動させる必要があるため、処理に時間がかかる傾向にあります。
対する LinkedListは、配列のように連続した領域を確保するのではなく、各領域にあるデータをリンクで繋ぐことによって一連性を持たせるクラスです。
データの構造上、インデックスによってアクセスする際に先頭や末尾からリンクを辿る必要があるため、取得位置によっては処理に時間がかかってしまう場合があります。
反対に、要素の追加や削除はリンクを繋ぎ直すだけで完了するため、どの位置に追加しても高速で処理することが可能です。
リストの要素に頻繁にアクセスする必要がある場合は ArrayList、追加や削除を行う機会が多い場合は LinkedListが使用に適しています。
ArrayListの使い方
ArrayList を使用する際は、「new ArrayList<>()」 で空のリストを作成することができます。
List<String> list = new ArrayList<>();Listで扱えるデータ型は参照型のみのため、intなどのプリミティブ型を指定することはできません。
そのため、数値などを格納する場合はラッパークラスを指定するようにしてください。
// プリミティブ型のためエラーが発生する
List<int> list = new ArrayList<>();
// ラッパークラスである Integerを使用
List<Integer> list = new ArrayList<>();作成後に要素を追加するのが一般的ですが、宣言と同時に値を指定したい場合は、以下の方法も使用できます。
List<String> list = new ArrayList<>(List.of("A", "B", "C"));LinkedListの使い方
LinkedList を使用する場合も、基本的な方法は ArrayListと変わりません。
// 空のリストを作成
List<String> list = new LinkedList<>();
// 作成と同時に要素を格納
List<String> list = new LinkedList<>(List.of("A", "B", "C"));Listを初期化する方法
Listを初期化する方法は、初期値を設定する必要があるかどうかで方法が変わります。
new ArrayListで空のリストを作成する
初期値の設定が必要ない場合は、空のリストを作成するのが一般的です。
上述したように、「new ArrayList<>()」 や 「new LinkedList<>()」 で空のリストを作成することができます。
List<Integer> arraylist = new ArrayList<>();
List<Integer> linkedlist = new LinkedList<>();Arrays.asListで値を追加する
初期値を指定したい場合に使用できる方法の1つに、Arrays.asList() を使用する方法があります。
List<String> list = Arrays.asList("A", "B", "C");使用時の注意点として、この方法で作成したリストは固定長となるため、要素の追加や削除は行うことができません。
通常のリストと同じように可変長にしたい場合は、new ArrayList<>()のコンストラクタに指定することで変更できます。
List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C"));Listの基本操作
Listの各種操作は、メソッドを通して行うことができます。
それぞれのメソッドの使い方について確認していきましょう。
addで要素を追加・挿入する
リストに要素を追加する際は、addメソッドを使用します。
// 値のみ場合
list.add("A");
// インデックスを指定する場合
list.add(1, "B");値のみの場合は末尾に、インデックスを指定した場合は対象の位置に要素が追加されます。
get、setでデータを取得・上書きする
要素を取得する場合は getメソッド、値を上書きする場合は setメソッドを使用します。
// 要素を取得する場合
String val = list.get(0);
// 上書きする場合
list.set(0, "D");remove、clearでデータを削除する
特定の要素を削除する場合は removeメソッド、全ての要素を削除する場合は clearメソッドで削除することができます。
// 指定の要素のみ削除
list.remove(0);
// 全ての要素を削除
list.clear();size、containsでリストの状態を確認する
sizeメソッドを使用すると、対象のリストの要素数を取得することができます。
int size = list.size();また、containsメソッドを使用することで、対象の要素がリストに含まれているかを検索可能です。
boolean exists = list.contains("A");Listの並び替え方法
sortメソッドを使用することで、リスト内の要素を並べ替えることができます。
メソッドの引数に渡す内容によって、昇順と降順を変更することも可能です。
昇順に並び替える場合
要素を昇順に並び替える場合は、引数にComparator.naturalOrder() を指定します。
List<String> list = new ArrayList<>(List.of("A", "D", "C", "B"));
list.sort(Comparator.naturalOrder());[A, B, C, D]降順に並び替える場合
降順に並び替える場合は、引数にComparator. reverseOrder() を指定します。
List<String> list = new ArrayList<>(List.of("A", "D", "C", "B"));
list.sort(Comparator.reverseOrder());[D, C, B, A]Listの反復処理
リスト内の各要素にアクセスする場合は、ループ処理を使用すると便利です。
for文で繰り返す
インデックスが必要な場合は、for文を活用しましょう。
List<String> list = new ArrayList<>(List.of("A", "B", "C"));
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}条件指定にsizeメソッドを使用することで、ループ回数を動的に変更することができます。
forEachメソッドで繰り返す
ケースによっては、forEachメソッドとラムダ式を利用して、より簡潔にコードを記述できる場合もあります。
list.forEach(val -> System.out.println(val));Stream APIを活用して、複雑なデータを加工する
Stream APIを活用すると、フィルタリングや変換処理などの複雑なデータ処理も簡単に実行することができます。
List<String> list = new ArrayList<>(List.of("Alice", "Bella", "Casey", "Aimee"));
list.stream()
.filter(s -> s.startsWith("A"))
.forEach(val -> System.out.println(val));Alice
Aimeeまとめ
いかがでしたか?今回は、Javaで Listを使用する方法について解説しました。
Listは、実際の開発でも頻繁に利用される重要な機能の1つです。
各クラスの特徴や使い方をしっかりと把握して、実務でも活用できるように習得していきましょう。
Javaの勉強方法は?
書籍やインターネットで学習する方法があります。昨今では、YouTubeなどの動画サイトやエンジニアのコミュニティサイトなども充実していて多くの情報が手に入ります。
そして、より効率的に知識・スキルを習得するには、知識をつけながら実際に手を動かしてみるなど、インプットとアウトプットを繰り返していくことが重要です。特に独学の場合は、有識者に質問ができたりフィードバックをもらえるような環境があると、理解度が深まるでしょう。
ただ、Javaに限らず、ITスキルを身につける際、どうしても課題にぶつかってしまうことはありますよね。特に独学だと、わからない部分をプロに質問できる機会を確保しにくく、モチベーションが続きにくいという側面があります。独学でモチベーションを維持する自信がない人にはプログラミングスクールという手もあります。費用は掛かりますが、その分スキルを身につけやすいです。しっかりと知識・スキルを習得して実践に活かしたいという人はプログラミングスクールがおすすめです。
プログラミングスクールならテックマニアがおすすめ!
ITスキル需要の高まりとともにプログラミングスクールも増えました。しかし、どのスクールに通うべきか迷ってしまう人もいるでしょう。そんな方にはテックマニアをおすすめします!これまで多くのITエンジニアを育成・輩出してきたテックマニアでもプログラミングスクールを開講しています。
<テックマニアの特徴>
・たしかな育成実績と親身な教育 ~セカンドキャリアを全力支援~
・講師が現役エンジニア ~“本当”の開発ノウハウを直に学べる~
・専属講師が学習を徹底サポート ~「わからない」を徹底解決~
・実務ベースでスキルを習得 ~実践的な凝縮カリキュラム~
このような特徴を持つテックマニアはITエンジニアのスタートラインとして最適です。
話を聞きたい・詳しく知りたいという方はこちらからお気軽にお問い合わせください。