Skip to content
Playground

演習: ArrayList

各問題のコードは、Main クラスの main メソッドの中に書く前提です。ArrayList を使うには import java.util.ArrayList; が必要です。

ArrayList動的サイズの配列 のような型で、配列と違って要素数が後から自由に変えられます。基本的な使い方:

import java.util.ArrayList;
public class Main {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<>();
list.add(10);
list.add(20);
System.out.println(list.size()); // 2
System.out.println(list.get(0)); // 10
}
}

ArrayList<型>参照型 である必要があり、プリミティブ型(intdouble など)はそのままでは使えません。代わりに IntegerDouble などの ラッパークラス を使います。Java が自動で変換するので、list.add(10) のように int のリテラルをそのまま渡すこともできます。

整数を要素に持つ ArrayList<Integer> を作り、10, 20, 30, 40, 50 の5つの要素を追加してください。最後に、要素数: に続けて要素数を、次の行に全要素を出力します。

出力例:

要素数: 5
[10, 20, 30, 40, 50]
ヒント

ArrayList<Integer> のインスタンス化:

ArrayList<Integer> list = new ArrayList<>();

右辺の <>ダイヤモンド演算子 と呼ばれ、左辺の型から型推論されます。

要素の追加には add(値) メソッドを使います。要素数は size()、全要素は System.out.println(list) で自動的に [10, 20, 30, ...] の形式で表示されます。

7-B. 要素の追加と取得(add, get, size)

Section titled “7-B. 要素の追加と取得(add, get, size)”

ArrayList<String> を作り、果物の名前を3つ追加します("apple""banana""cherry")。その後、インデックス指定で各要素を取り出して、インデックス: 要素 の形式で1行ずつ出力してください。

出力例:

0: apple
1: banana
2: cherry
ヒント

要素の追加: list.add(値)(末尾に追加)。

インデックス指定の取得: list.get(インデックス)

for ループで i を 0 から list.size() - 1 まで進め、各位置の要素を取り出します。

7-C. 要素の削除と更新(remove, set)

Section titled “7-C. 要素の削除と更新(remove, set)”

ArrayList<String>"apple""banana""cherry""date" を追加した状態から、次の操作を順に行い、各操作後の ArrayList の内容を出力してください。

  1. インデックス 1 の要素を削除する
  2. 末尾に "elderberry" を追加する
  3. インデックス 0 の要素を "avocado" に変更する

出力例:

初期状態: [apple, banana, cherry, date]
1の削除後: [apple, cherry, date]
追加後: [apple, cherry, date, elderberry]
更新後: [avocado, cherry, date, elderberry]
ヒント
  • 削除: list.remove(インデックス) でその位置の要素を削除(後続の要素が前にずれる)
  • 追加: list.add(値) で末尾に追加
  • 更新: list.set(インデックス, 新しい値) でその位置の要素を置き換え

ArrayList<Integer>3, 1, 4, 1, 5, 9, 2, 6 を追加し、拡張 for 文で全要素を半角スペース区切りで1行に出力してください。

出力例:

3 1 4 1 5 9 2 6
ヒント

拡張 for 文は ArrayList にも使えます。要素の型は Integer(または int でも可)として受け取ります。int で受け取ると、Integer から自動で変換されます。

要素間の区切りには半角スペースを手動で挿入する必要があります(5-A. 配列の宣言と表示と同じ)。

ArrayList<Integer> を受け取り、合計と平均を出力してください。平均は小数で表示します。

ArrayList<Integer> scores = new ArrayList<>();
scores.add(72);
scores.add(85);
scores.add(64);
scores.add(90);
scores.add(78);

出力例:

合計: 389
平均: 77.8
ヒント

for または拡張 forArrayList を走査し、合計を計算します。平均は (double) 合計 / list.size() でキャストが必要です(整数除算を避けるため)。

ArrayList<Integer> の最大値を出力してください。

ArrayList<Integer> numbers = new ArrayList<>();
numbers.add(15);
numbers.add(22);
numbers.add(18);
numbers.add(30);
numbers.add(25);
numbers.add(17);
numbers.add(28);

出力例:

最大値: 30
ヒント

list.get(0) を仮の最大値とし、インデックス 1 以降と順に比較していきます(5-C. 最大値と同じ考え方を ArrayList で行います)。

7-G. 特定値の検索(contains, indexOf)

Section titled “7-G. 特定値の検索(contains, indexOf)”

