0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Javaのfor文、昔習った書き方と最近よく見る拡張for文を整理する

0
Posted at

Javaを最初に勉強したとき、繰り返し処理といえばまずこの形を習った。

for (int i = 0; i < projects.size(); i++) {
    Project project = projects.get(i);
    System.out.println(project.getName());
}

一方、実務やAIが生成するコードでは、こちらの形をよく見る。

for (Project project : projects) {
    System.out.println(project.getName());
}

自分が最初に習ったfor文とは見た目がかなり違う。

今回は、通常のfor文と拡張for文が何をしているのか、どんな場面で使い分けるのかを整理する。


最初に習ったfor文

まずは通常のfor文。

for (int i = 0; i < projects.size(); i++) {
    Project project = projects.get(i);
    System.out.println(project.getName());
}

1つずつ見る。

int i = 0

i を0から開始する。

i < projects.size()

i がListの要素数より小さい間、処理を繰り返す。

i++

1回処理するたびに i を1増やす。

projects.get(i)

i 番目の要素を取得する。

つまり、

0番目
↓
1番目
↓
2番目
↓
...

と、位置を自分で管理しながらListを処理している。


最近よく見る拡張for文

次の書き方は拡張for文と呼ばれる。

for (Project project : projects) {
    System.out.println(project.getName());
}

この部分、

for (Project project : projects)

は、

projectsの中から
Projectを1件ずつ取り出して
projectに入れる

という意味。

通常のfor文のように、

int i = 0

や、

projects.get(i)

を書く必要がない。


同じ処理を並べる

通常のfor文。

for (int i = 0; i < projects.size(); i++) {
    Project project = projects.get(i);
    System.out.println(project.getName());
}

拡張for文。

for (Project project : projects) {
    System.out.println(project.getName());
}

どちらも、

projectsの中にあるProjectを
順番に取り出して処理する

という点では同じ。

単純に全件を処理するだけなら、拡張for文の方が「何をしたいのか」が見えやすい。


実務でも拡張for文をよく使っていた

実務では、DBから取得したListを1件ずつ処理する場面でよく見かけた。

たとえば、

for (SourceEntity source : sourceList) {
    TargetEntity target = new TargetEntity(
        source.getId(),
        source.getName(),
        source.getStatus()
    );

    targetList.add(target);
}

これは、

sourceListから1件取り出す
↓
getterで値を取得する
↓
TargetEntityを作る
↓
targetListへ追加する

という処理。

こういった形は、実務でもかなり見慣れていた。


通常のfor文が向いている場合

拡張for文があれば通常のfor文が不要になるわけではない。

たとえば、何番目のデータなのかを使いたい場合。

for (int i = 0; i < projects.size(); i++) {
    System.out.println(
        (i + 1) + "件目:" + projects.get(i).getName()
    );
}

逆順で処理したい場合も、

for (int i = projects.size() - 1; i >= 0; i--) {
    System.out.println(projects.get(i).getName());
}

と書ける。

つまり、

インデックスを使いたい
順番を細かく制御したい
逆順に処理したい

場合は通常のfor文が分かりやすい。


拡張for文が向いている場合

一方、

for (Project project : projects) {
    System.out.println(project.getName());
}

のように、

Listの中身を
最初から最後まで順番に処理する

だけなら拡張for文が自然。

インデックスではなく、

今処理しているProject

そのものに集中できる。


AIを使うようになってからよく見るようになった

自分がJavaを最初に習ったときは、

for (int i = 0; i < list.size(); i++)

という形から入った。

そのため、AIが生成するコードで、

for (Project project : projects)

を見る機会が増えて、

「最近はこちらの書き方が主流なのかな」

と感じた。

ただ、拡張for文自体は最近登場したものではない。

AIによって新しい書き方が生まれたというより、

自分が普段使っていなかった
一般的なJavaの書き方を見る機会が増えた

という方が近い。


まとめ

自分の中ではこう整理した。

通常のfor文
→ インデックスを自分で管理する

拡張for文
→ Listから要素を1件ずつ直接受け取る

通常のfor文は、

何番目かを使いたい
順番を制御したい

場合に向いている。

拡張for文は、

Listの中身を
1件ずつ順番に処理したい

場合に向いている。

どちらが新しい、古いというより、処理の目的によって使い分けるものだった。

そして、自分が実務でよく見ていた、

for (SourceEntity source : sourceList) {
    TargetEntity target = new TargetEntity(...);
    targetList.add(target);
}

という処理は、Streamの map と対応づけるとさらに理解しやすかった。

その部分は次の記事で整理する。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?