カテゴリ: Thymeleaf 更新日: 2026/02/12

Thymeleafのeachとindexの使い方を完全ガイド!初心者でもわかるループ処理の基本

【Thymeleaf】eachのindexの使い方をわかりやすく解説
【Thymeleaf】eachのindexの使い方をわかりやすく解説

新人と先輩の会話形式で理解しよう

新人

「Thymeleafでループ処理をしたいんですが、eachってどう使うんですか?」

先輩

th:eachは、Thymeleafでリストや配列を繰り返し表示するときに使う属性だよ。」

新人

「なるほど、でもindexってのもよく見るんですけど、それは何ですか?」

先輩

「それはループの回数を取得するための機能だね。じゃあ基本から順番に見ていこう!」

1. Thymeleafとは?

1. Thymeleafとは?
1. Thymeleafとは?

Thymeleaf(タイムリーフ)は、HTMLテンプレートエンジンの一種で、Spring Frameworkと組み合わせてWebアプリケーションを開発する際によく使われます。Thymeleafを使うと、HTMLに直接データを埋め込んで、動的に表示することができます。

テンプレートファイルは.html形式で書かれ、実際のHTMLと同じように見える構造なので、デザイナーと開発者が共同作業しやすいのも特徴です。JSPに比べてモダンで見やすく、今ではSpring Bootと一緒に使われることが増えています。

今回はその中でも、リストなどを繰り返し表示する際に重要なth:eachの使い方と、インデックス(index)の取得方法について解説していきます。

2. th:each属性の役割と基本的な使い方

2. th:each属性の役割と基本的な使い方
2. th:each属性の役割と基本的な使い方

Thymeleafでは、配列やリストなどのコレクションをHTMLで繰り返し表示するために、th:eachという属性を使用します。これはJavaのfor文のような役割を持っており、非常に直感的に使えるのが特徴です。

例えば、Javaのコントローラーで以下のようなリストを渡していたとします:


@Controller
public class SampleController {
    @GetMapping("/fruits")
    public String showFruits(Model model) {
        List<String> fruits = List.of("りんご", "バナナ", "みかん");
        model.addAttribute("fruits", fruits);
        return "fruits";
    }
}

上記のfruitsリストをHTMLテンプレート上で繰り返し表示するには、次のように書きます:


<ul>
  <li th:each="fruit : ${fruits}">
    [[${fruit}]]
  </li>
</ul>

th:each="fruit : ${fruits}"の意味は、fruitsリストの要素を1つずつ取り出して、fruitという変数で使うということです。これはJavaでいうところの次のようなループ処理に相当します:


for (String fruit : fruits) {
    System.out.println(fruit);
}

このように、HTMLテンプレート内でループ処理を簡単に記述できるのがth:eachの魅力です。テンプレートがHTML構造を維持したまま動的にデータを表示できるので、初心者でも視覚的に理解しやすいです。

また、th:eachを使えば、テーブルやリストの中にたくさんのデータを表示する場合にも非常に便利です。繰り返し表示される要素に対応したHTML構造をそのまま記述することで、見た目を整えながら柔軟な表示が可能になります。

3. eachでインデックス番号を取得する方法(stat属性の説明)

3. eachでインデックス番号を取得する方法(stat属性の説明)
3. eachでインデックス番号を取得する方法(stat属性の説明)

Thymeleafのth:eachを使ってループ処理をするときに、「何番目の要素なのか」を知りたい場面があります。たとえば、連番を表示したいときや、奇数・偶数でスタイルを変えたいときなどです。

そんなときに活躍するのが、stat属性です。th:eachの中で次のように指定します:


<tr th:each="fruit, stat : ${fruits}">
  <td>[[${stat.index}]]</td>
  <td>[[${fruit}]]</td>
</tr>

このように書くことで、ループの状態情報をstatという名前で使えるようになります。上記の例ではstat.indexで現在のインデックス番号(0から始まる)を取得しています。

statは省略形ではなく、任意の名前にできます。たとえばiでもstatusでも構いません。

4. indexの使い方を具体的なコード例で解説

4. indexの使い方を具体的なコード例で解説
4. indexの使い方を具体的なコード例で解説

それでは実際に、インデックス番号を使って表形式で表示する例を紹介します。以下のようにコントローラでリストを渡しておきます:


@Controller
public class FruitController {
    @GetMapping("/fruit-list")
    public String showFruitList(Model model) {
        List<String> fruits = List.of("りんご", "バナナ", "みかん", "ぶどう");
        model.addAttribute("fruits", fruits);
        return "fruit-list";
    }
}

