List を走査する
i を増やしたいわけではない
リストの中身を頭から見ていくとき、まず思いつくのは配列と同じインデックスのループです。
Java
ArrayList<String> names = new ArrayList<>();
names.add("sato");
names.add("suzuki");
names.add("takahashi");
for (int i = 0; i < names.size(); i++) {
System.out.println(names.get(i));
}動きますが、i は本当に欲しかったものでしょうか。やりたいのは全部の名前を表示することで、i はそのための道具にすぎません。しかも size() は配列の length と違ってメソッドなので () が要り、条件を <= と書けば最後の 1 周で IndexOutOfBoundsException が飛びます。位置そのものを使わないなら、i は書かないほうが安全です。
拡張 for なら、インデックスは要らない
Java 5 から使える拡張 for なら、インデックスを一切書かずに全要素を回せます。
Java
int total = 0;
for (String name : names) {
total += name.length();
}
System.out.println(total); // 19for (String name : names) は「names の中身を 1 つずつ name という名前で取り出す」という意味です。get(i) の呼び出しも終了条件も消えました。リストが空なら 1 周も回らないので、空かどうかの確認を別に書く必要もありません。
取り出す変数の型は、リストの山かっこの中と同じにします。ArrayList<Integer> を回すなら for (int n : list) と書けて、Integer から int への変換は Java が自動でやってくれます。
集計用の箱は、ループの外に置く
拡張 for でいちばん多い書き間違いは、集計用の変数をループの中で宣言してしまうことです。
Java
for (String name : names) {
int total = 0; // 毎回 0 に戻ってしまう
total += name.length();
}これだと 1 周ごとに total が作り直され、しかもループを抜けた時点で変数自体が消えています。足し込む先はループの前に用意して、ループの中では足すだけにします。箱は外、足し算は中、と覚えておくと間違えません。
課題では、リストを自分で作ってから拡張 for で合計を求めます。途中で println を挟んで、値がちゃんと積み上がっているか確かめながら進めてください。
要件
- メソッド内で
ArrayList<Integer>を新しく作り、5, 10, 15, 20の 4 つの値をこの順番でaddすること - 全要素の合計は 拡張 for (
for (int n : list)) を使って計算すること - 戻り値の型は
int、戻り値は50になること
入出力例
sumList() → 50