拡張 for ループ
配列を頭から全部見るだけなのに、for の丸カッコには int i = 0 と i < arr.length と i++ の 3 つを書かなければいけません。中では arr[i] と書きます。i を使いたいわけではないのに、i の面倒を全部見ている状態です。
i を書かずに要素だけ受け取る
Java には、この全部見るだけのための短い書き方があります。拡張 for です。
Java
String[] members = {"佐藤", "鈴木", "高橋"};
for (String name : members) {
System.out.println(name);
}丸カッコの中に書くのは、取り出す要素の型と名前、コロン、取り出したい配列の 3 つだけです。1 周ごとに members の要素が順番に name へ入ってきます。
同じ処理をこれまでの書き方で並べると、何が消えたのかがはっきりします。
Java
for (int i = 0; i < members.length; i++) {
System.out.println(members[i]);
}消えたのは、i の初期化、members.length との比較、i++、そして members[i] という取り出しです。書く量が減っただけではなく、< と <= を書き間違えて最後の 1 つを飛ばす定番の事故が、そもそも起こせなくなります。
変数名は name でも x でも構いませんが、item score name のように中身が分かる名前にすると、ループの本体が読みやすくなります。
添字が要る場面では使えない
拡張 for は今が何番目かを教えてくれません。前後の要素を比べたい、偶数番目だけ処理したい、見つけた位置を返したい、といった添字が要る処理は、これまでどおりの for で書きます。
受け取った変数を書き換えても、配列は変わらない
拡張 for でいちばん多い誤解がこれです。
Java
int[] prices = {100, 200, 300};
for (int p : prices) {
p = p * 2;
}
System.out.println(prices[0]); // 100 のままp に入っているのは要素のコピーです。p を書き換えても、配列の中身には何も起きません。中身を書き換えたいときは prices[i] = ... のように添字を通して代入する必要があるので、そこは通常の for の出番です。拡張 for は読むための道具だと割り切ると、迷わずに使い分けられます。
やってみよう
countEvens(int[] arr) は、配列に入っている偶数の個数を返します。繰り返しには必ず拡張 for を使ってください。
- 数えた個数を入れる変数は、ループの外で
0から始めます。中で宣言すると 1 周ごとに作り直されてしまいます - 偶数の判定は
x % 2 == 0です。-4のような負の偶数も、この式でちゃんと偶数と判定されます - 空の配列を渡すと、ループの本体が 1 度も実行されないまま
0が返ります
書けたら、同じ処理を通常の for でも書いてみてください。i を使わない処理で i を書くことがどれだけ余計か、並べると実感できます。
要件
- クラス名は
Solution、メソッド名はcountEvens、引数はint[] arr1 つ、戻り値の型はint - 繰り返しには必ず拡張 for (
for (int x : arr) { ... }の形) を使うこと - 偶数の判定は
x % 2 == 0で行うこと (負の偶数も正しくカウントされる)
入出力例
countEvens([1,2,3,4]) → 2
countEvens([5]) → 0
countEvens([2,4,6]) → 3
countEvens([]) → 0
countEvens([0,1,2,3]) → 2
countEvens([-2,-3,-4]) → 2