このリストをテンプレートで表として表示し、各行にインデックス番号を表示したい場合は、以下のように記述します:


<table border="1">
  <thead>
    <tr>
      <th>番号</th>
      <th>果物名</th>
    </tr>
  </thead>
  <tbody>
    <tr th:each="fruit, stat : ${fruits}">
      <td>[[${stat.index}]]</td>
      <td>[[${fruit}]]</td>
    </tr>
  </tbody>
</table>

stat.indexは0から始まるため、上記の表示では「0, 1, 2, 3」という番号になります。これはプログラミング的には正しいですが、ユーザーに見せるときは「1, 2, 3, 4」の方が自然ですね。その場合の対応方法は次で紹介します。

5. 0から始まるindexと1から始めたい場合の補足説明

5. 0から始まるindexと1から始めたい場合の補足説明
5. 0から始まるindexと1から始めたい場合の補足説明

Thymeleafのstat.indexは0から始まるのが標準ですが、人間の感覚では1から始まってほしいこともあります。たとえばランキングや表の連番などです。

そのような場合は、インデックスに+1をして表示すれば問題ありません。以下のように記述します:


<tr th:each="fruit, stat : ${fruits}">
  <td>[[${stat.index + 1}]]</td>
  <td>[[${fruit}]]</td>
</tr>

このように+1することで、「1, 2, 3...」と自然な連番表示になります。

なお、statで使えるプロパティはindexだけでなく、他にも色々あります。ここではよく使ういくつかを簡単に紹介しておきます。

  • index:0から始まるインデックス
  • count:1から始まる番号
  • even / odd:偶数か奇数か(boolean)
  • first / last:最初または最後の要素か(boolean)

たとえば偶数行と奇数行で背景色を変えたいときは、stat.evenstat.oddを使って分岐させることもできます。以下のようにクラスを分けることができます:


<tr th:each="fruit, stat : ${fruits}"
    th:class="${stat.odd} ? 'row-odd' : 'row-even'">
  <td>[[${stat.count}]]</td>
  <td>[[${fruit}]]</td>
</tr>

このように、th:eachstat属性を組み合わせることで、ループ処理だけでなく表示の制御も柔軟にできるようになります。Thymeleafは、初心者でもわかりやすく、拡張性も高いため、JavaのWeb開発にはとてもおすすめです。

6. th:eachでindexを使って表示する具体的なユースケース

6. th:eachでindexを使って表示する具体的なユースケース
6. th:eachでindexを使って表示する具体的なユースケース

Thymeleafのeachindexを使えば、連番付きのリストや表など、実務でもよくある表示を簡単に実装できます。ここでは、表に「番号」「名前」「備考」を表示する例を紹介します。

まず、Javaのコントローラで以下のようなサンプルデータを用意します:


@Controller
public class UserController {
    @GetMapping("/users")
    public String showUsers(Model model) {
        List<String> users = List.of("田中", "佐藤", "鈴木", "高橋");
        model.addAttribute("users", users);
        return "user-list";
    }
}

次に、HTMLテンプレート側では、インデックス番号を使って番号付きの表を表示します:


<table border="1">
  <thead>
    <tr>
      <th>番号</th>
      <th>名前</th>
      <th>備考</th>
    </tr>
  </thead>
  <tbody>
    <tr th:each="user, stat : ${users}">
      <td>[[${stat.index + 1}]]</td>
      <td>[[${user}]]</td>
      <td>-</td>
    </tr>
  </tbody>
</table>

stat.index + 1を使うことで、ユーザーには「1」から始まる自然な番号を見せることができます。こうした連番表示は、社員番号、注文リスト、テーブル一覧など、あらゆる業務アプリケーションで使われる基本パターンです。

7. よくある間違いとエラー例(indexが意図通りに動作しないケース)

7. よくある間違いとエラー例(indexが意図通りに動作しないケース)
7. よくある間違いとエラー例(indexが意図通りに動作しないケース)

初心者がth:eachindexを使うときに、よくある間違いをいくつか紹介します。

① stat属性の指定を忘れる

以下のように書いてしまうと、stat.indexが未定義となってエラーになります。


<tr th:each="user : ${users}">
  <td>[[${stat.index}]]</td>
  <td>[[${user}]]</td>
</tr>

このような場合は、2つ目の変数(status変数)を必ず指定しましょう。


<tr th:each="user, stat : ${users}">

② indexとcountを混同する