ArrayList<String> に対して、指定した値が含まれているかどうかと、含まれている場合は最初のインデックスを出力してください。

ArrayList<String> fruits = new ArrayList<>();
fruits.add("apple");
fruits.add("banana");
fruits.add("cherry");
fruits.add("banana");
fruits.add("date");
String target1 = "banana";
String target2 = "grape";

出力例:

banana: あり (最初の位置: 1)
grape: なし
ヒント
  • list.contains(値): その値が含まれていれば true、なければ false を返す
  • list.indexOf(値): 最初に現れる位置のインデックスを返す。見つからなければ -1

contains の結果で if 分岐し、見つかった場合に indexOf で位置を取得します。indexOf だけ使って、-1 かどうかで判定する書き方もできます。

2つの ArrayList<Integer> を、list1 の後ろに list2 をつなげる形で連結させ、結果を出力してください。元の list1 を直接書き換えます。

ArrayList<Integer> list1 = new ArrayList<>();
list1.add(1);
list1.add(2);
list1.add(3);
ArrayList<Integer> list2 = new ArrayList<>();
list2.add(10);
list2.add(20);
list2.add(30);

出力例:

連結後: [1, 2, 3, 10, 20, 30]
ヒント

addAll メソッドを使うと、別の ArrayList の全要素を一度に追加できます:

list1.addAll(list2);

または、拡張 forlist2 を走査して、1要素ずつ list1.add(要素) で追加する手動方式でも同じ結果になります。

ArrayList<Integer> から重複する要素を削除し、各値が最初に登場した順序を保ったまま、結果を出力してください。

ArrayList<Integer> numbers = new ArrayList<>();
int[] data = {3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 9};
for (int n : data) numbers.add(n);

出力例:

[3, 1, 4, 5, 9, 2, 6]
ヒント

新しい ArrayList<Integer> を1つ用意し、元の ArrayList を走査します。各要素について、新しい方にまだ含まれていなければ追加します。contains メソッドで判定できます。

最後に、元の ArrayList を新しい方で置き換える(または新しい方を結果として使う)。

7-J. Fisher-Yates シャッフル(ArrayList 版)

Section titled “7-J. Fisher-Yates シャッフル(ArrayList 版)”

ArrayList<Integer> を Fisher-Yates アルゴリズムでシャッフルし、結果を出力してください。元の ArrayList を直接書き換えます。アルゴリズムは 5-L. Fisher-Yates シャッフルと同じです。

ArrayList<Integer> numbers = new ArrayList<>();
for (int i = 1; i <= 10; i++) numbers.add(i);

実行ごとに結果が変わります。出力例の1つ:

[3, 7, 1, 9, 4, 10, 2, 8, 5, 6]
ヒント

アルゴリズム自体は 5-L. Fisher-Yates シャッフルと同じですが、ArrayList では要素の交換に get / set を使います:

int tmp = list.get(i);
list.set(i, list.get(j));
list.set(j, tmp);

ランダムなインデックス j0 ≤ j ≤ i)の生成は (int)(Math.random() * (i + 1)) です。

7-K. スタック実装(push / pop / peek)

Section titled “7-K. スタック実装(push / pop / peek)”

ArrayList<Integer> を使って、スタック(後入れ先出し、LIFO)の操作を実装してください。次の3つのメソッドを static で定義します:

  • push(list, value): 末尾に要素を追加(void
  • pop(list): 末尾の要素を取り出して返す(int、空ならエラー)
  • peek(list): 末尾の要素を見るだけ(取り出さない、int

main で以下の操作を順に行い、結果を確認します:

ArrayList<Integer> stack = new ArrayList<>();
push(stack, 10);
push(stack, 20);
push(stack, 30);
System.out.println("スタック: " + stack);
System.out.println("peek: " + peek(stack));
System.out.println("pop: " + pop(stack));
System.out.println("pop: " + pop(stack));
System.out.println("スタック: " + stack);

出力例:

スタック: [10, 20, 30]
peek: 30
pop: 30
pop: 20
スタック: [10]
ヒント

スタックの「末尾」を list.size() - 1 のインデックスとして扱います:

  • push: list.add(value) で末尾に追加
  • pop: list.remove(list.size() - 1) で末尾を取り出して返す
  • peek: list.get(list.size() - 1) で末尾を参照(削除しない)

pop / peek で空のスタックに対する操作が呼ばれた場合のエラー処理(例外を投げる、あるいは特殊な値を返す)も考えられますが、呼び出し側が空でないことを保証する前提で構いません。