JavaでListを使う(サンプルコード有)

Java_icon Java
この記事は約12分で読めます。

この記事は、以下の方に向けて書いています。

  • Listの使い方が分からない
  • Listの基本的な使い方は分かるけど、もっと知りたい

List作成構文

基本的な構文は以下の通りです。

Listの中には、ArrayListやLinkedListという型が存在しますが、

今回は扱いやすいArrayListの解説になります。

List<型> list = new ArrayList<>();

型推論(var)を使って記述する場合は、以下の通りです。

var list = new ArrayList<型>();

型はラッパークラスを指定してください。

例えばint型のラッパークラスはIntegerになります。

基本(プリミティブ)型ラッパークラス備考
byteByte
shortShort
intIntegerよく使います
doubleDoubleよく使います
longLong
floatFloat
booleanBooleanよく使います
charChar
Javaのデータ型

ちなみに、文字列を格納するString型は参照型ですので、Listに入れることが可能です。

データ型の最初の1文字目が大文字のものは格納できます。

ですので、クラスもListに格納することが可能です。

使用頻度が高いメソッド

次に使用頻度が高く便利なメソッドを紹介します。

add | 追加

addメソッドはListに要素を追加する際に使用します。

下図の実行結果から分かるように、addメソッドはListの最後尾に値が追加されます。

List<String> list1 = new ArrayList<>();
list1.add("aaa");
list1.add("bbb");
		
System.out.println(list1);
// [aaa, bbb]

addメソッドの引数に追加したいデータを記述することでListに値が追加されます。

特定の場所に、値を追加したい場合は、以下のように書き換えます。

List<String> list = new ArrayList<>();
list.add("aaa");
list.add("bbb");
		
list.add(1, "ccc");
				
System.out.println(list);
// [aaa, ccc, bbb]

addメソッドの第1引数に追加したい場所、第2引数に追加する値を記述します。

addAll | まとめて追加

まとめて値をListに格納したい場合は、Collections.addAllメソッドを使うと楽に追加出来ます。

第1引数に対象のList、第2引数以降に追加したい値を記述します。

List<String> list = new ArrayList<>();
Collections.addAll(list, "aaa", "bbb", "ccc");
				
System.out.println(list);
// [aaa, bbb, ccc]

また、addAllメソッドは、List同士の結合も可能です。

List<String> list1 = new ArrayList<>();
Collections.addAll(list1, "aaa", "bbb", "ccc");
		
List<String> list2 = new ArrayList<>();
Collections.addAll(list2, "ddd", "eee", "fff");
		
list1.addAll(list2);
System.out.println(list1);
// [aaa, bbb, ccc, ddd, eee, fff]

set | 変更

setメソッドは、既にListに格納されている値を書き換えることができます。

List<String> list1 = new ArrayList<>();
list1.add("aaa");
list1.add("bbb");
		
list1.set(0, "ccc");
	
System.out.println(list1);
// [ccc, bbb]

setメソッドの第1引数には、変更したい要素のindexを指定します。

第2引数には、変更後の値を記述します。

ちなみに、第1引数で指定するindexが存在しない場合はエラーが発生するので注意

get | 値の取得

getメソッドでは引数で指定したindexの値を取得できます。

戻り値はListではなく、Listの中の要素の型になります。

List<String> list1 = new ArrayList<>();
list1.add("aaa");
list1.add("bbb");
		
System.out.println(list1.get(1));
// bbb

size | 要素数を取得

sizeメソッドは、Listの中にある要素の数を取得することができます。

戻り値は、int型になります。for文の条件式に使われることが多いです。

List<String> list1 = new ArrayList<>();
list1.add("aaa");
list1.add("bbb");
		
System.out.println(list1.size());
// 2

contains | 存在確認

containsメソッドは、Listの中に引数で指定した値が含まれるか確認できます。

戻り値はboolean型になります。よくif文の条件式に使用されます。

List<String> list1 = new ArrayList<>();
list1.add("aaa");
list1.add("bbb");
		
System.out.println(list1.contains("aaa"));
// true

isEmpty | 空かどうか確認

isEmptyメソッドは、Listの中に要素が入っていないか確認することができます。

空の場合はtrue空ではない場合はfalseになります。

こちらもif文の条件式でよく使用されます。

List<String> list1 = new ArrayList<>();
list1.add("aaa");
list1.add("bbb");
		
System.out.println(list1.isEmpty());
// false

Listを使ったテクニック

いろいろなテクニックをいくつか紹介します。

Listの中にListを入れる

以下のサンプルコードでは、Listの中にListを入れています。

List<List<String>> lists = new ArrayList<>();
List<List<Integer>> lists = new ArrayList<>();