indexは0から、countは1から始まります。これを知らずにindexを使った場合、表示が「0,1,2,3...」となり、ユーザーが違和感を覚えることもあります。

人が見る画面ではcountの方が自然です。どちらを使うか意図的に選ぶようにしましょう。


<td>[[${stat.count}]]</td>  <!-- 1から始まる -->
<td>[[${stat.index}]]</td>  <!-- 0から始まる -->

③ nullのリストでループしている

コントローラでリストを渡し忘れたり、nullになっていると、テンプレートでループ処理がうまく機能しません。必ずmodel.addAttribute()でリストを渡しているか確認してください。

8. index以外のstat属性の活用例

8. index以外のstat属性の活用例
8. index以外のstat属性の活用例

Thymeleafのeachに付随するstat属性では、index以外にも便利なプロパティが用意されています。それぞれの機能を使うことで、表示にバリエーションを持たせることができます。

count(1から始まる番号)

ユーザー向けに連番を表示する場合は、stat.countを使うと便利です。+1の補正も不要なので、シンプルなコードになります。


<td>[[${stat.count}]]</td>

even / odd(偶数・奇数判定)

行の背景色を交互に変えるようなUIを作りたいときに便利です。たとえば、以下のように書くと、行によってクラスを切り替えることができます。


<tr th:each="item, stat : ${items}"
    th:class="${stat.odd} ? 'row-odd' : 'row-even'">

これにより、偶数行と奇数行で背景色を交互に表示できます。

first / last(最初・最後の判定)

リストの最初または最後の行だけに特別な装飾をしたいときに使えます。たとえば、最初の要素にだけ「新着」と表示したい場合は次のようにします:


<span th:if="${stat.first}">新着</span>

また、最後の要素で何か別の処理をしたい場合はstat.lastを活用します。

④ 複数の条件を組み合わせる

たとえば、「偶数行かつ最後の要素」だけにスタイルを適用したい場合は、th:classで複数の判定が可能です。


<tr th:each="item, stat : ${items}"
    th:class="${stat.even} and ${stat.last} ? 'highlight' : ''">

このようにeachstat属性を組み合わせることで、ループ処理に関する細かな制御が可能になります。index以外にも多彩なプロパティを活用することで、Thymeleafのテンプレートがさらに強力になります。

まとめ

まとめ
まとめ

本記事では、Thymeleafを使ったループ処理の基本として、th:each属性の役割と使い方、そしてインデックス番号を扱うためのstat属性について詳しく解説してきました。Thymeleafは、HTMLの構造を保ったまま動的なデータ表示を実現できるテンプレートエンジンであり、Spring Bootを利用したJavaのWebアプリケーション開発において非常に重要な存在です。その中でもth:eachは、リストや配列などのコレクションを画面に繰り返し表示するための中核となる機能です。

th:eachを使うことで、Java側で用意したListや配列の中身を、一つずつHTML要素として展開できます。これはJavaの拡張for文と考えると理解しやすく、テンプレート側でデータの流れを直感的に把握できる点が大きなメリットです。さらに、stat属性を併用することで、単なる繰り返し表示にとどまらず、「何番目の要素なのか」「最初か最後か」「奇数行か偶数行か」といった状態情報を簡単に扱えるようになります。

特にindexは、プログラム内部の処理順を表す際に欠かせない情報です。stat.indexは零から始まるため、プログラム的な処理には向いていますが、画面表示ではstat.countを使ったり、indexに一を足したりする工夫が必要になります。この違いを正しく理解しておくことで、ユーザーにとって自然で見やすい画面を作ることができます。また、evenやoddを使えば、表の行ごとに背景色を変えるなど、実務でよく使われる表現も簡単に実装できます。

記事内で紹介したサンプルプログラムのように、コントローラでデータを準備し、テンプレートでth:eachとstatを使って表示する流れを押さえておけば、多くの画面表示に応用できます。社員一覧、商品リスト、注文履歴、ランキング表示など、番号付きで一覧を表示する場面は非常に多く、今回学んだ内容はそのまま現場で役立つ知識です。

また、よくある間違いとして、stat属性の指定を忘れてしまったり、indexとcountを混同してしまったりするケースも紹介しました。これらは初心者がつまずきやすいポイントですが、逆に言えば、ここをしっかり理解しておけば、Thymeleafのループ処理に対する不安は大きく減ります。nullのリストを渡してしまうと表示されない点なども含め、データの受け渡しを意識することが重要です。

Thymeleafのeachとindex、そしてstat属性は、一度理解してしまえば非常に強力な武器になります。HTMLとJavaの役割分担が明確になり、テンプレートが読みやすく、保守しやすくなる点も大きな魅力です。今回の内容を振り返りながら、自分のプロジェクトに当てはめて試してみることで、理解はさらに深まっていくはずです。

まとめで振り返るサンプルプログラム

最後に、th:eachとstat.index、stat.countを組み合わせた基本的なサンプルを改めて確認しておきましょう。番号付きでリストを表示する、非常にシンプルで実用的な例です。


<table border="1">
  <thead>
    <tr>
      <th>番号</th>
      <th>名前</th>
    </tr>
  </thead>
  <tbody>
    <tr th:each="user, stat : ${users}">
      <td>[[${stat.count}]]</td>
      <td>[[${user}]]</td>
    </tr>
  </tbody>
</table>

このようにstat.countを使えば、一から始まる連番をそのまま表示でき、画面上でも違和感のない一覧表を作ることができます。用途に応じてindexとcountを使い分ける意識を持つことが大切です。

先生と生徒の振り返り会話

生徒「th:eachは何となく使っていましたけど、stat属性まで意識したのは初めてでした」

先生「多いね。最初は表示できれば満足しがちだけど、番号や状態を扱えるようになると、一気に表現の幅が広がるよ」

生徒「indexが零から始まる理由も、プログラム的には納得できました」

先生「そうそう。画面用にはcountを使う、内部処理にはindexを使う、という使い分けができると一段レベルが上がる」

生徒「偶数行と奇数行で色を変えられるのも便利ですね」

先生「実務ではかなり使うよ。eachとstatを理解できたなら、Thymeleafの基礎はしっかり身に付いたと言っていい」

生徒「これからはテンプレートを書くのが楽しくなりそうです」

先生「その調子で、実際に手を動かしながら覚えていこう」

この記事を読んだ人からの質問

この記事を読んだ人からの質問
この記事を読んだ人からの質問

プログラミング初心者からのよくある疑問/質問を解決します

Thymeleafとは何ですか?Spring Bootとどう関係がありますか?

Thymeleaf(タイムリーフ)は、HTMLテンプレートエンジンの一種で、Spring BootなどのJavaフレームワークと組み合わせてWebアプリを構築する際によく使われます。HTMLファイルに直接データを埋め込めるのが特徴で、デザイナーとエンジニアが協力しやすいという利点があります。
コメント
コメント投稿は、ログインしてください

まだ口コミはありません。

カテゴリの一覧へ
新着記事
New1
Springの基本
Spring Bootの@ConfigurationPropertiesScanとは?設定クラス自動検出の仕組みを解説
New2
SpringのAPI開発(REST & GraphQL)
Spring Boot GraphQLでResolverを理解しよう!初心者でもわかるデータ取得の基本
New3
SpringのAPI開発(REST & GraphQL)
Spring Boot GraphQL入門!Query・Mutation・Subscriptionの基本を初心者向けに解説
New4
SpringのDB操作
JPQLのパラメータバインド(:name / ?1)の使い方を完全解説!初心者でも迷わない基本の考え方
人気記事
No.1
Java&Spring記事人気No1
Thymeleaf
Thymeleaf とは?初心者向けにThymeleafの基本を徹底解説
No.2
Java&Spring記事人気No2
SpringのWeb開発(Spring MVC)
DispatcherServletの仕組みを理解する!初心者向け完全ガイド
No.3
Java&Spring記事人気No3
Springの基本
Spring Bootのデフォルトログ設定を徹底解説(Logback / SLF4J)
No.4
Java&Spring記事人気No4
SpringのDB操作
JPAの標準クエリメソッド(findById, findAll)を完全解説!初心者でもわかるデータ取得の基本
No.5
Java&Spring記事人気No5
SpringのWeb開発(Spring MVC)
Spring Bootでの@GetMappingと@PostMappingの基本を完全解説!初心者でも理解できる使い方
No.6
Java&Spring記事人気No6
Spring認証(Spring Security)
セッション管理の基本(@SessionAttributes)を完全解説!初心者でもわかるセッションの仕組み
No.7
Java&Spring記事人気No7
SpringのWeb開発(Spring MVC)
@Controller と @RestController の違いを完全解説!初心者向けSpring MVC入門
No.8
Java&Spring記事人気No8
SpringのWeb開発(Spring MVC)
ループ処理(th:each)の基本を完全ガイド!Thymeafの繰り返し処理の使い方