階層的になったListを取り出す方法は以下の通りです。

List<List<String>> lists = new ArrayList<>();
lists.add(List.of("aaa", "bbb"));
lists.add(List.of("ccc", "ddd"));
		
System.out.println(lists.get(0).get(1));

// bbb

3行目のList.ofは長さ(length)が固定のListを作成できます。

add(追加)やremove(削除)ができなくなりますので、注意してください。

また、nullを入れることもできません。

拡張for文で値を取り出す

値をすべて取り出したい場合は、拡張for文が便利です。

ただし、removeメソッド(削除)を使用する場合は注意してください。

拡張for文を使う場合は、removeメソッドを使用しないのが無難です。

List<String> lists = new ArrayList<>();
lists.add("aaa");
lists.add("bbb");

for (var list : lists) {
	System.out.println(list);
}

// aaa
// bbb

iteratorを使用する

イテレーターを使用することで拡張for文のように繰り返し処理を実現できます。

hasNext()は次の要素がある場合にtrueになります。

List<String> list = new ArrayList<>();
list.add("aaa");
list.add("bbb");
Iterator<String> ite = list.iterator();

while (ite.hasNext()) {
	System.out.println(ite.next());
}
	
// aaa
// bbb

Listの中にクラスを入れる

Listの中には基本的にどんな型でも入れることができます。

※int型などのプリミティブ型は不可(IntegerであればOK)

クラスも型ですので、Listの中に入れることができます。

まずは、リストに格納するクラスを作成します。

package java20230808;

public class Data {
	private int num;
	private String str;
	
	// setterとgetterの定義
	public int getNum() {
		return num;
	}
	public void setNum(int num) {
		this.num = num;
	}
	public String getStr() {
		return str;
	}
	public void setStr(String str) {
		this.str = str;
	}
}

次に、Mainクラスを作成します。

package java20230808;

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

public class Main {

	public static void main(String[] args) {
		// Dataクラスのインスタンス(data1)を作成し、値をセット
		Data data1 = new Data();
		data1.setNum(1);
		data1.setStr("apple");
		
		// Dataクラスのインスタンス(data2)を作成し、値をセット
		Data data2 = new Data();
		data2.setNum(2);
		data2.setStr("banana");
		
		// リストに上で作成した2つのインスタンスを格納
		List<Data> dataList = new ArrayList<>();
		dataList.add(data1);
		dataList.add(data2);
		
		// 拡張for文でDataクラスの中に入っている値を取り出す
		for (Data data : dataList) {
			System.out.println(data.getNum() + ":" + data.getStr());
		}
	}
}

これで実行すると、結果は以下のようになります。

1:apple
2:banana

このようにクラスもリストに格納することができます。

最初は難しく感じますが、慣れると便利で使用する場面も多々ありますので

覚えておくといいと思います。

LinkedListについて

冒頭で少し、LinkedListについて触れたので、少し解説します。

LinkedListは、ArrayListと非常に似ていますが、構造が異なります。

そのため、それぞれに違いやメリットとデメリットがあります。

内部実装

ArrayListは、内部的に配列を使用して値の格納を行います。

値の追加や削除が行われるたびに、内部の配列のサイズを調整しています。(可変長配列)

一方で、LinkedListは双方向リンクリストを使用して値を格納しています。

各値は、前後の要素の参照を保持しているため、値の追加や削除が効率的になります。

そのため、値の追加や削除を目的とするListの場合はLinkedListが有効な場合が多いです。

アクセス効率

ArrayListは、値が順序を保持しているため、List内のランダムな値へのアクセス速度は速いです。

値のインデックス(順序)を指定したい場合は、ArrayListが有効です。

LinkedListは、値が順序を保持しているわけではなく、前後を見なければいけないため、

ランダムな値へのアクセス速度は遅くなります。

ただし、先頭から順番にたどるような操作にはLinkedListが有効です。

追加/削除の効率

ArrayListは、値の追加や削除をする場合に後続の値をずらす必要があるため、

追加や削除の操作には向いていません。

一方でLinkedListは、前後の値のリンクを変更するだけなので効率よく操作が可能です。

メモリ使用量

ArrayListは、内部的に配列を使用するため、

値の追加や削除が頻繁に行われる場合でも、メモリの再割り当てが発生しません。

LinkedListは、各値が自身の前後の値への参照を持つため、余分なメモリが必要になります。

また、値ごとに参照用のオブジェクトが追加されるため、

ArrayListよりもメモリ使用量が多くなる場合があります。

まとめ

ここまでListについて、紹介しました。

工夫次第で便利な使い方ができるので、色々試してみてください。

読んでいただき、ありがとうございます。

コメント

タイトルとURLをコピーしました