区分 環境情報科目
ディプロマ・ポリシーとの関係

カリキュラム・ポリシーとの関係

カリキュラム全体の中でのこの科目の位置づけ
本学修科目「環境プログラミングⅢ」は、「環境プログラミングⅠ」において修得したJava言語の基本文法および実装能力、「環境プログラミングⅡ」において修得したクラス設計とオブジェクト指向プログラミングの知識を基盤として、実践的なプログラム設計力を養成する応用段階の科目として位置づけられる。
Javaによる実務的なソフトウェア開発では、個々の機能を自前で実装するのではなく、標準APIや既存ライブラリを適切に選択・組み合わせて利用することが、開発効率の向上と品質の確保、更には保守・運用コストの低減につながる。本科目では、Java標準APIを体系的に学修することで、「何を自作し、何を再利用すべきか」を判断できる設計視点の獲得を目指す。
また、標準APIの活用は、開発作業の簡素化による労働負荷の軽減や、開発・保守工程に伴うエネルギー消費の削減にも寄与する点で、GREENSOFT Modelに準拠したサステナブル・ソフトウェア開発の重要な要素である。本科目では、文字列処理、日時処理、コレクション、並行処理などの標準APIを通して、環境配慮とソフトウェア設計を結び付けて考える力を養成する。
更に、標準APIの利用にとどまらず、ライブラリとして再利用可能なコードを自ら設計・実装する基礎を学ぶことで、実践的なソフトウェア開発へとつながる土台を形成する。

科目の目的
本科目では、Java APIに含まれる主要な標準ライブラリの用途と利用方法を体系的に学び、実務で求められる高度なプログラミング技術を段階的に習得することを目的とする。文字列処理や正規表現、日付・時刻 API、数値計算、ファイル操作などの基礎的な標準機能から出発し、それらを正確かつ効率的に扱う力を養う。単にメソッドの使い方を覚えるのではなく、「どの API を、どの場面で選択するべきか」を判断できる実践的な理解を重視する。
更に、コレクションフレームワークや列挙型、レコード、内部クラスなどの言語機能を通して、オブジェクト指向設計の応用的な考え方を身に付ける。関数型インタフェース、ラムダ式、メソッド参照、Stream APIの学習を通して、従来型の記述方法との違いを理解し、簡潔で可読性の高いコードを書ける力を育成する。また、並行処理や非同期処理の基礎を学び、複数の処理を安全かつ効率的に制御するための設計力を養う。加えて、モジュール機能やパッケージ公開の仕組みを理解し、大規模開発を想定した部品の分割と依存関係の管理について学ぶ。ロケールやリソースバンドルを用いた国際化対応、フォーマット処理を通して、利用者環境を意識した設計の重要性を理解する。更に、入力値検査やプラットフォームセキュリティなどの観点から、安全性を意識したプログラム設計の基礎を身に付ける。
本科目全体を通して、APIを単に利用するだけでなく、「保守性」「拡張性」「安全性」「可読性」を意識した設計・実装ができる応用力を育成する。最終的には、Javaの標準機能を活用しながら、実務において通用する堅牢で信頼性の高いプログラムを自ら設計・実装できる能力の獲得を目標とする。

到達目標
本科目を修了することで、以下の能力を習得することを目標とする。

1 Java API の理解と基本的な活用
 (1) Java API に含まれる主要な標準ライブラリの役割を理解し、使用例を参考にしながら活用できる。
 (2) 入出力処理、正規表現、ユーティリティクラスなどを用いて、基本的な処理を実装できる。
2 安全性を意識したプログラミング
 (1) 例外処理やアサーションの基本を理解し、その目的や利用場面を踏まえて、適切に実装できる。
 (2) ファイル操作やリソース管理の基本を理解し、安全に扱うことができる。
3 並行処理とモダンJava の基礎
 (1) スレッドや並行処理の基本的な仕組みやAPIを理解し、その用途や利用場面を踏まえて、サンプルコードをもとに簡単な並行処理を記述できる。
 (2) 関数型インタフェース、ラムダ式、ストリーム API の概要を理解し、簡単な処理に適用できる。
4 構造と可読性を意識したコード設計
 (1) クラスやメソッドの役割を意識し、読みやすいコード構造で記述できる。
 (2) 小規模なプログラムについて、処理の流れを整理しながら実装できる。

科目の概要
 本講義では、Java API を中心とした応用的なプログラミング技術を体系的に学習する。単に機能の使い方を覚えるのではなく、「どの場面で、どのAPIを選び、どのように組み合わせるか」を判断できる実践的な活用力の習得を目標とする。授業は理論解説と演習を組み合わせ、基礎的な標準ライブラリの理解から、並行処理・モジュール・セキュリティといった高度なテーマへ段階的に発展させていく。

1 標準ライブラリの理解と活用
文字列処理、正規表現、日付・時刻操作、数値処理など、業務で頻繁に利用される標準ライブラリを扱う。APIの役割や設計意図を理解し、適切に選択・活用できる力を養う。
2 コレクションとデータ構造の活用
コレクションフレームワークの構造と特性を理解し、List・Set・Map の使い分けを学ぶ。更に、スタックやキューなどのデータ構造を通じて、データの扱い方と処理効率の考え方を身に付ける。
3 オブジェクト指向構文の発展的理解
列挙型、レコード、内部クラスなどの機能を通して、クラス設計の幅を広げる。可読性・再利用性・保守性を意識した設計手法を学習する。
4 ラムダ式と Stream API による宣言的処理
関数型インタフェースやラムダ式を用いた簡潔な記述方法を理解し、Stream API によるデータ処理を実践する。従来型の記述との違いを比較しながら、より表現力の高いコーディング手法を習得する。
5 並行処理とモダンJava機能
スレッド処理、スレッドプール、非同期処理、仮想スレッドなどを扱い、複数処理を安全かつ効率的に制御する方法を学ぶ。また、アノテーションやモジュールシステムなど、現代的なJava開発に不可欠な仕組みの概要を理解する。
6 国際化と安全性を考慮した設計
ロケールやリソースバンドルによる多言語対応、フォーマット処理を通じて、利用者環境を意識した設計を学ぶ。更に、入力値検査やデータの無害化、プラットフォームセキュリティの考え方を通じて、安全で信頼性の高いプログラム設計の基礎を身に付ける。
7 総合演習による実践力の育成
複数のAPIや構文を組み合わせた応用演習を通して、仕様を読み取り、自ら設計・実装する力を養う。個々の知識を点ではなく線として結び付け、実務レベルで通用するプログラム構築力を高める。

 本講義は、Javaの標準機能を単独で理解する段階から、それらを統合して設計・実装する段階へと発展させる構成となっている。最終的には、可読性・保守性・安全性を備えた実用的なプログラムを自律的に構築できる力を養成する。

科目のキーワード
標準API、文字列処理、正規表現、日付・時刻API、数値処理、ファイル操作、コレクションフレームワーク、List/Set/Map、スタック・キュー、列挙型、レコード、入れ子クラス、関数型インタフェース、ラムダ式、メソッド参照、Stream API、マルチスレッド、排他制御、ExecutorService、非同期処理、仮想スレッド、アノテーション、リフレクション、Javaモジュール、ロケール、リソースバンドル、フォーマット、入力値検査、プラットフォームセキュリティ、セキュアコーディング
授業の展開方法
 本科目は、以下の手順で進行する。

1 理論の理解
各トピックについて、Java APIの設計思想や背景を含めて講義形式で学び、機能の目的や利用場面を理解する。
2 基本操作の確認
提示されたコードの意味を確認し、APIや構文の基本的な使い方及び動作を理解する。
3 実践的な演習
講義内容を踏まえ、演習課題を通じてコードを記述し、APIの使い分けや記述方法を体験的に習得する。
4 応用的な課題への取組
複数のライブラリや構文を組み合わせ、仕様を読み取りながら実装を行うことで、設計力と応用力を養う。
5 フィードバックと改善
作成したプログラムの動作や記述を振り返り、より適切なAPIの選択や記述方法について理解を深める。

各コマでは、理論説明と演習を連続して行う構成とし、学んだ内容をその場で確認することで知識の定着を図る。後半では、実務を意識した課題に取り組むことで、APIを活用して課題を解決する力を段階的に身に付ける。

 担当教員は、日立において長年にわたり、オペレーティング・システム、システム系ユーティリティ、金融系オンラインシステム、携帯電話ソフトウェアなど、多様なソフトウェア開発に従事してきた。本授業では、その実務経験を活かし、Javaの標準APIを単なる「ライブラリの使い方」としてではなく、「実務で再利用可能な機能群をどのように組み合わせて問題解決を行うか」という観点から指導している。
授業では、コレクションフレームワーク、文字列処理、例外処理、ファイル操作、日付時刻APIなどについて、実際の業務システムを意識した演習を多く取り入れている。例えば、「大量データを安全かつ効率的に処理するには、なぜ List や Map を使い分ける必要があるのか」「例外処理を適切に設計しないと、実運用でどのような障害につながるのか」といった点について、担当教員自身の開発経験を踏まえながら説明している。
また、担当教員は、銀行システムや公共交通機関向けシステムなど、高い信頼性が求められる開発を経験しており、「動けばよいプログラム」ではなく、「保守しやすく、安全で、読みやすいプログラム」を作る重要性を重視している。そのため授業では、APIの文法理解だけでなく、変数命名、可読性、処理分割、例外設計など、実務を見据えたコーディングスタイルについても指導している。さらに、海外プロジェクトでの経験を踏まえ、国際的な開発環境でも通用するプログラム設計の考え方についても紹介している。担当教員は、第22回目から第24回目の「コレクション・フレームワーク」、第25回目から第31回目の「オブジェクト指向構文」、第56回目から第58回目の「ローカライズ/フォーマット」、第59回目から第60回目の「セキュリティの概念」を担当し、上記を指導する。

オフィス・アワー
山浦恒央:【前期】
サステナブル・ソフトウェア論Ⅰ(ソフトウェア品質)木曜5限
環境プログラミングⅢ(標準API)月曜4限、水曜4限
【後期】木曜5限
村井浩昭:【前期】
環境プログラミングⅢ(標準API)月曜4限、水曜4限
【後期】
情報リテラシーⅡ(表計算ソフトによるデータ処理)木曜5限
神馬一博:【前期】
Web環境システム概論木曜5限
【後期】
Web環境システム開発Ⅰ(Webアプリケーションの実装)水4限・5限
Web環境システム開発Ⅱ(クライアント再度・プログラミング)木5限

科目コード UC3013
学年・期 2年・前期
科目名 環境プログラミングⅢ(標準API)
単位数 8
授業形態 演習
必修・選択 必修
学習時間
前提とする科目
展開科目
関連資格
担当教員名 山浦恒央・村井浩昭・神馬一博
主題コマシラバス項目内容教材・教具
1 Java標準APIの概要とStringクラスの基本メソッド 科目の中での位置付け 標準API学習の導入コマとして、標準ライブラリの基本概念について理解する。文字列がオブジェクトとして提供されている意味、主要メソッドの概要、APIドキュメントの参照方法を学ぶ。また、文字列処理の基礎となる メソッドを通して、Stringオブジェクトの扱い方を習得する。参照比較と内容比較の違いを正しく理解し、条件分岐やデータ判定で安全に利用できる力を身に付ける。
第1回テキスト 
第1章 「標準ライブラリ」 第1節「文字列操作」
項目1「Java標準APIの概要とStringクラスの基本メソッド」
コマ主題細目 ① Java標準APIの役割と構成 ② Stringクラスの基本的な性質 ③ Stringクラスの主要メソッドの活用
細目レベル ① Javaの標準APIを「使う前提の道具」として捉えられるようになることの理解まで。
本項目では、Javaでプログラムを書くときに、多くの機能がすでに用意されていることを知り、それを活用するという考え方を身に付けることを目標とする。授業の最初には、短いプログラムを実行し、文字を表示したり、簡単な処理を行ったりする様子を確認する。その上で、「この中には、自分で一から書いていない処理がたくさん含まれている」ことを示し、「今日はその正体を見ていく」とゴールを明確にする。
次に、もし標準APIが存在しなかったらどうなるかを考える。例えば、文字数を数える、文字をつなげる、特定の文字が含まれているかを調べるといった処理を、すべて自分で書こうとすると、コードは長くなり、間違いも増える。このような例を通して、「よく使う処理は、あらかじめ安全な形で用意されている」という標準APIの役割を実感する。
ここでは、APIの細かい構造や分類には踏み込まず、「Javaでプログラムを書くときに、最初から使える便利な道具箱」として理解できれば十分である。実習では、すでに用意されている機能を呼び出すだけで、複雑な処理が簡単に実現できることを確認し、今後の学習では「自分で考える部分」と「用意されたものを使う部分」を意識して書くことが大切であることを理解する。

② Stringクラスを使って文字列を安全に扱えるようになることの理解まで。
本項目では、Javaにおいて文字列がどのように扱われているかを学び、Stringクラスを使って文字列を操作する基本的な考え方を身に付けることを目標とする。授業の最初に、文字列を変数に代入し、画面に表示する簡単なプログラムを実行し、「文字列も特別な扱いを受けたデータである」ことを確認する。次に、数値と文字列の違いを具体例で確認する。同じように見えるデータでも、計算できるものとできないものがあり、文字列は単なる文字の並びとして扱われることを体験する。ここで、「文字列には、文字列専用の操作方法が用意されている」という考え方を示し、それをまとめたものが Stringクラスであることを説明する。
実習では、文字列をそのまま表示するだけでなく、「文字列の長さを調べる」「文字列同士をつなげる」といった基本的な操作を行う。これにより、Stringクラスは「文字を入れる箱」ではなく、「文字列を扱うための機能を持った存在」であることを理解する。また、文字列は一度作られると中身が直接書き換わらないという性質があることにも軽く触れ、後の授業で扱う処理につながる意識を持たせる。

③ Stringクラスの基本メソッドを使って文字列の情報を取り出せるようになることの理解まで。
本項目では、Stringクラスに用意されている基本的なメソッドを使い、文字列の中身に関する情報を取り出せるようになることを目標とする。最初に、完成形として、文字列の長さや一部の情報を表示するプログラムを実行し、「今日は文字列の中を調べる」と目的を明確にする。
次に、こうした情報について、メソッドを使わずに処理しようとすると、どれほど面倒になるかを簡単な例で示す。文字を一つずつ数えたり、位置を自分で管理したりする方法と比べることで、用意されたメソッドを使う意味を理解する。
実習では、文字列の長さを調べる方法や、指定した位置の文字を取り出す方法を体験する。ここでは、「必要なときに調べて使えること」が重要であることを強調する。また、メソッドを使うことで、文字列の状態を確認し、それを条件分岐や表示処理につなげられることを確認し、次回以降に学ぶ入力チェックや検索処理への橋渡しとする。

キーワード ① Java標準API Stringオブジェクト length compareTo equalsIgnoreCase
コマの展開方法 社会人講師 AL ICT PowerPoint・Keynote 教科書
コマ用オリジナル配布資料 コマ用プリント配布資料 その他 該当なし
小テスト 「小テスト」については、毎回の授業時間内に、LMS上において当該コマの小テスト(難易度表示付
復習・予習課題 ◆今回授業の復習
Javaの標準APIの役割と考え方を振り返り、Stringクラスが標準ライブラリに含まれる意味を整理する。特に、length・codePointCount・equals・compareTo などの各メソッドの違いと使い分けについて、具体例を挙げてまとめる。
◆次回授業の予習
次回は、空文字列や空白のみからなる文字列をどのように判定するかを学ぶ。isEmpty と isBlank の違いや、入力に含まれる空白文字の種類を確認し、文字列チェックの重要性を考える。

2 空文字列の判定と前後空白の除去及び検索 科目の中での位置付け 文字列を安全かつ実践的に扱うための基礎を形成する重要な項目である。文字列が空であるかどうかの判定、入力値に含まれる不要な前後空白の除去、更に特定の文字列を含むかどうかの検索といった処理を扱うが、これらはいずれも実際のプログラムにおいて一連の流れとして用いられることが多い処理である。入力された文字列に対して、まず妥当性を確認し、次に整形を行い、その後に検索や条件分岐を行うという処理の流れをまとめて学習することで、文字列処理を断片的なメソッドの暗記ではなく、実務的な処理手順として理解させることをねらいとしている。
第2回テキスト 
第1章 「標準ライブラリ」 第1節「文字列操作」
項目2「空文字列の判定と前後空白の除去及び検索」
コマ主題細目 ① 文字列の空判定の方法 ② 前後空白の除去処理 ③ 文字列検索の基本操作
細目レベル ① 本項目では、文字列が入力されていない状態をプログラムで正しく判断できるようになることの理解まで。
ユーザから受け取った文字列が「本当に入力されていると言える状態かどうか」を、プログラムでどのように判断するかを学習する。授業の最初には、完成形の簡単なプログラムを実行し、入力欄に何も入力しない場合や、スペースだけを入力した場合に、画面上でどのようなメッセージが表示されるかを確認する。ここで、日常的に使っているWebフォームやアプリの「入力してください」という表示が、プログラムの中でどのように実現されているかを具体的にイメージする。
次に、文字列の中身を確認せずに処理を進めた場合に起こる問題を確認する。たとえば、名前が入力されていないにもかかわらず「○○さん、ようこそ」と表示されてしまう例や、入力がない状態で処理を進めた結果、意図しない動作やエラーにつながる例を見ることで、「入力チェックをしないプログラムは簡単に不自然な動きをする」という感覚をつかむ。
その上で、文字が一文字も含まれていない状態を判定する方法として isEmptyを扱う。ここでは細かな定義には立ち入らず、「本当に何も入力されていないかを調べる方法」として理解する。実習では、入力が空の場合と、何か文字が入っている場合とで、処理の流れがどのように分かれるかを確認する。
続いて、見た目では何も入力されていないように見えるが、実際にはスペースだけが入っているケースを取り上げる。スペースキーを何度か押しただけの入力は、人間の目には空白にしか見えないが、プログラムにとっては「文字が入っている状態」である。このような入力を有効と判定してしまうと、実用的なアプリとしては不自然な挙動になる。そこで、空白だけの入力も「入力されていない」と判断する考え方として isBlank を扱う。
実習では、何も入力しない場合、スペースだけを入力した場合、実際に文字を入力した場合を並べて比較し、判定結果がどのように異なるかを確認する。これにより、「空かどうかを調べる」と一言で言っても、目的によって判断基準が異なることを理解し、入力内容に応じて適切な方法を選択できるようになる。

② 本項目では、入力された文字列をそのまま使うのではなく、前後の不要な空白を取り除いて扱いやすい形に整えられることの理解まで。
最初に、完成形として「整えられた文字列」を表示するプログラムを実行し、入力がきれいな形で扱われている様子を確認する。たとえば、名前の前後に余計な空白がなく、検索や表示にそのまま使える状態になっていることを確認する。
次に、空白を除去しない場合にどのような不便が起こるかを確認する。見た目では同じ「Tokyo」という文字列でも、実際には前後に空白が含まれていると、検索や比較がうまくいかないことがある。このように、空白は目に見えにくいが、プログラムの動作に大きな影響を与える要素であることを具体例を通して実感する。そこで、文字列の先頭と末尾から余分な空白を取り除く方法として trim を使い、入力を整える体験を行う。ここでは内部の仕組みよりも、「入力された文字列を信用せず、まず整える」という考え方を重視する。実際に、空白を取り除く前と後で、表示結果や判定結果がどのように変わるかを確認する。
また、trimを使った結果は新しい文字列として扱われるため、処理の中でどの値を使っているのかを意識する必要があることも確認する。演習では、元の文字列と整形後の文字列を並べて表示し、処理の流れを目で追いながら確認する。更に、空白を除去した結果、何も残らなかった場合には、前項で学んだ空判定と組み合わせて処理できることを確認する。

③ 本項目では、文字列の中に特定の言葉や記号が含まれているかを調べ、その結果を条件判断に利用できることの理解まで。
最初に、完成形として「文章の中に特定の言葉が含まれているかを判定し、結果を表示する」プログラムを実行する。例えば、文章中に特定のキーワードが含まれている場合に注意メッセージを表示するなど、身近な利用例を確認する。次に、このような検索を便利な仕組みを使わずに実装しようとすると、処理が複雑になり、間違いやすくなることを確認する。文字を一つずつ調べる方法と比べることで、検索用のメソッドを使う意味を実感する。
その上で、文字列の先頭から検索を行い、最初に見つかった位置を返す方法を使う。実習では、見つかった場合には位置を示す数値が返り、見つからなかった場合には特別な値が返ることを確認する。この結果を条件分岐に利用することで、「含まれている場合だけ処理を行う」といった安全なプログラムが書けることを体験する。
更に、同じ言葉が複数回現れる場合に、最初に見つかった位置と最後に見つかった位置を使い分ける場面も確認する。文章の中から特定の部分を切り出したり、区切り文字を基準に処理を行ったりする際に、検索結果がどのように活用できるかを具体的に示す。

キーワード ① 空文字列(empty string)空白文字(whitespace)isEmpty isBlank trim strip stripLead
コマの展開方法 社会人講師 AL ICT PowerPoint・Keynote 教科書
コマ用オリジナル配布資料 コマ用プリント配布資料 その他 該当なし
小テスト 「小テスト」については、毎回の授業時間内に、LMS上において当該コマの小テスト(難易度表示付
復習・予習課題 ◆今回授業の復習
適当な文字列を想定し、isEmptyとisBlank を用いて入力が有効かどうかを判定する。次に、stripまたはtrimを用いて文字列の前後の不要な空白を除去し、その後、indexOfまたはlastIndexOf を用いて、指定した文字列が含まれているか、またはその位置を確認するプログラムを作成する。
◆次回授業の予習
"tanaka,tarou,20,Tokyo"のように、区切り記号(カンマ)で連結された文字列が与えられたとき、それを 「人にとって読みやすく表示する」ためには、どのような整形が必要かを考える。例えば、項目ごとに意味を付けて表示する方法、区切り記号を空白や改行に置き換える方法、大文字・小文字の表記を整える方法などが考えられる。に、年齢や住所といった情報をラベル付きで表示する場合や、表示形式を変えることで読み手の理解がどのように変わるかについても検討し、複数の表示例を思い描いておく。これらを通して、文字列の整形が「情報を伝える分かりやすさ」にどのように影響するかを意識しておく。

3 文字列の整形についての概要と演習 科目の中での位置付け 文字列処理分野の導入段階から実践段階へ移行する橋渡しに位置づけられる。空文字列判定や前後空白除去といった入力の健全性確認を踏まえ、データを「人にとって読みやすい形」に整える視点を養うことを目的とする。氏名・年齢・住所などの簡易データを題材に、表示順序の工夫や区切り記号の付与を体験的に学ぶことで、後続の部分文字列取得、分割・結合、フォーマット処理へと発展する基礎的感覚を身に付ける。
第3回テキスト 
第1章 「標準ライブラリ」 第1節「文字列操作」
項目3「文字列の整形についての概要と演習」
コマ主題細目 ① 書式指定による整形出力の基本 ② 書式指定子(インデックス・幅・精度等)の指定方法 ③ ロケールを考慮した整形出力
細目レベル ① 複数の情報を「人にとって読みやすい文章」として整えて表示できるようになることの理解まで。
本項目では、名前・年齢・住所といった複数の情報を、そのまま並べるのではなく、「人が読んで分かりやすい形」に整えて表示できるようになることを目標とする。授業の最初には、完成形として、いくつかの値を含んだ自己紹介文や簡単なデータ表示プログラムを実行する。
例えば、「tanaka」「20」「Tokyo」という情報が、単に並んで表示されるのではなく、「名前:tanaka 年齢:20歳 住所:Tokyo」のように、意味が伝わる形で表示されている様子を確認する。次に、文字列を単純につなぎ合わせて表示しようとした場合に起こる不便さを体験する。値が増えるたびに「+」でつなぐコードは長くなり、どこに何が表示されるのかが分かりにくくなる。数字や文字の位置がずれたり、読みづらい文章になったりする様子を見ることで、「動いてはいるが、きれいではない表示」が実際には使いにくいことを実感する。そこで、複数の値をまとめて、一定の形で整えて表示する方法を紹介する。実習では、「ここに名前が入り、ここに年齢が入る」という“型”を用意し、その中に値を当てはめて表示する体験を行う。これにより、「文章の形」と「中に入る値」を分けて考えられるようになり、表示内容を後から修正しやすくなることを確認する。
この学習を通して、単にプログラムが動くかどうかではなく、「人にとって読みやすいかどうか」を意識して文字列を整形する感覚を身に付ける。

② 本項目では、表示の順序や揃え方を工夫し、見やすい出力を作れるようになることの理解まで。
同じ情報であっても、表示の順序や並び方を工夫することで、分かりやすさが大きく変わることを体験し、意図した見た目で文字列を表示できるようになることを目標とする。
始めに、完成形として、数値や文字がきれいにそろって表示されている例を確認する。例えば、複数人分のデータが縦に並び、数字の位置がそろっていることで、一目で比較できる様子を示す。次に、整形を行わずに表示した場合の問題点を確認する。数値の桁数が異なると表示がずれ、どこが同じ項目なのか分かりにくくなる。金額や点数の一覧がガタガタに表示される例を見て、「情報は合っているのに、読みづらい」という状態を体感する。
そこで、表示する位置や幅を意識して整える方法を使い、見た目をコントロールする体験を行う。実習では、同じデータを「整えない表示」と「整えた表示」で比べ、揃っていることがどれだけ見やすさにつながるかを確認する。また、値を表示する順番を変えたり、同じ値を別の場所に再利用したりすることで、文章や表示の自由度が高まることも体験する。
この学習を通して、「正しい値を出す」だけでなく、「読み手がどう見るか」を考えながら表示を作る意識を持ち、簡単な表や一覧を自分で整えて出力できるようになる。

③ 本項目では、数値や日時を場面に応じて分かりやすく表現できるようになることの理解まで。
数値や日時といったデータを、使う場面に合わせて分かりやすく整形できるようになることを目標とする。
最初に、完成形として、現在の日時や数値が「人が見て意味を取りやすい形」で表示されるプログラムを実行する。たとえば、日付が「2026-01-15」のように整理されて表示されたり、数値が桁区切り付きで表示されたりする様子を確認する。次に、整形を行わずに出力した場合の問題点を確認する。日時が数字の羅列として表示されたり、大きな数値が読みにくく表示されたりする例を見ることで、「データとしては正しいが、人には分かりにくい」表示が存在することを理解する。そこで、数値や日時を「どのように見せたいか」を意識して表示を整える体験を行う。実習では、同じ数値でも表示方法を変えることで印象が変わることや、日時の表示形式を変えることで用途に合った表現ができることを確認する。また、国や地域によって数値や日付の書き方が異なることにも軽く触れ、「誰に向けた表示なのか」を考える視点を持つ。
今回学習したAPIをまとめた課題演習を通して、プログラムが扱うデータを「人に伝える情報」として捉え、目的や利用場面に応じて適切な文字列整形ができる基礎的な力を身に付ける。

キーワード ① 文字列整形 書式付き出力 String.format printf 表示形式 可読性
コマの展開方法 社会人講師 AL ICT PowerPoint・Keynote 教科書
コマ用オリジナル配布資料 コマ用プリント配布資料 その他 該当なし
小テスト 「小テスト」については、毎回の授業時間内に、LMS上において当該コマの小テスト(難易度表示付
復習・予習課題 ◆今回授業の復習
Java における書式付き文字列出力について、基本から応用までを体系的に学習した。まず、String.format および System.out.printf を用いた基本的な書式付き出力を通して、書式文字列と引数の関係を理解し、文字列連結に比べて可読性の高い出力が可能であることを確認した。次に、書式指定子の構造を学び、引数インデックスや幅指定、揃え方、精度指定を用いることで、表示順序や見た目を柔軟に制御できることを理解した。更に、数値の進数表現や指数表記、日時データの書式指定、Locale による表示形式の違いを通して、用途や利用者を意識した整形出力の重要性を確認した。本コマの学習を通して、情報を分かりやすく伝えるための文字列整形の基礎的な考え方を理解する。
◆次回授業の予習
文字列入力が正しいかどうかを判定する方法や、文字列の一部を取り出す処理について学習する。私たちは日常的に、名前やメールアドレス、パスワードなど、文字列としてデータを入力するが、プログラムではその内容をそのまま使うのではなく、「空でないか」「必要な文字数があるか」「特定の文字を含んでいるか」などを確認する必要がある。そこで、入力された文字列を判定するために、どのような条件をチェックすべきかを考えておくこと。また、文字列の一部分を取り出すことで、どのような処理が可能になるかについても具体例を挙げてみる。

4 文字列入力の判定及び部分文字列の取得 科目の中での位置付け 文字列処理分野の導入段階から実践段階へ移行する橋渡しに位置づけられる。空文字列判定や前後空白除去といった入力の健全性確認を踏まえ、データを「人にとって読みやすい形」に整える視点を養うことを目的とする。氏名・年齢・住所などの簡易データを題材に、表示順序の工夫や区切り記号の付与を体験的に学ぶことで、後続の部分文字列取得、分割・結合、フォーマット処理へと発展する基礎的感覚を身に付ける。
第4回テキスト 
第1章 「標準ライブラリ」 第1節「文字列操作」
項目4「文字列入力の判定及び部分文字列の取得」
コマ主題細目 ① 文字列内容の判定(contains・startsWith・endsWith 等) ② 部分文字列の取得(substring) ③ 文字列判定と部分抽出の組合せ
細目レベル ① 本項目では、入力された文字列の中に「何が書かれているか」を調べ、その結果を条件分岐に使えるようになることの理解まで。
最初には、入力された文章に特定の言葉が含まれているかを調べ、結果によって表示を変えるプログラムを実行する。例えば、メッセージの中に「重要」という言葉が含まれていれば注意表示を出す、メールアドレスの文字列が「@」で終わっていないかを確認する、といった身近な例を示す。あわせて、Webアプリにおける入力チェックやメッセージ表示の制御など、これらのAPIが実際にどのような場面で使われているかを紹介し、その必要性を理解させる。そのうえで、「今日は文字列の中身を条件にして判断する方法を学ぶ」とゴールを明確にする。「次に、これらの判定を、メソッドを使わずに行おうとするとどうなるかについて確認する。文字を一つずつ取り出して比較する方法は、コードが長くなり、読みづらく、間違いも起こりやすい。この不便さを体感した上で、「よくある判定は、すでに用意されたメソッドを使えば簡単に書ける」ことを示す。ここで使用する主なメソッドとして、contains、startsWith、endsWithを取り上げる。
contains は「この言葉が含まれているか」を直感的に判定でき、文章チェックやキーワード検索にそのまま使えることを確認する。startsWith と endsWith は、「決まった形で始まっているか」「決まった形で終わっているか」を調べるためのメソッドであり、ファイル名や入力形式の確認など、実際のプログラムで頻繁に使われる場面を例に理解を深める。
実習では、同じ文字列に対して contains・startsWith・endsWith をそれぞれ使い、判定結果がどのように変わるかを比較する。また、indexOfを使った場合との書き方を並べて示し、「意味が伝わりやすいメソッドを選ぶと、コードが読みやすくなる」ことを確認する。これにより、文字列の判定を条件分岐に自然に組み込めるようになる。

② に自然に組み込めるようになる。
② 文字列全体ではなく、その一部分だけを取り出して利用できるようになることの理解まで。
最初に、ID文字列の一部を切り出して表示する、メールアドレスから名前部分だけを取り出す、といったプログラムを実行し、「文字列を切り分けて使う」ことを示す。次に、部分文字列を使わずに処理しようとすると、文字を一つずつ数えたり、位置を自分で管理したりする必要があり、処理が複雑になることを確認する。ここで、「位置を指定するだけで必要な部分を取り出せる」メソッドとして substringを紹介する。
実習では、substring(begin) と substring(begin, end) の使い方を体験する。特に、文字列の位置は0から始まること、endで指定した位置の文字は含まれないことを、実際の出力結果を見ながら確認する。「思った通りに切り出すには、どこを指定すればよいか」を試行錯誤しながら理解することを重視する。
また、範囲を間違えるとエラーが起こる例も示し、「安全に使うには、文字列の長さや位置を意識する必要がある」ことを確認する。ここでは例外の詳細な仕組みには踏み込まず、「無理な位置指定は危険」という感覚を持たせることを目的とする。
更に、indexOfやlastIndexOfと組み合わせることで実用的な処理ができることを示す。例えば、「@の位置を探して、その前を名前として取り出す」といった具体例を通して、部分文字列取得が現実のデータ処理に直結していることを理解させる。

③ 文字列の判定と部分文字列取得を組み合わせ、一連の入力処理として扱えるようになることの理解まで。
最初に、入力された文字列をチェックし、条件を満たした場合のみ必要な部分を取り出して表示する」プログラムを実行する。例えば、「特定の記号が含まれていない場合はエラー表示をし、含まれている場合のみ処理を進める」といった流れを確認する。
次に、判定を行わずに substringを使った場合に起こる問題を示す。条件を満たしていない入力に対して処理を進めると、エラーが発生したり、意味のない結果が出たりすることを体験し、「順番を考えて処理を書くこと」の重要性を理解する。
最後の実習では、contains や startsWith で入力内容を確認し、条件を満たした場合のみ substring で必要な部分を取り出すという流れを演習として段階的に実装する。これにより、「入力 → 判定 → 加工 → 出力」という基本的な処理の型を身に付ける。

キーワード ① 文字列判定 部分文字列 contains startsWith endsWith substring indexOf
コマの展開方法 社会人講師 AL ICT PowerPoint・Keynote 教科書
コマ用オリジナル配布資料 コマ用プリント配布資料 その他 該当なし
小テスト 「小テスト」については、毎回の授業時間内に、LMS上において当該コマの小テスト(難易度表示付
復習・予習課題 【復習・予習課題】
◆今回授業の復習
任意の文字列を用意し、contains・startsWith・endsWith をそれぞれ使って、文字列の中身を判定する簡単なプログラムを作成する。その際、「なぜそのメソッドを使うのか」を意識し、indexOf を用いた場合との違いを考えさせる。
次に、substringを用いて、開始位置、終了位置を変えたときに取得される文字列がどのように変化するかを確認し、インデックスの考え方を整理する。あわせて、範囲外の値を指定した場合にどのような問題が起こるかも調べ、安全な文字列操作の必要性を理解する。
◆次回授業の予習
次回は、区切り文字を用いた文字列の分割と結合(split・join)を扱う。「カンマ」「空白」「スラッシュ」などで区切られた文字列の具体例を3つ以上考え、それらが配列に分割されたとき、どのような要素になるかを紙に書いて整理する。特に、区切り文字が連続した場合や、先頭・末尾にある場合に何が起こりそうかを予想しておく。
次に、分割された複数の要素を再び1つの文字列として表示するには、どのような処理が必要かを考え、「人にとって読みやすい表示」にするための工夫を文章でまとめる。次回の実習に備え、処理の流れを言葉で説明できるようにしておく。

5 区切り文字による文字列分割と結合 科目の中での位置付け 前時で学習した文字列判定および部分文字列取得を基盤として、複数の情報が一つの文字列として与えられるデータを扱うための実践的な処理方法を学ぶ段階に位置づけられる。入力データには、氏名の一覧、列挙された項目、簡易的なCSV形式の文字列など、区切り文字によって意味的なまとまりが表現されている場合が多く存在する。そのような文字列を分割し、配列として内部処理した上で、必要に応じて再び結合するという一連の流れを体験的に学ぶことを目的とする。
文字列を「そのまま扱う対象」から「構造を持ったデータ」として捉える視点を養うことで、後続のコレクション処理、正規表現による高度な解析、ファイル入出力やCSVデータ処理へと発展するための基礎的感覚を身に付ける。

第5回テキスト 
第1章 「標準ライブラリ」 第1節「文字列操作」
項目5「区切り文字による文字列分割と結合」
コマ主題細目 ① 区切り文字による文字列分割(split) ② 分割結果の配列操作と反復処理 ③ 文字列の結合処理(join 等)
細目レベル ① 本項目では、1つの文字列に含まれる複数の情報を、区切り文字を使って分割し、配列として扱えるようになることの理解まで。
授業の冒頭では、完成形として「カンマ区切りの文字列を分割し、それぞれの要素を表示するプログラム」を実行する。
例えば、"tanaka,taro,20,Tokyo"のような文字列を分割し、名前・年齢・居住地といった情報を個別に扱えることを示す。あわせて、Webアプリにおけるフォーム入力データの処理やCSV形式のデータの読み取りなど、実際のシステムでどのように活用されているかを紹介し、これらのAPIが必要となる場面を理解させる。これまで学んだ substringだけでは、この処理は面倒になることを思い出させ、4コマ目とのつながりを明確にする。次に、データは1行の文字列として渡されるが、中身は複数の情報で構成されているという現実的な場面を提示する。CSV形式や簡単な入力データを例に挙げ、「分割できなければ、データを正しく扱えない」ことを確認する。
ここで、文字列を分割するための基本メソッドとして splitを導入する。splitは、どこで区切るかを指定するだけで、文字列をString配列に変換できるメソッドであることを説明する。難しい理論には立ち入らず、「区切り文字を指定すると、バラバラにして配列にしてくれる」と直感的に理解させる。
カンマ、空白、スラッシュなど、異なる区切り文字を指定して splitを実行し、配列の中身がどのように変わるかを実習を通して確認する。また、分割結果が配列であることから、length を使って要素数を確認するなど、配列との関係も自然に復習する。

②  split によって得られた配列を、繰り返し処理の中で利用できるようになることの理解まで。
最初に、分割した文字列を1つずつ処理する完成例を示す。例えば、名前・年齢・住所といった各要素を順に表示したり、形式を整えて出力したりするプログラムを実行する。
次に、「配列にしただけでは意味がなく、それをどう使うかが重要である」ことを確認する。ここで、拡張for文や通常のfor文を使って、配列の要素を順に処理する流れを復習する。文字列処理と配列・繰り返し処理が結び付く場面であることを強調する。
実習では、split の結果を for 文で回し、各要素に対して trim を適用したり、表示形式を変えたりする演習を行う。これにより、「文字列処理は単独で完結するのではなく、制御構造と組み合わせて使われる」ことを体験的に理解させる。
また、期待した数の要素が得られなかった場合についても触れる。入力データが不完全な場合、配列の長さが想定と異なることがあることを示し、「処理を書く前に、データの形を確認する必要がある」という意識を持たせる。例外処理の詳細には踏み込まず、考え方の導入にとどめる。

③  split による分割と join による結合を組み合わせ、文字列を加工して再構成できるようになることの理解まで。
冒頭では、「分割した文字列を加工した後、再び1つの文字列にまとめる」という完成例を提示する。例えば、不要な空白を除去したうえで、区切り文字を変更して表示する、といった処理を示す。
ここで、文字列を結合する方法として String.joinを紹介する。join は、「区切り文字」と「配列(または複数の文字列)」を指定することで、整った1つの文字列を生成できるメソッドであることを説明する。"+" 演算子による結合と比較し、「要素が多い場合には joinの方が意図が伝わりやすい」ことを確認する。
最後に実習では、split → 加工 → join という一連の流れを課題演習として実装する。例えば、入力文字列を分割し、各要素を確認・整形したうえで、別の形式の文字列として出力する演習を行う。この流れを通して、「文字列は分けて終わりではなく、再構成して使うもの」であることを理解させる。



キーワード ① 文字列分割 split String.join 区切り文字 文字列加工
コマの展開方法 社会人講師 AL ICT PowerPoint・Keynote 教科書
コマ用オリジナル配布資料 コマ用プリント配布資料 その他 該当なし
小テスト 「小テスト」については、毎回の授業時間内に、LMS上において当該コマの小テスト(難易度表示付
復習・予習課題 ◆今回授業の復習
任意の区切り文字を含む文字列を複数用意し、split メソッドを用いて分割結果がどのような配列になるかを確認する。その際、区切り文字を固定文字列として指定した場合と、正規表現を用いて複数の区切り文字を指定した場合とで、結果がどのように変化するかを比較する。また、第2引数 limitの値を変えたときに、配列の要素数や最後の要素の内容がどのように変わるかを確認し、分割数を制御する意義を整理する。
あわせて、分割した配列を join メソッドで再結合し、区切り文字を変更することで出力形式がどのように変化するかを確認し、分割と結合が一連の処理として成り立っていることを理解する。
◆次回授業の予習
次回は、数値や変数の値をもとに文字列を組み立てる「文字列フォーマットとテンプレート表現」を学習する。これまでに学んだ「文字列の連結(+演算子)」を用いた表示方法について、変数の数が増えるとコードがどのように読みにくくなるかを、簡単な例を自分なりに考えて整理しておくこと。あわせて、String.formatや printfで用いられる書式指定(%s、%d、%.1f など)が、どのような場面で有効であるかを調べ、数値や文字列を「見やすい形」で表示する必要性について考えておくこと。更に、Java 21で導入された文字列テンプレートでは、変数や式を文字列中に直接埋め込める点に注目し、従来の方法と比べてどのような利点があるかを意識したうえで次回の授業に臨むこと。

6 文字列を「組み立てて表示する」ための設計とAPI活用 科目の中での位置付け 本コマは、これまでに学習してきた文字列判定、部分文字列取得、分割・結合といった操作を踏まえ、それらの結果を人にとって読みやすい形で表示することに焦点を当てる段階に位置づけられる。第4・第5コマまでは、「入力された文字列をどう扱うか」「必要な情報をどう取り出すか」が中心であったが、本コマでは、その情報をどのような形で画面に出すと分かりやすいかを考える。
実際のプログラムでは、内部で扱うデータの形と、画面や帳票に表示する文字列の形は一致しないことが多い。そこで、処理用データと表示用文字列を意識的に分けて考える視点を身に付け、プログラムの見通しを良くするための基本的な設計感覚を養う。

第6回テキスト 
第1章 「標準ライブラリ」 第1節「文字列操作」
項目6「文字列を“組み立てて表示する”ための設計とAPI活用」
コマ主題細目 ① 文字列連結と書式指定による出力構成 ② 処理データと表示文字列の分離設計 ③ 文字列テンプレートの概念
細目レベル ①  本項目では、複数の情報を含むデータを、意味が伝わる文章や表示形式として組み立てられるようになることの理解まで。
最初に、氏名・年齢・住所といった複数の値を含むデータを、整った文章として表示するプログラムを実行する。例えば、”tanaka,20,Tokyo”という情報が、「名前:tanaka 年齢:20歳 住所:Tokyo」のように表示される様子を確認する。し、あわせて、Webアプリにおけるユーザー情報の表示や入力データの整形といった実例を示し、これらの処理の背後で授業で扱うAPIがどのように活用されているかを説明する。そのうえで、「今日はこの表示を自分で作る」と指標を明確にする。
次に、これを単純な文字列連結(”+”演算子)だけで書こうとした場合のコードを示す。値が増えるにつれて式が長くなり、どこに何が表示されるのか分かりにくくなる様子を見て、「動いてはいるが、読みづらいコード」になりやすいことを体感する。そこで、書式を決めて値を当てはめるという考え方を導入し、String.formatや System.out.printf を使った表示方法を扱う。
ここでは、細かな書式指定の暗記は求めず、”%s”は文字列を入れる場所、”%d” は数値を
入れる場所といった最低限の理解にとどめ、「文章の型」と「中に入る値」を分けて考えられるようになることを重視する。
実習では、同じデータを「文字列連結で表示した場合」と「String.formatを使って表示した場合」で比較し、後者の方が修正や再利用がしやすいことを確認する。これにより、「表示を組み立てる」という発想を身に付ける。

② プログラム内部で扱うデータと、画面に表示する文字列を意識的に分離して考えられるようになることの理解まで。
  最初に、CSV形式の文字列をsplitで分割し、配列として保持したうえで、その内容を整えて表示する完成例を示す。ここで、「配列の中身そのものを表示する」のではなく、「表示用に組み立てた文字列を出力している」点に注目させる。次に、処理と表示を分けずに書いた例を示し、コードが読みにくくなったり、表示形式を変えたいときに多くの修正が必要になったりことを確認する。これにより、「とりあえず表示できる」書き方と、「後から直しやすい」書き方の違いを意識させる。
実習では、「文字列を分割して配列や変数に格納する→必要な順序・表現を考える→表示専用の文字列を組み立てる」という流れでコードを書く。このとき、「どこまでが処理で、どこからが表示か」をコメントで区別させ、設計上の役割分担を言葉として説明できるようにする。

③  将来の発展として、文字列を組み立てるための新しい考え方が存在することを知ることの理解まで。
これまで、文字列連結や String.format、printf を用いて、表示用の文字列を組み立ててきた。これらはいずれも現在でも広く使われている方法であり、基本としてしっかり身に付けておく必要がある。一方で、プログラムが長くなり、扱う変数や式が増えてくると、どの値がどこに入るのかが分かりにくくなる場面も出てくる。
  そこで本項目では、Java には文字列をより直感的に組み立てるための新しい考え方が導入されていることを紹介する。具体的には、文字列の中に変数や式をそのまま埋め込むという発想があり、これにより表示内容とコードの対応関係が分かりやすくなることを確認する。
授業では、従来の書き方と、新しい書き方の例を並べて示し、「何が読みやすいか」「どこが分かりやすいか」を学生自身に比較させる。ここでは、詳しい文法や仕様を覚えることは求めず、「文字列を組み立てる方法にも進化がある」「目的に応じて表現方法を選べる」という視点を持つことを重視する。学生が「とりあえず動く表示」を書く段階から、「後から読んでも意味が分かる表示」を意識する段階へ進むことをねらいとし、次回以降に扱う正規表現や高度な文字列処理への足掛かりとする。

キーワード ① 文字列連結 書式付き出力 String.format printf 表示用文字列 可読性
コマの展開方法 社会人講師 AL ICT PowerPoint・Keynote 教科書
コマ用オリジナル配布資料 コマ用プリント配布資料 その他 該当なし
小テスト 「小テスト」については、毎回の授業時間内に、LMS上において当該コマの小テスト(難易度表示付
復習・予習課題 ◆今回授業の復習
任意のCSV形式の文字列を用意し、splitメソッドで分割した後、String.format または printf を用いて、人にとって読みやすい文章形式で出力するプログラムを作成する。その際、処理用のデータと表示用の文字列を分けて考え、どの部分が「整形」に該当するのかを意識する。
あわせて、文字列連結と書式指定のどちらが読みやすいかを比較し、それぞれの利点と注意点を整理する。
◆次回授業の予習
次回は、これまでに学習してきた文字列判定、部分文字列取得、分割・結合、書式指定による整形出力を総合的に用いて、与えられた文字列データを解析し、分かりやすく表示する演習を行う。
そこで予習として、次のような文字列を一つ考えること。
例:「suzuki,ichiro,1998/4/12,Tokyo」
このように複数の情報が区切り文字で連結された文字列を想定し、①どのように分割すればよいか、②各要素をどのように判定・加工すればよいか、③最終的にどのような表示形式に整えると「人にとって読みやすいか」を文章で整理しておくこと。

7 文字列解析と整形出力の総合演習 科目の中での位置付け 学習してきた文字列処理に関する知識と技能を総合的に活用し、与えられた文字列データを解析し、意味を抽出し、人にとって読みやすい形式で整形して出力することを目的とした総合演習に位置づけられる。 これまでは、標準APIの位置づけ理解、文字列の比較や判定、検索、部分文字列の取得、分割と結合、書式指定による整形出力といった要素を段階的に学習してきたが、本コマではそれらを個別の知識としてではなく、一連の処理の流れとして統合的に扱う。特に、実務的なプログラムでは「入力された文字列をそのまま表示する」ことはほとんどなく、入力値の妥当性確認、不要な部分の除去、意味のある単位への分解、必要な情報の抽出、そして最終的な表示形式への整形という複数の工程を経て処理が行われる。そのような実践的な処理の流れを演習を通して体験させることで、文字列処理が単なる文法事項ではなく、設計力や読解力と密接に関わる重要なテーマであることを理解させることをねらいとする。
第7回テキスト 
第1章 「標準ライブラリ」 第1節「文字列操作」
項目7「文字列解析と整形出力の総合演習」
コマ主題細目 ① 文字列の調査・検索・判定処理 ② 部分取得・分割によるデータ分解 ③ 整形出力までの一連処理
細目レベル ①  与えられた文字列をそのまま使うのではなく、「この文字列は今、どんな状態なのか」「この先の処理に進んでよいのか」を自分で判断できるようになることの理解まで。
授業の最初には、文字列データを受け取り、条件に応じて処理を分けるプログラムを実行する。例えば、入力されたメッセージの内容によって表示を変えるといった身近な例を示す。更に、Webアプリでの入力判定などの実用例にも触れ、これらのAPIの必要性を理解させる。名前やデータが正しく入力されていない場合には処理を止め、問題がなければ次の解析に進む、といった動きを確認する。「今日は、文字列をいきなり分解するのではなく、その前に“調べる”ところから始める」という位置づけを明確にする。次に、文字列の状態を確認せずに処理を進めた場合に起こる問題を示す。空の文字列に対して処理を行おうとしてエラーが起きたり、想定外の内容が表示されたりする例を見ることで、「文字列解析の最初の一歩は、必ず状態確認から始まる」という感覚を持たせる。
それらを踏まえて、文字列の内容が同じかどうかを調べる方法を扱う。大文字・小文字を区別する場合としない場合で、判定結果がどのように変わるかを具体例で確認し、「人が見て同じに感じるか」と「プログラムが同じと判断するか」は必ずしも一致しないことを理解する。また、文字列の長さを調べることで、「短すぎる」「長すぎる」といった不正な入力を見つけられることも確認する。
更に、特定の語句が含まれているか、決まった文字で始まっているか、終わっているかを調べる方法を用い、文字列の中身を大まかに把握する体験を行う。ここでは、「完全に一致しているかどうか」ではなく、「条件を満たしているかどうか」を調べるための道具として、これらのメソッドを使うことを意識させる。
実習を通して、文字列解析は「分割や切り出し」から始まるのではなく、「今、この文字列を扱ってよいかを確認するところから始まる」という基本的な流れを理解し、後続の処理に安全につなげられるようになることを目指す。

②  1つの文字列の中に複数の情報が含まれている場合に、それを意味のある単位に分解して扱えるようになることの理解まで。
最初に、区切り文字を含む文字列データを受け取り、名前・日付・住所などの情報を個別に取り出して表示するプログラムを実行する。ここで、「1行の文字列の中に、実は複数の意味のある情報が入っている」ことを視覚的に確認する。次に、分解の仕組みを使わずに処理しようとした場合の例を示す。文字の位置を数えながら切り出そうとすると、コードが分かりにくくなり、少し形式が変わるだけで正しく動かなくなることを確認する。これにより、「文字列を力ずくで扱う」方法の限界を実感させる。
その上で、文字列の一部分を取り出す方法として、位置を指定して切り出す操作を扱う。どこからどこまでを取り出すのかを意識することで、「文字列には位置という考え方がある」ことを再確認する。ただし、細かな数値の暗記は目的とせず、「指定した範囲だけを取り出せる」という感覚をつかむことを重視する。
続いて、区切り文字を基準に文字列を分割する方法を扱う。カンマやスラッシュなど、見た目で分かりやすい区切りを使い、分割後に配列としてデータを扱えることを確認する。分割結果の要素数や順序を確認することで、「思っていた形に分かれているか」を自分でチェックする姿勢を身に付ける。
更に、単純な分割では対応しにくい場合には、検索と切り出しを組み合わせることで柔軟な解析ができることを紹介する。これにより、「splitだけで何でもできるわけではないが、組み合わせることで対応できる範囲が広がる」ことを理解する。

③  解析・分解した文字列データを、人にとって意味が伝わる形に整えて表示できるようになることの理解まで。
最初に、分解したデータをラベル付きで整形し、見やすく表示するプログラムを実行する。同じデータでも、表示の仕方によって理解のしやすさが大きく変わることを確認し、「最後の仕上げとしての整形出力」の重要性を意識させる。次に、文字列を単純に”+”でつなげた場合の表示例を確認し、要素が増えるにつれてコードも表示も分かりにくくなることを再確認する。これにより、「動くが読みづらいコード」と「整理されたコード」の違いを意識させる。
その上で、文字列を組み立てるための方法として、繰り返し処理に適した仕組みや、書式を決めて値を当てはめる方法を用いた整形出力を行う。ここでは効率や内部構造の詳細には踏み込まず、「何を使うと、どんな場面で書きやすくなるか」という実感を重視する。
まとめの演習として、解析したデータを文章として整理まとめ直したり、複数行に分けて表示したりすることで、「情報を伝えるための出力」を自分で設計する体験を行う。同じデータを別の形式で表示し直すことで、表示形式が目的に依存することを理解させる。



キーワード ① 文字列解析  判定処理(isEmpty・isBlank・equals) 検索処理(contains・indexOf) 分割処理(split) 整形出力(String.format)
コマの展開方法 社会人講師 AL ICT PowerPoint・Keynote 教科書
コマ用オリジナル配布資料 コマ用プリント配布資料 その他 該当なし
小テスト 「小テスト」については、毎回の授業時間内に、LMS上において当該コマの小テスト(難易度表示付)
復習・予習課題 ◆今回授業の復習
区切り文字で連結された文字列(例:「suzuki,ichiro,1998/4/12,Tokyo」など)を一つ選び、空判定・検索・分割・部分文字列取得・整形出力をすべて含むプログラムを作成する。各処理がどの段階で必要になるのかを意識し、処理の流れを文章で説明できるように整理する。
◆次回授業の予習
次回は、正規表現を用いた文字列処理を、より実践的な場面で活用する演習に取り組む。予習として、身近なデータの中にどのような「文字列パターン」が存在するかを意識して観察しておくこと。例えば、郵便番号、電話番号、メールアドレス、URLなどが、どのような共通構造を持っているかを考え、それを正規表現で表すとしたらどのような記述になるかを想像してみる。

8 正規表現の基本構文とパターンマッチ 科目の中での位置付け 本コマは、これまでに学習してきた文字列判定、検索、分割、整形といった処理を一段階発展させ、「あいまいな文字列パターン」を扱うための基礎技術である正規表現を導入する位置づけにある。文字列を単なる固定的な値としてではなく、「一定の規則性を持った集合」として捉える視点を養い、入力チェック、抽出、置換といった実務的な文字列処理への橋渡しを行う。
特に、郵便番号・電話番号・URL・メールアドレスなど、形式は決まっているが内容が一定でないデータを扱う場面を想定し、正規表現が持つ表現力と有効性を理解することで、後続の文字列解析やデータ処理演習につながる基礎的素養を身に付けることを目的とする。

第8回テキスト 
第1章 「標準ライブラリ」 第2節「正規表現」
項目1「正規表現の基本構文とパターンマッチ」
コマ主題細目 ① 正規表現の基本構文 ② パターンマッチによる文字列判定 ③ Javaにおける正規表現の利用
細目レベル ①  正規表現とは何かを感覚的に理解し、「決まった形をもつ文字列」を一つのルールとして表せるようになることの理解まで。
最初に、郵便番号や電話番号が正しい形式かどうかを判定する簡単なプログラムを実行する。「この授業では、こうした入力チェックを一行で書けるようになります」という目標を最初に示す。次に、正規表現を使わずに同じ判定を行おうとした場合の例を見る。例えば、文字数を調べ、特定の位置にハイフンがあるかを確認し、数字かどうかを一文字ずつ調べる、といった処理を if 文で書くと、コードが長くなり、読みづらくなることを確認する。ここで、「形式をチェックする処理は、手作業で書くと大変になりやすい」という問題意識を持つ。
その上で、正規表現は「文字の並び方のルール」をまとめて表すための記法であることを説明する。まずは、数字の集まり、英字の集まりといった基本的な考え方から入り、「0〜9のどれか1文字」「英字が何文字か続く」といった条件を一つの表現で書けることを確認する。
実習では、数字だけからなる文字列や、英字と数字が混ざった文字列などを用意し、どのような文字列が条件に合い、どのような文字列が合わないのかを実際に確かめる。
あわせて、「何文字分繰り返すのか」を指定する考え方にも触れ、記号の違いによってマッチする範囲が変わることを体験的に理解する。ここでは暗記を目的とせず、「書き方を少し変えるだけで、許される文字列の範囲が変わる」という感覚をつかむことを重視する。

②  正規表現と文字列が「一致する」とはどういう状態なのか、及び入力チェックに利用できるようになることの理解まで。
入力された文字列が「正しい形式かどうか」を判定し、結果を画面に表示するプログラムを実行する。学生は、正しい形式の入力と、少しでも条件から外れた入力とで、結果がどのように変わるかを確認する。次に、正規表現を使わずに同様の判定を行った場合に、条件分岐が増え、修正が難しくなる例を見る。例えば、形式が少し変わっただけでコード全体を書き直す必要があることを示し、「形式のルールをコードにばらばらに書く危険性」を理解する。その上で、正規表現を使うと、「この形に合っているかどうか」という判断を一つの条件としてまとめられることを説明する。ここでは、「正規表現は特定の1つの文字列を判定するためのものではなく、同じ構造をもつ複数の文字列をまとめて扱うためのもの」であることを強調する。
実習では、正しい形式の文字列と、よくある間違いを含む文字列を複数用意し、どこが条件から外れているのかを確認することで、判定の仕組みを理解する。更に、文字列の先頭や末尾を意識した条件指定を行うことで、「一部分だけ合っている」場合を除外できることを確認し、入力チェックとしての正確さが高まることを体験する。

③  Javaにおいて正規表現を用いた判定処理を実際に書き、動作を確認できるようになることの理解まで。
正規表現を用いて入力文字列を判定するプログラムを実行し、「この書き方で正しいかどうかを判断できます」という全体像を示す。
次に、コードを少しずつ書きながら、正規表現と判定処理がどのように結び付いているかを確認する。ここでは、難しい仕組みの説明は行わず、「正規表現で条件を表し、その条件に合っているかを true / false で受け取る」という流れを理解することを重視する。
実習では、正しい入力と誤った入力を与え、結果がどのように変わるかを実際に確かめる。また、Java では「\」が特別な意味をもつため、正規表現を書く際には記述に注意が必要であることを、具体例を通して確認する。ここでは理由の詳細よりも、「Javaではこう書く必要がある」という実用的な理解を優先する。

キーワード ① 正規表現(Regular Expression) 文字クラス・量指定子・位置指定 String.matches Pattern クラス Pattern.matches
コマの展開方法 社会人講師 AL ICT PowerPoint・Keynote 教科書
コマ用オリジナル配布資料 コマ用プリント配布資料 その他 該当なし
小テスト 「小テスト」については、毎回の授業時間内に、LMS上において当該コマの小テスト(難易度表示付
復習・予習課題 ◆今回授業の復習
郵便番号、電話番号、簡単なIDなど、形式が決まっている文字列を2つ以上想定し、それぞれについて正規表現パターンを考える。次に、その正規表現を Pattern.matches または String.matches を用いて判定する簡単なプログラムを作成し、マッチする場合としない場合の挙動を確認する。特に、「なぜその正規表現で判定できるのか」を言葉で説明できるように整理する。
◆次回授業の予習
正規表現を用いることで、「文字列の中から必要な情報だけを取り出す」「不要な部分を除去する」といった処理が可能になる。掲示板投稿や文章データを例に、メールアドレスやURLだけを抽出したい場合、どのような条件指定が必要になりそうかを考え、正規表現がどのような場面で役立つかを具体的にイメージしておく。

9 正規表現による文字列検索 科目の中での位置付け これまでに学習してきた文字列判定・分割・整形といった処理を踏まえ、「条件に合致する文字列を検索し、必要な情報を抽出する」という、より高度で実践的な文字列処理を扱う段階に位置づけられる。前コマまででは、String クラスのメソッドを中心に、位置指定や分割による解析を行ってきたが、本コマでは、正規表現を規則として用い、複数の候補から目的の文字列を柔軟に検索、取得する方法を学習する。
特に、Pattern/Matcher クラスを利用することで、単なる真偽判定にとどまらず、マッチした文字列の位置情報や部分要素(グループ)を取り出せる点に注目し、入力チェックやログ解析、データ抽出など、実務的な場面に直結する処理へと発展させることを目的とする。

第9回テキスト 
第1章 「標準ライブラリ」 第2節「正規表現」
項目2「正規表現による文字列検索」
コマ主題細目 ① 正規表現による形式一致判定 ② matchesメソッドによる基本検索 ③ Pattern・Matcherによる検索処理
細目レベル ①  文字列が特定の形式に一致しているかを判定できるようになることの理解まで。
文字列が含まれているか」ではなく、「文字列全体がある形になっているか」を判定したい。初めに、メールアドレスや電話番号のような文字列を入力し、「正しい形式です」「形式が正しくありません」と表示するプログラムを実行する。ここで、「今日は“中身を探す”のではなく、“形をチェックする”」という視点を明確にする。次に、これまで学んだcontainsやindexOfを使って同じ判定をしようとした場合の問題点を確認する。例えば、「@ が含まれている」「. が含まれている」だけでは、abc@や @testのような不自然な文字列も通ってしまうことを示し、「部分的なチェックでは限界がある」ことを体感する。また、実際に住所登録の場面でどのような用途で使用されているか、補足を行う。
そこで、「文字の並び方そのものを条件として書ける仕組み」として正規表現を紹介する。ここでは理論的な説明は行わず、「文字列のルールをまとめて書ける方法」として捉えられれば十分である。
実習では、数字だけからなる文字列、英字と数字が混ざった文字列などを例に、形式判定の考え方に慣れる。

②  matchesを用いて正規表現による判定ができるようになることの理解まで。
Stringクラスが提供する matchesメソッドを使い、正規表現による判定を最もシンプルな形を体験する。
まず、「文字列が指定した形式に完全に一致しているかを判定する」プログラムを実行する。ここで、matchesは「含まれているか」ではなく、「最初から最後まで一致しているか」を調べるメソッドであることを、結果を見ながら理解させる。次に、正規表現を使わずに同様の判定を行おうとすると、条件分岐が増え、コードが読みにくくなる例を示す。これにより、「短く書けること」だけでなく、「意図がはっきり伝わる」という正規表現の利点を実感させる。
実習では、「数字だけで構成されているか」「 英字と数字の組み合わせか」「決まった文字数になっているか」といった条件をmatchesを使って判定する。ここでは、「条件を1行でまとめて書ける」という感覚を身に付けることを重視する。

③  PatternとMatcherを用いた検索処理の流れの理解まで。
「一度決めて、何度も使う」場合の正規表現の基本的な書き方を理解することを目標とする。
最初に、同じ正規表現を使って複数の文字列をチェックするプログラムを実行し、「毎回 matchesを書く方法」との違いを確認する。次に、Patternが「正規表現そのものを表すオブジェクト」、Matcherが「実際に文字列と照合する役割」であることを、処理の流れに沿って説明する。ここではクラス設計の詳細には踏み込まず、「準備 → 照合 → 結果確認」という流れを理解できれば十分である。
  まとめとして、「正規表現をPatternとして用意する→Matcherを作成する→一致するかどうかを判定する」という基本的な手順を体験する。これにより、「正規表現を部品として使い回すことができる」ことを理解し、次回以降の応用的な検索処理への足掛かりとする。

キーワード ① 正規表現 matches Pattern Matcher 形式判定
コマの展開方法 社会人講師 AL ICT PowerPoint・Keynote 教科書
コマ用オリジナル配布資料 コマ用プリント配布資料 その他 該当なし
小テスト 「小テスト」については、毎回の授業時間内に、LMS上において当該コマの小テスト(難易度表示付
復習・予習課題 ◆今回授業の復習
任意の文字列について、matchesを用いて形式判定を行うプログラムを作成する。次に、同じ正規表現をPatternとMatcherを使って判定した場合のコードを書き比べ、処理の流れがどのように変わるかを整理する。
◆次回授業の予習
正規表現を用いて「入力が正しい形式かどうか」を判定する場面を想定し、メールアドレス、パスワード、社員番号など、形式チェックが必要になりそうな文字列の例を3つ以上挙げる。それぞれについて、「どのような規則で表現できそうか」を言葉で整理しておく。

10 正規表現による文字列検索演習 科目の中での位置付け 本コマは、第8コマで学習した正規表現の基本概念および matches メソッドによる完全一致判定、第9コマで学習した Pattern/Matcher クラスを用いた文字列検索と抽出処理を踏まえ、それらを総合的に活用する演習回として位置づけられる。
これまでの学習では、正規表現の構文理解やAPIの役割把握を中心に扱ってきたが、本コマでは「どの正規表現を、どのAPIと、どのオプションで用いるか」を自ら判断しながら、実際の文字列データを対象に検索処理を構成する力を養うことを目的とする。
特に、matches による完全一致判定と、Pattern/Matcher+find による部分一致検索の違いを明確に意識させ、入力チェックと情報抽出という異なる目的に応じた使い分けができるようにする。

第10回テキスト 
第1章 「標準ライブラリ」 第2節「正規表現」
項目3「正規表現による文字列検索演習」
コマ主題細目 ① matches と Pattern/Matcher の使い分け ② 検索モードによる動作の違い ③ 検索目的に応じた正規表現とAPIの選択
細目レベル ①  正規表現を用いた「判定」と「検索」の違いを使い分けられるようになることの理解まで。
最初にデモサンプルを例示し実用目的について説明し、二つのプログラムを実行する。一つは、入力された文字列が「正しい形式かどうか」を判定するプログラム、もう一つは、文章の中から条件に合う文字列をすべて取り出して表示するプログラムである。ここで、「本時は、正しいかどうかを調べる場合と、探し出す場合の違いをはっきりさせます」という授業のゴールを最初に示す。次に、同じ正規表現でも、matchesを使った場合と、Pattern/Matcher を使った場合とで、結果がどのように変わるかを確認する。matches は文字列全体が条件に合っているかを判定するため、入力チェックに向いていることを、実行結果を通して理解させる。一方で、文章の一部に条件に合う文字列が含まれていても、matchesでは検出できないことを確認し、「目的に合わないメソッドを使うと、正しく動かない」という問題を実感させる。
その上で、Pattern/Matcher を用いることで、文章の途中に現れる条件一致部分を探し出せることを示す。ここでは、「正規表現が合っているかどうか」よりも、「どのAPIを使うかで、意味が変わる」という点に意識を向けさせる。
入力チェックとしての matches、情報抽出としての Pattern/Matcher を実際に書き分けることで、「同じ正規表現でも役割が違う」という理解を確かなものにする。

②  findとgroupを用いて、文章中から必要な情報を取り出せるようになることの理解まで。
本項目では、Pattern/Matcher を使った「検索」の具体的な使い方を演習を通して確認する。
まず、1つの文章の中に複数回現れる条件一致文字列をすべて取り出して表示するプログラムを実行する。ここで、「1回だけでなく、見つかる限り何度も処理できる」ことを確認し、正規表現検索の実用的な場面をイメージさせる。次に、findメソッドを while文と組み合わせることで、複数の検索結果を順番に処理できることを確認する。ここでは、構文の暗記を目的とせず、「find は“次があるか”を調べる役割を持っている」という感覚をつかむことを重視する。また、`group` を使うことで、「見つかった文字列そのもの」を取り出せることを確認し、検索結果を画面に表示したり、別の処理に渡したりできることを理解する。
更に、文章データやログのような文字列を例に、「どの部分を取り出したいのか」を意識しながら正規表現を書く。これにより、「正規表現は書くこと自体が目的ではなく、必要な情報を取り出すための手段である」という意識を持たせる。

③  同じ正規表現でも、検索モードによって結果が変わることの理解まで。
最初に、大文字と小文字を区別しない検索を行うプログラムを実行し、入力の表記ゆれを気にせず検索できる利点を確認する。ここでは、「正規表現を複雑に書かなくても、設定を変えるだけで対応できる」ことを理解させる。次に、改行を含む文字列を対象に、検索モードの有無によって結果がどう変わるかを確認する。複数行の文章を一つのデータとして扱う場面を想定し、「1行ずつ見る場合」と「全体をまとめて見る場合」とで、考え方が変わることを整理する。
実習では、検索モードを切り替えながら同じ正規表現を使い、結果を比較する。これにより、「正規表現は固定されたルールではなく、目的に合わせて調整できる検索条件である」ことを理解し、次回扱う置換や分割処理へのつながりを意識させる。

キーワード ① 正規表現 matches Pattern Matcher find group 検索モード
コマの展開方法 社会人講師 AL ICT PowerPoint・Keynote 教科書
コマ用オリジナル配布資料 コマ用プリント配布資料 その他 該当なし
小テスト 「小テスト」については、毎回の授業時間内に、LMS上において当該コマの小テスト(難易度表示付
復習・予習課題 ◆今回授業の復習
まとめの課題として、複数行の文字列を用意し、「① matchesによる形式判定、② Pattern/Matcherを用いた部分一致検索、③ 検索モード」をすべて含むプログラムを作成する。それぞれの処理について、「なぜこの方法を選んだのか」を説明できるようにする。
◆次回授業の予習
身近な文章やデータを一つ選び、「どの部分を置き換えたいか」「どの条件で分割したいか」を考えておくこと。例えば、文章中の全角・半角の表記ゆれ、不要な記号や空白の削除、複数の区切り文字(カンマ、空白、スラッシュなど)が混在するデータの分割などを想定し、それらを正規表現で表すとしたら、どのようなパターンになるかを文章で整理しておくこと。

11 正規表現による文字列の置換処理と分割 科目の中での位置付け 本コマは、第8コマから第10コマにかけて学習してきた正規表現の基本構文、検索、抽出処理を踏まえ、それらを文字列の書き換え(置換)や分割に応用する段階に位置づけられる。
これまでの授業では、「条件に合っているかを調べる」「条件に合う部分を見つける」といった処理を中心に扱ってきたが、本コマでは更に一歩進めて、「見つけた部分をどう加工するか」「扱いやすい形にどう分けるか」を体験する。
実際のプログラムでは、入力された文字列をそのまま使えることはほとんどなく、不要な部分を消したり、表記をそろえたり、意味のある単位に分解したりする必要がある。本コマでは、正規表現と標準APIを組み合わせることで、そうした処理を、短く、分かりやすく書けることを実感し、文字列処理が「手間のかかる作業」から「設計して整理する作業」へ変わる体験を行う。

第11回テキスト 
第1章 「標準ライブラリ」 第2節「正規表現」
項目4「正規表現による文字列の置換処理と分割」
コマ主題細目 ① 正規表現による文字列置換 ② キャプチャグループを利用した置換処理 ③ 正規表現による文字列分割
細目レベル ①  デモで理解する正規表現の必要性と文字列置換の理解まで
授業の最初に、文章中に含まれるURLを自動的に検出し、HTMLのリンク形式に置き換えて表示するプログラムを実行させる。ここで、「今日は、文字列の中から見つけた部分を、別の形に書き換える処理を行う」「このような処理を、自分で書けるようになることが目標である」と明確に示す。次に、正規表現を使わずに同じ処理を行おうとした場合の例を見る。URLの開始位置を探し、文字を一つずつ確認しながら終わりを判定し、部分文字列として切り出し、文字列を組み立て直す、といった手順をコードで確認する。ここで、「処理の流れが分かりにくい」「少し形式が変わると動かなくなる」といった問題点を共有し、「文字列を力ずくで扱うことの大変さ」を実感させる。その上で、正規表現と replaceAllメソッドを使うと、「条件に合う部分をまとめて書き換えられる」ことを示す。ここでは、構文の細かい説明には踏み込まず、「検索で使っていた正規表現を、そのまま置換にも使える」という点を強調する。
実習で文章中の特定の表現(URLや決まった語句など)を別の表現に置き換え、表示結果がどのように変わるかを確認することで、「検索の次は置換」という自然な流れを理解させる。

②  置換後の文字列に、元の情報を活かした表現を組み込めるようになることの理解まで。
置換処理の中で「元の文字列の情報を再利用できる」ことに注目させ、正規表現でマッチした文字列全体を、そのまま別の形で囲んで表示する例を実行する。学生には、「見つけた文字列そのものを、置換後に使っている」という点を意識させる。次に、正規表現の中で一部を区切って指定することで、マッチした文字列の一部分だけを取り出し、置換後の文字列に埋め込めることを示す。例えば、メールアドレスから利用者名とドメイン部分を分けて表示する例を通して、「一度の処理で、分解と再構成ができる」ことを体験する。ここでは、専門用語の説明よりも、「元の情報を並べ替えたり、文章として組み直したりできる」という感覚を重視する。
実習では、置換後の表示内容を少しずつ変えながら、「どの部分を使って、どこに表示しているのか」を確認する。これにより、正規表現が「ただ消すための道具」ではなく、「情報を加工するための道具」であることを理解させる。

③  正規表現を用いて、複雑な条件で文字列を分割できるようになることの理解まで。
最初に、一つの文章を特定の条件で分割し、単語や意味のまとまりごとに表示するプログラムを実行する。ここで、「区切り文字が1文字とは限らない」「見た目では分かりにくい条件でも分割できる」という点を確認する。次に、これまで学んできたsplitを使わずに処理しようとした場合の例を見る。文字の位置を数えながら切り出す方法では、条件が複雑になるとコードが読みづらくなり、修正も難しくなることを確認する。
その上で、正規表現を使うと、「こういう並びが来たら区切る」というルールをそのまま分割条件として書けることを示す。
まとめの演習では、数値や特定の語句を含む部分を区切りとして文字列を分割し、結果が配列として得られることを確認する。分割後の要素数や内容を表示することで、「自分の考えた条件で、意図した形に分かれているか」を確かめる姿勢を身に付ける。これにより、「正規表現は、検索や置換だけでなく、分割にも使える汎用的な仕組みである」ことを理解し、次回の総合演習につなげる。

キーワード ① 正規表現 replace replaceAll replaceFirst キャプチャグループ split Pattern
コマの展開方法 社会人講師 AL ICT PowerPoint・Keynote 教科書
コマ用オリジナル配布資料 コマ用プリント配布資料 その他 該当なし
小テスト 「小テスト」については、毎回の授業時間内に、LMS上において当該コマの小テスト(難易度表示付
復習・予習課題 ◆今回授業の復習
文章形式の文字列を一つ用意し、「① 正規表現を用いた置換処理、② 元の文字列の一部を利用した置換、③ 正規表現による分割処理」などのプログラムを作成し実行してみる。
それぞれについて、「どの条件で、何を目的に処理しているか」をコメントで説明できるように整理する。
◆次回授業の予習
次回は、正規表現を総合的に活用する演習に取り組む。
身近なデータ(文章、ログ、入力データなど)を一つ選び、「不要な部分を消す」「表記をそろえる」「意味のある単位に分ける」としたら、どのような処理が必要になりそうかを考えておくこと。

12 正規表現演習 科目の中での位置付け 本コマは、正規表現の基本構文を用いた検索処理を中心に、これまで学習してきた正規表現の知識を実際の文字列処理に適用する演習回である。これまでの授業では、正規表現の記号や書き方、Pattern や Matcher を用いた検索処理、置換や分割といった個別の操作を段階的に扱ってきたが、本コマではそれらを断片的な知識としてではなく、「目的に応じて正規表現を調整しながら使う」という実践的な使い方として整理することを目標とする。
扱う題材は、HTMLタグや電話番号、メールアドレスなど、日常的によく目にする構造をもった文字列である。正規表現を一度書いて終わりにするのではなく、実行結果を見ながら書き方を少しずつ変え、「なぜこの書き方だとうまくいくのか」「なぜ別の書き方では意図しない結果になるのか」を確認することで、正規表現を暗記の対象ではなく、調整しながら使う道具として捉え直すことをねらいとする。

第12回テキスト 
第1章 「標準ライブラリ」 第2節「正規表現」
項目5「正規表現演習」
コマ主題細目 ① 量指定子および最長一致と最短一致の違い ② キャプチャグループによる部分抽出と再利用 ③ 実用的な検索・抽出処理への応用
細目レベル ①  正規表現の書き方の違いによって、検索結果が大きく変わることの理解まで。
授業の冒頭では、HTMLタグを含む文字列を対象とした検索プログラムを実行し、画面にどのような文字列が出力されるかを確認する。最初は、タグが一つずつ取り出される例を示し、「今日は、正規表現を使って、意図した単位で文字列を取り出す練習をする」という授業の目的を明確にする。次に、正規表現の一部を変更した場合の例を示し、複数のタグがまとめて一つの文字列として出力されてしまう様子を確認する。学生には、「なぜ同じように見える書き方でも、結果が大きく変わるのか」を考えさせ、正規表現が「どこまでを一つとして扱うか」を内部で判断していることを、実行結果から体感させる。
  ここでは専門用語の説明に深入りせず、「できるだけ長く取ろうとする書き方」と「必要なところで止まる書き方」があることを、結果の違いから理解させることを重視する。
実習では、正規表現の一部を少しずつ書き換えながら実行し、出力結果がどのように変化するかを確認することで、「正規表現は一度で完成させるものではなく、調整しながら使うもの」であるという感覚を身に付ける。

②  キャプチャグループを用いて、文字列の中の情報を意味ごとに取り出せるようになることの理解まで。
電話番号やメールアドレスのように、一つの文字列の中に複数の意味をもつ情報が含まれている例を扱う。最初は、文字列全体をそのまま検索して表示するプログラムを実行し、「全体は取れているが、中身は分かれていない」状態を確認する。その上で、「市外局番」「市内局番」「加入者番号」といった意味のある単位に分けて取り出せると、後続の処理がしやすくなることを説明する。
実習では、正規表現の中で区切りを作ることで、それぞれの部分を個別に取得できることを確認し、画面にラベル付きで表示する。これにより、正規表現が単に探すための道具ではなく、「文字列を分解して扱うための手段」でもあることを理解させる。
更に、取り出した部分に名前を付けて参照する方法を紹介し、番号で指定する場合と比べて、コードの読みやすさや意図の分かりやすさが向上することを実感させる。ここでは細かな構文の暗記を目的とせず、「意味を意識して文字列を扱えるようになる」ことを重視する。

③  正規表現を用いた検索・抽出の応用例を通して、活用範囲を理解することの理解まで。
最後に、正規表現を用いた検索処理の応用例を紹介する。ここでは新しい構文を詳細に学習するのではなく、「このような書き方を使うと、構造をもった文字列をまとめて扱える」という理解を目的とする。
例として、HTMLのリンクタグを対象に、完成した正規表現を用いたプログラムを実行し、特定の条件を満たす要素だけが抽出される様子を確認する。正規表現を使わずに同様の処理を行おうとすると、文字列の切り出しや比較、条件分岐が必要になり、コードが複雑になることにも触れ、「文字列の構造が分かっている場合には、正規表現に任せる方が分かりやすい」という判断基準を示す。
この項目では、「すべてを書けるようになる」ことを求めるのではなく、「正規表現には、こうした使い方もあることを知り、必要になったときに調べて使える状態になる」ことを目標とする。

キーワード ① 規表現 Pattern Matcher find キャプチャグループ group
コマの展開方法 社会人講師 AL ICT PowerPoint・Keynote 教科書
コマ用オリジナル配布資料 コマ用プリント配布資料 その他 該当なし
小テスト 「小テスト」については、毎回の授業時間内に、LMS上において当該コマの小テスト(難易度表示付
復習・予習課題 ◆今回授業の復習
授業で扱った正規表現の例を一つ選び、正規表現の一部を変更したときに検索結果がどのように変化するかを確認する。「どこを変えたか」「なぜ結果が変わったと考えられるか」を簡潔に説明できるように整理する。
◆次回授業の予習
次回からは、日付や時刻といった別のAPIを扱う。日付や時刻をプログラムで扱う際に、文字列として扱う場合と専用のAPIを使う場合で、どのような違いや不便さがありそうかを考えておく。

13 日付/時刻APIの概要とオブジェクト生成 科目の中での位置付け 本コマは、これまで扱ってきた文字列処理中心の学習から一歩進み、「時間」という現実世界と強く結びついたデータを扱うための基礎として、Java の日付/時刻APIを導入する位置づけにある。
業務プログラムでは、入力日時の記録、期限判定、経過時間の計算、ログの解析など、日付/時刻を扱う場面は極めて多い。一方で、日付や時刻は「見た目は単純だが、内部構造や前提条件が複雑」なデータでもある。
本コマでは、java.timeパッケージにより提供される Date-Time API の全体像を把握し、用途に応じて適切なクラスを選択し、日付/時刻オブジェクトを正しく生成できるようになることを目的とする。特に、「時差やタイムゾーンを考慮しない場合」と「考慮する必要がある場合」との使い分けを明確にし、後続コマでの比較・計算・整形処理へとつながる基礎理解を形成する。

第13回テキスト 
第1章 「標準ライブラリ」 第3節「日付/時刻操作」
項目1「日付/時刻APIの概要とオブジェクト生成」
コマ主題細目 ① java.timeパッケージの構成と主要クラス ② 現在日時および指定日時からのオブジェクト生成 ③ 文字列からの日付/時刻オブジェクト生成
細目レベル ①  java.time パッケージが提供する日付/時刻APIの全体像を把握できるようになることの理解まで。
初めに、投稿日時の表示や予約時刻の管理など、日時処理がどのような場面で必要になるのかをデモサンプルを通して示す。例えば、「投稿した時刻を表示する」「海外ユーザーに現地時刻で表示する」といった具体例を提示し、「プログラムで“今の日時”を扱うとはどういうことか」という問いにつなげる。その上で、現在日時を表示する簡単なプログラムを実行する。LocalDateTime、OffsetDateTime、ZonedDateTime、LocalDate、LocalTimeを順に表示し、「同じ“今”でも、取得できる情報が異なる」ことを確認する。
続いて、Date-Time API の実体が java.timeパッケージに含まれるクラス群であることを説明し、ローカル日時を扱う LocalXxxxx 系クラス、時差情報を含む OffsetXxxxx 系クラス、地域情報まで含めた ZonedDateTime の役割を整理する。ここでは詳細な内部構造には踏み込まず、「どのクラスは何を表しているのか」「どんな場面で使い分けるのか」を理解することを重視する。
特に、「時差を意識しない処理では LocalDateTime を使う」「国や地域をまたぐ処理では ZonedDateTime を使う」といった具体的な利用場面と結びつけて説明し、API選択が設計の一部であることを意識させる。

②  指定した日時情報から、日付/時刻オブジェクトを正しく生成できるようになることの理解まで。
ここでは、ofメソッドを用いた日付/時刻オブジェクトの生成方法を扱う。年月日や時分秒を直接指定してオブジェクトを生成する例を実行し、「プログラム上で任意の日時を作る」ことができる点を確認する。月を数値ではなく Month列挙型で指定できる例を示し、数値指定との違いを比較することで、「可読性を高める書き方」が用意されていることを理解させる。また、範囲外の値を指定した場合には自動補正されず例外が発生することを確認し、「日付/時刻は厳密なルールのもとで管理されている」ことを体感させる。
更に、LocalDateと LocalTimeを個別に生成し、それらを組み合わせて LocalDateTimeを生成する例を通して、「部品として生成し、後から組み立てる」という設計の考え方に触れる。OffsetDateTimeやZonedDateTimeについては、ZoneOffsetやZoneIdを引数として渡すことで、時差や地域情報を含めた日時が生成できることを確認する。ここでは、「何を指定すると、どの情報が付加されるのか」を整理することを重視する。

③  日付/時刻を表す文字列から、対応するオブジェクトを生成できるようになることの理解まで。
最後に、parseメソッドを用いた文字列からの変換処理を扱う。まず、ISO形式で記述された日付文字列を LocalDate に変換する例を実行し、「文字列を解析して日付オブジェクトに変換できる」ことを確認する。次に、DateTimeFormatter を指定することで、年と通算日、週番号表現など、異なる形式の文字列も解析できることを示す。ここではフォーマッターの一覧をすべて暗記させるのではなく、「形式が違えば、対応するフォーマッターを指定する必要がある」という考え方を理解させることを目的とする。
ZonedDateTime を例に、オフセットやタイムゾーン情報を含む文字列を解析できることを確認し、「表示形式」と「内部表現」が分離されている点を強調する。これにより、後続コマで扱う比較・整形処理への見通しを持たせる。

キーワード ① Date-Time API(java.time) LocalDateTime ZonedDateTime of parse
コマの展開方法 社会人講師 AL ICT PowerPoint・Keynote 教科書
コマ用オリジナル配布資料 コマ用プリント配布資料 その他 該当なし
小テスト 「小テスト」については、毎回の授業時間内に、LMS上において当該コマの小テスト(難易度表示付
復習・予習課題 ◆今回授業の復習
現在日時を取得するプログラムと、指定した日時(自分の誕生日や任意の日付)を生成するプログラムを作成し、LocalDateTime と ZonedDateTime の出力結果を比較する。それぞれについて、「どの情報が含まれているか」「どの用途に向いていそうか」を文章で整理する。
また、ISO形式の日付文字列を parse メソッドで変換し、正しく日付オブジェクトが生成されているかを確認する。
◆次回授業の予習
日付や時刻を扱う場面では、「どちらが早いか」「期限を過ぎているか」といった判定が頻繁に行われる。日常生活やシステム利用の中で、「日付の比較が必要になりそうな場面」をいくつか挙げ、それをプログラムで判定するとしたら、どのような処理が必要になりそうかを考えておくこと。

14 日付・時刻の比較と構成要素を用いた判定処理 科目の中での位置付け 本コマは、第13コマで学習した日付/時刻オブジェクトの生成方法を踏まえ、それらを実際の処理判断に用いるための基礎技術を学ぶ段階に位置づけられる。
業務プログラムでは、期限内かどうかの判定、開始時刻と終了時刻の前後関係の確認、特定の日付に該当するかどうかの判定など、「日時を比べて判断する」処理が頻繁に登場する。そこで、Date-Time API が提供する equals/isBefore/isAfter メソッドを用いて、日付/時刻同士を安全かつ直感的に比較する方法を学ぶ。更に、年月日や時分秒といった時刻要素を取得し、それらを条件分岐に利用する方法を確認することで、「日時を値として扱う」のではなく、「意味を持った情報として判断に使う」視点を身に付けることを目的とする。

第14回テキスト 
第1章 「標準ライブラリ」 第3節「日付/時刻操作」
項目2「日付・時刻の比較と構成要素を用いた判定処理」
コマ主題細目 ① 日付/時刻オブジェクトの比較 ② 年月日・時分秒などの構成要素の取得 ③ 日時比較と要素取得を用いた判定処理
細目レベル ①  日付/時刻同士の比較によって、前後関係や一致を判定できるようになることの理解まで。
初めに、日時の比較が必要となる場面をデモサンプルを通して示す。例えば、「現在時刻が有効期限を過ぎている場合は利用不可と表示する」といった具体例を提示し、日時比較の必要性を理解させる。
その上で、二つの日時を用意し、「どちらが先か」「同じ日時かどうか」を判定する簡単なプログラムを実行する。学生には、equals、isBefore、isAfter を用いることで、「日時を数値として計算することなく、意味的に比較できる」ことを確認させる。次に、これらの判定を if 文と組み合わせ、「期限を過ぎているか」「まだ有効か」といった実務的な条件判断の例を示す。ここでは、比較結果が true/false として得られ、それをそのまま条件分岐に利用できる点を強調する。
また、「等しい」「より前」「より後」という三つの関係を明示的に分けて判定できることにより、処理の意図が読み取りやすくなることを確認し、日時比較においては専用メソッドを用いることが基本であることを理解させる。あわせて、比較を行う際には、同じ型の日付/時刻オブジェクト同士で判定する必要があることを確認し、異なる型や異なる基準の日時を安易に比較しない姿勢を身に付けさせる。更に、「現在時刻」との比較を通して、nowメソッドで取得した日時が判定処理の基準として頻繁に用いられることを示し、日時比較が一時的な確認ではなく、処理の流れを制御する重要な要素であることを意識させる。

②  日付/時刻オブジェクトから、年月日や時分秒などの構成要素を取得できるようになることの理解まで。
ここでは、getYearや getMonthValue、getDayOfMonth、getHourなどのメソッドを用いて、日時を構成する個々の要素を取り出す方法を学習する。最初に、1つの日時オブジェクトから複数の要素を取得し、それぞれを画面に表示するプログラムを実行することで、「日時は一つの値ではなく、複数の情報の集合である」ことを確認する。
次に、曜日や月が列挙型として取得できる点に触れ、数値だけでなく「意味を持った値」として扱えることを説明する。これにより、可読性の高い判定処理が書けることを実感させる。更に、ChronoField を用いることで、取得したい要素を柔軟に指定できる方法を紹介し、「必要な情報を取り出す」という視点で API を使う意識を育てる。

③  日時比較と要素取得を組み合わせ、実用的な判定処理を書けるようになることの理解まで。
最後に、比較処理と要素取得を組み合わせた判定例を扱う。例えば、「指定日が平日かどうかを判定する」「営業時間内かどうかを時刻要素から判断する」「特定の月に該当するかを判定する」といった条件をコードとして表現する。
ここでは、単にメソッドを呼び出すだけでなく、「何を基準に判断しているのか」を言葉で説明できることを重視する。日時比較と要素取得を適切に使い分けることで、条件式が整理され、処理の意図が明確になることを確認する。
本コマを通して、「日時を比べる」「日時の一部を見る」という二つの方法が、状況に応じて選択されるべき判断手段であることを理解し、次回の整形表示や差分計算へとつなげる。

キーワード ① Date-Time API equals/isBefore/isAfter getYear/getMonthValue/getDayOfMonth DayOfWeek ChronoField
コマの展開方法 社会人講師 AL ICT PowerPoint・Keynote 教科書
コマ用オリジナル配布資料 コマ用プリント配布資料 その他 該当なし
小テスト 「小テスト」については、毎回の授業時間内に、LMS上において当該コマの小テスト(難易度表示付
復習・予習課題 ◆今回授業の復習
二つの日付/時刻を用意し、「① 前後関係の判定、② 日付要素を用いた条件判定」を含む簡単なプログラムを作成する。例えば、「指定日時が現在より前かどうか」「平日か休日か」といった条件を設定し、それぞれの判定結果がどのように得られているかをコメントで説明できるように整理する。
◆次回授業の予習
日付や時刻を「人にとって読みやすい形」で表示する必要がある場面を考える。例えば、ログ表示、画面表示、帳票出力などを想定し、「どのような形式で表示されていると分かりやすいか」を具体的に挙げておくこと。

15 日付・時刻の整形表示とフォーマット演習 科目の中での位置付け 本コマは、第13コマで学習した日付/時刻APIの概要とオブジェクト生成、第14コマで学習した日時の比較・判定処理を踏まえ、日付/時刻を「人にとって読みやすい形で表示する」ための方法を学ぶ段階に位置づけられる。
これまでのコマでは、日付/時刻を「計算・判定の対象」として扱ってきたが、本コマではそれを「利用者に提示する情報」として整形することに焦点を当てる。
特に、DateTimeFormatter を用いた標準フォーマットとカスタムフォーマットの使い分け、ロケールやタイムゾーンによる表示差の理解を通して、内部表現と表示形式を分離して設計するというJava標準APIの考え方を理解させることを目的とする。

第15回テキスト 
第1章 「標準ライブラリ」 第3節「日付/時刻操作」
項目3「日付・時刻の整形表示とフォーマット演習」
コマ主題細目 ① DateTimeFormatterによる日付/時刻の整形表示 ② 標準フォーマットとカスタムフォーマットの使い分け ③ ロケール・暦による表示形式の違い
細目レベル ①  DateTimeFormatter を用いて日付/時刻を整形表示できるようになることの理解まで。
最初に、LocalDateTime や ZonedDateTime の値をそのまま表示した場合と、format メソッドを用いて整形表示した場合の出力を比較するプログラムを実行する。その際、単なる出力の違いの確認にとどまらず、ログ出力やユーザー向け画面表示(例:予約日時表示、履歴一覧、エラーログなど)を模したデモサンプルを用いて確認する。これにより、「同じ日時オブジェクトでも表示方法によって印象や読みやすさが大きく変わる」ことを体験的に理解させるとともに、そのままの出力では利用者にとって直感的に理解しづらい場合があることや、タイムゾーンの有無や表記形式によって誤解や読み違いが生じる可能性があること、さらに用途(ログや画面表示)に応じて適切なフォーマット設計が必要になることに気付かせる。
このように、実際のソフトウェア機能と結びつけて考えることで、日時フォーマットの重要性を具体的に理解させる。
次に、DateTimeFormatter.ofLocalizedDate、ofLocalizedTime、ofLocalizedDateTime を用いた標準フォーマットを紹介し、FormatStyle の指定によって表示の詳細度や表現の簡潔さが変化することを確認する。ここでは、SHORT・MEDIUM・LONG などの違いを実際に比較し、「用途によって適切な表示粒度が異なる」ことを理解させる。
学生には、「日時の値そのものを変更しているのではなく、表示方法だけを切り替えている」点を繰り返し確認させ、整形表示が日付/時刻オブジェクト自身の責務ではなく、フォーマッターが担う役割であることを理解させる。これにより、内部表現と表示形式を分離するという、API設計の基本的な考え方を身に付けさせる。

②  標準フォーマットと自作フォーマットの違いと使い分けを理解できるようになることの理解まで。
標準フォーマットでは対応しきれない表示例として、日本語を含む書式や、業務要件に基づいた独自の並び順による表示を取り上げ、ofPattern メソッドによるカスタムフォーマットを紹介する。ここでは、「○年○月○日」「曜日を含めた表示」など、実務でよく見られる例を示し、カスタム書式の必要性を具体的に理解させる。
この段階では、書式指定子をすべて暗記させることを目的とせず、「年・月・日・時刻といった構成要素を、必要な形で並べ替えられる」という感覚を重視する。実習では、同じ日時に対して複数の書式を適用し、表示結果を比較することで、「表示形式によって受け取る情報の印象が変わる」ことを確認する。
あわせて、標準フォーマッターを優先すべき理由として、ロケールに応じた自動調整や将来的な拡張性が確保されている点を示し、「常に自作書式を書くのではなく、目的・利用環境・保守性を考慮してAPIを選択する姿勢」を養う。これにより、整形表示も設計判断の一部であることを意識させる。

③  ロケールや暦の違いによって表示結果が変わることの理解まで。
withLocaleメソッドを用いてロケールを切り替えた場合の表示結果を比較し、日本と海外で日時の表現方法が異なることを確認する。月日の順序、曜日名や月名の表記などに注目させ、「同じ日時情報でも、文化や言語によって自然な表示が異なる」ことを理解させる。
「プログラムは同じでも、利用環境によって表示が変わる」という点を強調し、国際化対応が特別な処理ではなく、設計段階から考慮すべき要素であることを意識させる。標準フォーマッターがロケール情報をもとに適切な表示を提供している点にも触れ、APIの設計意図を確認する。
補足として、JapaneseDateクラスを用いた和暦表示を紹介し、西暦とは異なる暦体系も Javaの標準APIとして扱えることを示す。ここでは、「日本独自の特殊処理」ではなく、「用途や利用者に応じたクラスを選択する」という視点を重視し、日時表示が文化的・社会的背景とも密接に関わる情報であることを理解させる。
更に、学習内容の整理と定着を目的として、日時処理に関するまとめの演習を実施する。ロケールによる表示の違い、標準フォーマッターの活用、和暦を含む複数の暦体系の扱いを確認することで、日時処理に関する理解を総合的に深める。

キーワード ① DateTimeFormatter FormatStyle ofPattern Locale JapaneseDate
コマの展開方法 社会人講師 AL ICT PowerPoint・Keynote 教科書
コマ用オリジナル配布資料 コマ用プリント配布資料 その他 該当なし
小テスト 「小テスト」については、毎回の授業時間内に、LMS上において当該コマの小テスト(難易度表示付
復習・予習課題 ◆今回授業の復習
同一の日時オブジェクトに対して、① 標準フォーマット、② 自作フォーマット、③ ロケールを切り替えた表示の3種類を行うプログラムを作成し、それぞれの表示結果を比較する。どの表示がどの場面に適しているかを、簡単なコメントとして整理する。
◆次回授業の予習
日付/時刻の「差分計算」や「加算・減算」が必要になりそうな場面(期限管理、スケジュール表示、残り日数の計算など)を2つ以上想定し、どのような処理が必要になりそうかを言葉で整理しておく。

16 日付・時刻の差分計算と加算・減算 科目の中での位置付け 本コマは、第13コマで学習した日付/時刻オブジェクトの生成、第14コマで扱った比較と判定処理、第15コマの整形表示を踏まえ、「日時を計算対象として扱う」段階に位置づけられる。
これまでのコマでは、日時を「表す」「比べる」「表示する」ことを中心に学んできたが、本コマではそれを一歩進め、「どれくらい離れているか」「どれだけ進める/戻すか」といった時間的な差や変化を扱う。
実務では、経過日数の算出、期限までの残り時間、予約日から一定期間後の日時算出など、日付・時刻の計算は非常に頻繁に登場する。本コマでは、数値計算に頼るのではなく、Javaの Date-Time APIが用意している Period/Duration クラスや plus/minus 系メソッドを用いることで、安全かつ読みやすく日時計算が行えることを理解することを目的とする。

第16回テキスト 
第1章 「標準ライブラリ」 第3節「日付/時刻操作」
項目4「日付・時刻の差分計算と加算・減算」
コマ主題細目 ① Period/Durationによる日付・時刻の差分取得 ② plus/minusメソッドによる日時の加算・減算 ③ 差分計算と日時操作の実務的活用
細目レベル ①  日付/時刻の差分を、意味をもった単位として取得できるようになることの理解まで。
最初に、スケジュール管理アプリや予約システムなどを例に挙げ、「イベントまであとどれくらいか」「利用時間がどれくらいか」といった機能で日時の差分計算が必要になる場面を示す。簡単なデモプログラムを通して、実際にどのように差分が利用されるのかをイメージさせる。
その上で、二つの日時を用意し、「どれくらい離れているか」を求めるプログラムを実行する。ここでは、単純にミリ秒差を引き算するのではなく、PeriodとDurationという専用クラスを使って差分を表すことを示す。
Period は「○年○か月○日」といった日付感覚の差を、Duration は「○時間」「○分」といった時間間隔としての差を表すクラスであることを、実行結果を見ながら確認する。
これにより、用途に応じて適切な差分の表現方法を選択する必要があることを理解させる。
次に、betweenメソッドの引数に指定できる型の違いに注目し、Durationは LocalDateTimeや ZonedDateTimeなど幅広い日時型を扱える一方で、Period は LocalDateを対象とするため、必要に応じて toLocalDateによる変換が必要になる点を整理する。
ここでは APIの制約を暗記させるのではなく、「日付として比べたいのか、時刻まで含めて比べたいのか」という視点でクラスを選ぶことが重要であると強調する。
演習では、年・月・日単位で差を求めた場合と、時間単位で差を求めた場合とで、得られる値や意味が異なることを比較し、「同じ二つの日時でも、目的によって使うクラスが変わる」ことを理解させる。

②  日時を指定した量だけ進めたり戻したりできるようになることの理解まで。
次に、plus/minus メソッドを用いた日付・時刻の加算/減算を扱う。まずは、特定の日付に対して「〇年後」「〇日前」といった計算を行うプログラムを実行し、日時オブジェクトは変更されず、新しい日時が返されるという不変性の考え方を確認する。ここでは、変数に再代入しない限り元の日時は保持されることを明示し、意図せず値が書き換わることを防ぐ設計になっている点を理解させる。
続いて、ChronoUnitを指定する plus/minus メソッドと、plusDaysや minusMonthsなどの専用メソッドを比較し、それぞれの読みやすさや使いどころを整理する。例えば、「何日後か」を表したい場合には専用メソッドが直感的である一方、単位を変数として扱いたい場合には ChronoUnitを用いる方法が有効であることを示す。ここでは、「どちらが正しいか」ではなく、「処理の意図が伝わりやすいか」「変更に強い書き方か」という観点でメソッドを選ぶ姿勢を重視する。
演習では、ある基準日から一定期間後の日時を求める処理や、期限日から逆算して準備開始日を求める処理などを題材にし、日時計算が現実のスケジュール管理や業務設計と直結していることを意識させる。また、計算結果をそのまま表示するだけでなく、判定処理と組み合わせることで、実務的な利用場面を具体的にイメージさせる。

③  期間オブジェクトを用いて、日時計算をまとめて扱えるようになることの理解まで。
最後に、Period/Duration オブジェクトそのものを plus/minus に渡す方法を紹介する。これにより、「3年と2か月後」「1日と1時間前」といった複合的な期間を、一つの値として扱えることを確認する。ここでは、複数の加算・減算処理を連続して書くのではなく、期間をひとまとまりのオブジェクトとして定義できる点に注目させ、処理の意味が明確になることを理解させる。
また、ofXxxxx メソッドや parse メソッドを用いて期間オブジェクトを生成できることを示し、文字列による期間指定が可能である点にも触れる。これにより、設定ファイルや入力値から期間を読み取り、日時計算に利用できることを示し、実務への応用可能性を意識させる。ここでは書式の暗記を目的とせず、「期間も日時と同様にオブジェクトとして扱われている」という設計思想を理解することを重視する。
演習では、Period/Durationを使った場合と、個別に plusDays・minusHoursを呼び出した場合とを比較し、処理の見通しや保守性、修正時の影響範囲の違いを考えさせる。これにより、日時計算を「場当たり的な足し引き」ではなく、「意味をもった操作として構造化する」視点を養い、後続の実践的なプログラム設計につなげる。

キーワード ① Date-Time API Period Duration between plus/minus ChronoUnit 不変オブジェクト
コマの展開方法 社会人講師 AL ICT PowerPoint・Keynote 教科書
コマ用オリジナル配布資料 コマ用プリント配布資料 その他 該当なし
小テスト 「小テスト」については、毎回の授業時間内に、LMS上において当該コマの小テスト(難易度表示付
復習・予習課題 ◆今回授業の復習
基準となる日時を一つ設定し、① Periodを用いた日付差分の取得、② Durationを用いた時間差分の取得、③ plus/minus を用いた日時の加算・減算
を含むプログラムを作成する。それぞれについて、「なぜそのクラスやメソッドを選んだのか」をコメントで説明できるように整理する。
◆次回授業の予習
Java 7 以前の日付/時刻 API(Date、Calendar)では、日時計算がどのように行われていたかを調べ、「なぜ現在の Date-Time API が導入されたのか」を整理しておく。

17 Java 7以前の日付/時刻APIとの関係と相互変換 科目の中での位置付け 本コマは、第13コマから第16コマにかけて学習してきた Date-Time API(java.time パッケージ)を、実際の既存コードや過去の資産と結び付けて理解するための位置づけにある。
Java 8 以前では、日付・時刻処理は主にCalendarやDateクラス(java.util パッケージ)を用いて行われており、現在でもそれらを用いたコードは多くの現場で利用されている。そのため、Date-Time APIだけを理解していても、既存のプログラムを読めない・扱えないという状況が生じやすい。
本コマでは、Calendarを用いた従来の日時操作の考え方を確認したうえで、Date-Time APIとの対応関係や相互変換の方法を学習する。これにより、過去のコードを理解しつつ、現在主流となっている API へ安全に移行できる基礎力を身に付けることを目的とする。

第17回テキスト 
第1章 「標準ライブラリ」 第3節「日付/時刻操作」
項目5「Java 7以前の日付/時刻APIとの関係と相互変換」
コマ主題細目 ① Date/Calendarによる従来の日時操作 ② 従来APIとDate-Time APIの設計思想の違い ③ 従来APIとDate-Time APIの相互変換
細目レベル ①  Java 7 以前の日時 API による基本的な操作についての理解まで。
最初に、Calendarクラスを用いて日時を生成・表示・加算する簡単なプログラムを実行する。年・月・日・時・分・秒をsetメソッドで指定し、getメソッドで各要素を取り出す処理を通して、「日時を一つのオブジェクトとして扱っている」点を確認する。
次に、add メソッドを用いた日時の加算処理を実行し、「〇年後」「〇日後」といった計算が可能であることを確認する。また、getTimeInMillisを利用した差分計算の例を示し、ミリ秒単位の数値計算によって日数差を求めていることを理解させる。
ここでは、Calendar API を積極的に使いこなすことを目的とするのではなく、「既存コードでよく見かける書き方として読めるようになる」ことを重視する。同時に、コードが直感的に読みづらい点や、月が 0 始まりである点など、注意が必要な特徴にも触れ、後の比較につなげる。

② Date-Time API と従来 API の設計の違いを理解できることの理解まで。
次に、Calendarを用いた日時操作と、これまで学習してきた LocalDateTimeや ZonedDateTimeによる操作を並べて示し、書き方や考え方の違いを整理する。Calendarでは、オブジェクト自身が変更される可変オブジェクトであるのに対し、Date-Time APIでは操作の結果として新しいオブジェクトが返される不変オブジェクトである点を確認する。これにより、処理の途中で値が書き換わってしまう危険性や、意図しない副作用が発生しにくい設計になっていることを理解させる。また、日時の比較や差分計算についても、「数値を取り出して計算する」方法と、「意味を持ったメソッドを呼び出す」方法の違いに注目し、Date-Time APIが読みやすさと安全性を重視して設計されていることを整理する。ここでは、「古い APIが間違っている」のではなく、「設計思想が異なる」ことを理解することを目標とする。

③ Calendar と Date-Time API を相互に変換できるようになることの理解まで。
最後に、Calendarと Date-Time APIを相互に変換する方法を扱う。まず、Calendarから toInstantメソッドを用いて Instantオブジェクトを生成し、それを ofInstantメソッドによって LocalDateTime、OffsetDateTime、ZonedDateTime に変換する流れを確認する。
ここで、Instant が「1970年1月1日からの経過時間」という共通の基準で日時を表すクラスであり、異なる API 同士をつなぐ橋渡しの役割を果たしていることを理解させる。また、変換時に ZoneId を指定する必要がある理由にも触れ、タイムゾーンの扱いが明示的になっている点を確認する。
次に、Date-Time APIから Calendarへ戻す例を示し、Instant → Date → Calendarという手順が必要であることを確認する。その際、Date-Time API はナノ秒精度、Calendar/Date はミリ秒精度であるため、精度の切り捨てが発生する点に注意を向ける。
演習では、既存の Calendarベースのコードを読み取り、その一部を Date-Time APIに変換するあるいはその逆を行う課題を通して、「混在する API を安全につなぐ」実践的な感覚を身に付けさせる。

キーワード ① Calendar Date Instant LocalDateTime toInstant/ofInstant
コマの展開方法 社会人講師 AL ICT PowerPoint・Keynote 教科書
コマ用オリジナル配布資料 コマ用プリント配布資料 その他 該当なし
小テスト 「小テスト」については、毎回の授業時間内に、LMS上において当該コマの小テスト(難易度表示付
復習・予習課題 ◆今回授業の復習
Calendarを用いた日時生成・加算・比較の簡単なプログラムを作成し、その結果を Date-Time APIを用いた場合のコードと書き比べる。どちらの方が処理の意図を読み取りやすいかを文章で整理する。
◆次回授業の予習
Date-Time API を用いた日付・時刻操作の演習では、複数の API を組み合わせた処理を行う。これまで学習した生成・比較・加算・整形表示の各操作を、どのような順序で組み合わせれば実用的な処理になるかをイメージしておく。

18 日付/時刻操作演習 科目の中での位置付け 本コマは、これまでに学習してきた日付/時刻APIの内容を、実際に動かし、比べ、書き換えることを通して定着させる演習回である。
これまでの授業では、日時オブジェクトの生成、比較、整形表示、差分計算、加算・減算、そして従来APIとの関係を段階的に学んできた。本コマではそれらを一つの流れとして扱い、「日付/時刻を使った処理を最初から最後まで組み立てる」体験を重視する。
特に、現在でも多くの現場で目にするCalendarやDateをあえて取り上げ、「なぜ書きづらいのか」「どこで困りやすいのか」を実例として確認したうえで、Date-Time API を使うことで同じ処理がどのように整理されるかを体感的に理解させる。
目的は、新旧APIの優劣を知識として覚えることではなく、「読みやすく、間違えにくい書き方とは何か」を、自分の手で確かめることである。

第18回テキスト 
第1章 「標準ライブラリ」 第3節「日付/時刻操作」
項目6「日付/時刻操作演習」
コマ主題細目 ① Calendar/Dateによる日時処理の特徴 ② Date-Time APIによる書き換えと比較 ③ 日時の生成・比較・計算・表示の統合処理
細目レベル ①  従来の日時APIを用いた処理を実行し、「どこで困るのか」を具体的に実感できるようになることの理解まで。
前回までの復習として、Date-Time APIを用いた簡単な日時処理を振り返る。その後、あらかじめ完成形として用意された Calendar を用いた日時操作プログラムを実行し、「これと同じことを、今日は作り直します」と全体像を示す。
Calendar に年月日や時刻をsetし、日付を変更したり、Dateに変換して表示したりする処理を実行する。ここで学生には、「動いてはいるが、コードを読んで直感的に意味が分かるか」「一部を書き換えるときに不安がないか」という点に注目させる。例えば、月が 0 から始まること、setを何度も呼び出す必要があること、オブジェクトの中身がその場で書き換わっていることなどを、実行結果とコードを照らし合わせながら確認する。
この段階では、細かな仕様説明は行わず、「思った通りに書けているかどうか」「後から見たときに自分で理解できそうか」という感覚を重要視する。あわせて、SimpleDateFormat を用いた文字列変換の例を実行し、書式文字列を少し間違えるだけで例外が発生する様子を確認することで、「日時処理は一見簡単そうに見えて、実は失敗しやすい」ことを実感させる。

② Date-Time API を用いることで、同じ日時処理を整理して書けるようになることの理解まで。
「同じ処理を Date-Time API で書くとどうなるか」を示す。ここでは最初に完成形のプログラムを実行し、LocalDate や LocalDateTime、ZonedDateTime を用いて、日時の生成・加算・比較・表示が一連の流れとして行われている様子を確認する。
その後、Calendar を使ったコードと Date-Time API を使ったコードを並べて提示し、学生自身に「どこが読みやすいか」「どこで安心できるか」を考えさせる。
例えば、plusDays や isAfter といったメソッド名が、そのまま処理内容を表している点、不変オブジェクトであるため途中で値が変わらない点などを、実行結果と対応づけて確認する。
実習では、次のような流れでコードを書き進める。
「基準となる日付を LocalDate で生成する」→「一定日数後の日付を plusDays で求める」→「現在日付と比較し、条件分岐を行う」→「結果を DateTimeFormatter で整形して表示する」
  この一連の処理を通して、「日時を数値として扱っていない」「意味のある操作を組み合わせている」という感覚を持たせる。また、Instant と ZonedDateTime の相互変換を簡単に体験し、「同じ瞬間でも、見る場所が変わると表示が変わる」ことを確認することで、これまで学んできた内容が線としてつながるように構成する。

③ 日付/時刻操作を組み合わせ、実用的な小さな処理を完成させられるようになることの理解まで。
最後に、これまで学習してきた操作を組み合わせた 総合演習を行う。題材は、「ある日付を基準に、期限日を計算し、現在が期限内かどうかを判定して表示する」といった、日常的にイメージしやすい内容とする。
学生には、最初に「完成したらこう動く」というプログラムを実行して見せ、「これを自分で作る」という目標を明確にする。その後、「日時をそのまま扱おうとすると不便な例」「Calendar で書いた場合の読みにくさ」を短く示し、「だからこの API を使う」という流れで Date-Time API を用いた実装に導く。
すべてを一から書かせるのではなく、穴埋めや一部修正を中心とし、「メソッドを選ぶ理由」「処理の流れ」を考えながら完成させることを重視する。最終的に、「日付/時刻の生成 → 計算 → 比較 → 表示」という一連の処理を、自分の書いたコードとして確認できることをゴールとする。

キーワード ① Calendar Date-Time API LocalDateTime plus/minus DateTimeFormatter
コマの展開方法 社会人講師 AL ICT PowerPoint・Keynote 教科書
コマ用オリジナル配布資料 コマ用プリント配布資料 その他 該当なし
小テスト 「小テスト」については、毎回の授業時間内に、LMS上において当該コマの小テスト(難易度表示付
復習・予習課題 ◆今回授業の復習
授業で作成したプログラムについて、「どの部分が分かりやすかったか」「Calendar で書いた場合と比べて安心できた点」を短い文章で整理する。
◆次回授業の予習
 数値・配列・ファイルなど、これまで学んできた他のAPIと日付/時刻処理がどのように組み合わさるかを想像し、「日時が関係しそうな処理」を一つ挙げておく。

19 数学演算・乱数生成・数値の整形 科目の中での位置付け 本コマは、日付/時刻APIを中心とした一連の学習を終え、Java標準APIの中でその他の機能の学習へと対象を広げる位置づけにある。
これまで扱ってきた文字列、日時、コレクションなどに加え、実務プログラムでは、数値計算・乱数生成・数値の表示整形といった処理が頻繁に登場する。
特に、計算結果を安全に扱うための数学関数、型の上限を超える数値を正しく扱うための仕組み、数値を「人に伝わる形」で表示するための整形処理は、アルゴリズム以前に標準APIの正しい使い方として身に付けておくべき基礎技術である。
Math・BigInteger・Random・NumberFormatといった代表的なユーティリティクラスを通して、「数値を計算する」「数値を生成する」「数値を表現する」という三つの観点から、Java標準APIの設計思想と実務的な活用方法を理解することを目的とする。

第19回テキスト 
第1章 「標準ライブラリ」 第4節「その他のユーティリティ」
項目1「数学演算・乱数生成・数値の整形」
コマ主題細目 ① Mathクラスによる基本的な数学演算 ② BigIntegerクラスによる大規模整数の扱い ③ Randomによる乱数生成とNumberFormatによる数値整形
細目レベル ①  数学演算用ユーティリティを用いて、数値計算を安全かつ簡潔に記述できるようになることの理解まで。
最初に、売上計算や評価システムなどを例に挙げ、数値計算がどのような機能で利用されるのかを示す。たとえば、「キャラクターの移動距離の計算」「評価点の四捨五入表示」「範囲内での最大値・最小値の制御」などの簡単なデモプログラムを通して、Mathクラスの機能が実際のソフトウェアの中でどのように使われるかを理解させる。
その上で、Mathクラスが提供する各種静的メソッドを用いて、絶対値・最大値/最小値・四捨五入・切り上げ/切り捨てなどの基本的な数学演算を行うプログラムを実行する。ここでは、Mathクラスがインスタンス化不要なユーティリティクラスであり、「計算ロジックを自分で実装する必要がない」ことを確認する。特に、ceilDiv/floorDivや ceilMod/floorModを例に、単純な「割り算」や「剰余演算」が、負の数を含む場合に直感と異なる結果を生むことがある点に注目させる。その上で、演算の意味を明示した専用メソッドを用いることで、バグを防ぎ、意図の伝わるコードになることを理解させる。
また、三角関数や対数関数については、数式としての理解よりも、「ライブラリとして正しく呼び出せる」ことを重視し、角度とラジアンの変換が必要である点を実行結果を通して確認する。ここでは、「必要な計算をAPIに委ねる」という標準API活用の基本姿勢を身に付けさせる。
特に、ceilDiv/floorDivやceilMod/floorModを例に、単純な割り算や剰余演算が負の数を含む場合に直感と異なる結果を生むことがある点に注目させる。その上で、演算の意味を明示した専用メソッドを用いることで、バグを防ぎ、意図の伝わるコードになることを理解させる。
また、三角関数や対数関数については、数式としての理解よりも、「ライブラリとして正しく呼び出せる」ことを重視する。たとえば、回転処理や角度計算といった簡単なデモを通して、角度とラジアンの変換が必要である点を実行結果から確認させる。
これらを通して、「必要な計算をAPIに委ねる」という標準API活用の基本姿勢を身に付けさせる。

②  long 型の限界を理解し、BigIntegerを用いて安全な整数演算ができるようになることの理解まで。
long 型を用いた階乗計算の例を実行し、一定の桁数を超えた時点でオーバーフローが発生し、結果が破綻する様子を確認する。これにより、「型の範囲を超えた計算は、エラーにならず静かに壊れる」という危険性を具体的に理解させる。
その後、同じ処理を BigIntegerクラスを用いて書き換え、valueOf メソッドによる生成、add・multiply などの演算メソッドを用いた計算により、正しい結果が得られることを確認する。ここでは、コードが多少冗長になる代わりに、正確さと安全性が保証されるという設計上のトレードオフを意識させる。
あわせて、BigIntegerが「巨大な数値そのもの」ではなく、「数値を扱うためのオブジェクト」である点を強調し、演算がすべてメソッド呼び出しとして表現されている理由を確認する。これにより、数値もまたオブジェクトとして扱われているという Java の一貫した設計思想を理解させる。

③  乱数生成と数値整形を通して、「数値の生成」と「数値の表示」を分離して扱えるようになることの理解まで。
最初に、くじ引き機能、テストデータの自動生成などを例に挙げ、乱数生成がどのようなソフトウェアの機能で利用されるのかを示す。簡単なデモプログラム(例:サイコロの出目を生成する、ランダムに値を選択するなど)を通して、乱数が実際の処理にどのように組み込まれるかを理解させる。その上で、Random クラスを用いた乱数生成を扱い、nextInt・nextDoubleなどのメソッドによって、目的に応じた乱数が取得できることを確認する。特に、引数を指定した場合の nextIntが「範囲を制御した乱数生成」に使える点を示し、ゲームやシミュレーション、テストデータ生成などへの応用可能性を意識させる。
続いて、NumberFormatクラスを用いた数値の整形表示を扱う。通貨・パーセント・整数・桁区切りといったフォーマットを切り替えることで、同じ数値でも表示結果が大きく変わることを確認する。ここでは、数値そのものを加工しているのではなく、「表示方法を制御している」点を強調する。更に、setMaximumFractionDigitsなどの設定メソッドを用いてフォーマットを調整し、「表示要件はプログラム側で制御できる」ことを理解させる。

キーワード ① Mathクラス 丸め処理(ceil/floor/round) BigInteger オーバーフロー Random NumberFormat
コマの展開方法 社会人講師 AL ICT PowerPoint・Keynote 教科書
コマ用オリジナル配布資料 コマ用プリント配布資料 その他 該当なし
小テスト 「小テスト」については、毎回の授業時間内に、LMS上において当該コマの小テスト(難易度表示付
復習・予習課題 ◆今回授業の復習
Math クラスを用いた計算、BigIntegerを用いた整数演算、Random による乱数生成、NumberFormat による数値整形のうち、少なくとも2種類以上を組み合わせた簡単なプログラムを作成する。
それぞれについて、「なぜそのクラスを使ったのか」「自分で計算・整形しなかった理由」を説明できるように整理する。
◆次回授業の予習
配列操作やファイル処理など、「複数のデータをまとめて扱う」場面では、数値や文字コードの扱いが重要になる。次回扱う配列・Unicode・ファイル操作について、「どのような場面で必要になりそうか」を具体例とともに考えておくこと。

20 配列・Unicode正規化・ファイル操作API 科目の中での位置付け 本コマは、数値・日時といった単一の値を扱ってきた前段までの学習を踏まえ、複数の値をまとめて扱う配列操作と、文字列の表現揺らぎを吸収するUnicode正規化を学ぶ回として位置づけられる。
配列は、Javaの最も基本的なデータ構造でありながら、検索・並び替え・コピーといった処理を自前で実装しようとすると、可読性や安全性が低下しやすい。本コマでは、Arraysクラスが提供する静的メソッドを利用することで、「配列操作を意図通り・簡潔に記述する」方法を理解させる。
また後半では、見た目は同じでも内部表現が異なる文字列が存在することを示し、Normalizerクラスによる Unicode正規化を通して、入力データの揺らぎを吸収する設計の重要性を理解させる。これにより、次コマ以降の配列・コレクション・ファイル操作を「安全な前処理の上で行う」ための基礎を形成する。

第20回テキスト 
第1章 「標準ライブラリ」 第4節「その他のユーティリティ」
項目2「配列・Unicode正規化」
コマ主題細目 ① Arraysクラスによる配列操作 ② 配列コピーにおけるシャローコピーとディープコピー ③ NormalizerによるUnicode正規化
細目レベル ①  Arrays クラスを用いて、配列操作を安全かつ簡潔に行えるようになることの理解まで。
最初に、文字列配列を用いた基本的な例を実行し、Arrays.sortによる並び替え、Arrays.binarySearchによる検索、Arrays.toStringによる内容表示を確認する。
ここでは、「配列はそのままでは中身が見えにくい」「検索はソート済みであることが前提になる」といった注意点を、実行結果とともに整理する。特に、binarySearchがソート済み配列を前提として動作する点を強調し、「APIは前提条件を満たして初めて正しく使える」ことを理解させる。続いて、copyOfおよび copyOfRangeを用いた配列コピーを扱い、配列サイズが固定であること、サイズ変更は「新しい配列を作る」ことで実現されている点を確認する。これにより、「配列操作は破壊的変更ではなく、コピーによる設計が基本である」という考え方を身に付けさせる。

② 配列コピーにおけるシャローコピーとディープコピーの違いについての理解まで。
まず、配列に格納された参照型オブジェクトが、コピーによってどのように扱われるかを確認する。
Arrays.copyOによるコピーが、シャローコピーであり、要素そのものではなく「参照」がコピーされていることを、StringBuildeを用いた具体例で確認する。コピー元の要素を変更した結果がコピー先にも影響する様子を観察し、「コピーしたつもりでも、同じオブジェクトを共有している場合がある」ことを理解させる。
その上で、for 文を用いて要素ごとに新しいオブジェクトを生成する ディープコピーの例を示し、コピー元とコピー先が独立して動作することを確認する。ここでは、「どちらが常に正しいか」ではなく、「どのような場面で注意が必要か」を判断できることを重視し、APIの動作を理解したうえで使い分ける姿勢を養う。

③ Unicode正規化の必要性を理解し、Normalizer クラスを用いて文字列を統一できるようになることの理解まで。
後半では、見た目は同じでも内部的には異なる文字列が存在する例として、「ギガ」の複数表現を提示する。検索や比較処理において、こうした表記揺らぎが問題になることを確認し、「人にとって同じ」と「コンピューターにとって同じ」が一致しない場合があることを理解させる。
次に、Unicode正規化の4つの形式(NFD/NFC/NFKD/NFKC)について確認し、特に互換正規化(NFKC)を用いることで、半角カナや記号文字も含めた統一が可能になる点を示す。
Normalizer.normalizeを用いた具体例では、複数の文字表現が正規化によってどのように変換されるかを確認し、「正規化は表示のためではなく、比較・検索・保存前の前処理として行う」べきであることを強調する。
本コマを通して、配列操作とUnicode正規化が、ともに入力データを安全に扱うための下準備であることを意識させ、次回の数値・配列・ファイル操作API活用へとつなげる。

キーワード ① Arrays sort/binarySearch シャローコピー/ディープコピー Unicode正規化 Normalizer
コマの展開方法 社会人講師 AL ICT PowerPoint・Keynote 教科書
コマ用オリジナル配布資料 コマ用プリント配布資料 その他 該当なし
小テスト 「小テスト」については、毎回の授業時間内に、LMS上において当該コマの小テスト(難易度表示付
復習・予習課題 ◆今回授業の復習
文字列配列を一つ用意し、① 並び替え、② 検索、③ サイズ変更(コピー)を行うプログラムを作成する。あわせて、参照型配列をコピーした場合にどのような影響が出るかを確認し、シャローコピーとディープコピーの違いを文章で整理する。
更に、表記の異なる同一語(例:全角/半角、濁点分離文字など)を Unicode 正規化した結果を比較し、検索前に正規化を行う意義をまとめる。
◆次回授業の予習
 配列や文字列は、ファイル入力や数値処理と組み合わさって使われることが多い。
「外部から読み込んだデータを配列として扱う場面」を想定し、どのような前処理(整形・正規化・並び替え)が必要になりそうかを考えておくこと。

21 数値・配列・ファイル操作API活用演習 科目の中での位置付け 本コマは、第19コマ「数学演算・乱数生成・数値の整形」、第20コマ「配列・Unicode正規化」で学習した内容を総合的に復習・定着させるとともに、新たにファイル操作API(java.nio.file)を扱う演習回である。
これまでの「その他のユーティリティ」では、数値計算、乱数、配列操作、文字の正規化といった、プログラム内部で完結する処理を中心に学んできた。本コマではそれらを踏まえ、外部のファイルやフォルダーを扱う処理へと学習範囲を広げる。
業務プログラムでは、計算結果や配列データをファイルとして保存・移動・削除する場面が非常に多く、ファイル操作は実用的なプログラムの入り口ともいえる。本コマでは、難解な入出力処理に踏み込む前段階として、Filesクラスによる基本的なファイルシステム操作を演習中心で体験する。目的は、「数値・配列で処理した結果を、ファイルという形で扱えるようになる」という一連の流れを理解することである。

第21回テキスト 
第1章 「標準ライブラリ」 第4節「その他のユーティリティ」
項目3「数値・配列・ファイル操作API活用演習」
コマ主題細目 ① 数値計算・乱数・配列操作の総合演習 ② 数値・配列処理結果の整理と活用 ③ Filesクラスによるファイルおよびフォルダー操作
細目レベル ① 数値・配列に関する既習内容を、演習を通して再確認できるようになることの理解まで。
前半では、第19・20コマで扱った内容を中心に、復習を目的とした演習を行う。具体的には、Mathクラスによる基本的な数値演算、Randomクラスによる乱数生成、NumberFormatによる数値の整形表示を組み合わせた簡単な処理を題材とする。例えば、「乱数で生成した数値の配列を作成し、その平均値や最大値を計算し、見やすい形式で表示する」といった演習を通して、数値APIと配列操作が自然に結び付くように構成する。
また、配列操作については、配列要素が基本型である場合と参照型である場合の違いを確認し、「コピーしたつもりでも中身は共有されている」ケースがあることを、短いコード例で再確認する。ここでは理論説明に深入りせず、実行結果の違いから挙動を理解させることを重視する。
Unicode正規化については、文字列比較の結果が変わる例を軽く振り返り、「見た目が同じでも内部表現が異なることがある」という注意点を再確認する程度にとどめる。

② 数値処理・配列処理を一つの流れとして整理できるようになることの理解まで。
次に、複数の処理を組み合わせた小さな演習課題に取り組む。例えば、「複数の数値データを配列で管理し、条件に合うものを抽出して整形表示する」といった課題を通して、これまで学んできたAPIを“点”ではなく“流れ”として使う感覚を養う。
ここでは、「どのAPIを使うか」よりも、「どの順序で処理しているか」「中間結果がどのようなデータになっているか」を意識させ、処理の構造を言葉で説明できることを重視する。
この段階までで、後半のファイル操作演習につながる「処理結果を外に出す準備」が整っていることを確認する。

③ Filesクラスを用いて、基本的なファイル/フォルダー操作が行えるようになることの理解まで。
後半では、java.nio.file.Files クラスを用いたファイル操作の演習を行う。最初に、Files.exists、isReadable、isWritableなどを用いて、指定したファイルの状態を確認する簡単なプログラムを実行し、「ファイルを操作する前に、状態を確認する」という基本姿勢を身に付けさせる。続いて、Files.copy、move、delete、deleteIfExists を用いたファイルのコピー・移動・削除を扱い、それぞれのメソッドが何を行っているのかを、実際のファイル構成の変化と対応付けて確認する。特に、delete と deleteIfExists の違いについては、例外の有無という観点から整理し、「安全に処理を書くためのAPIが用意されている」点を強調する。
更に、フォルダー操作として createDirectoriesや listメソッドを用い、フォルダーの作成や配下ファイルの一覧取得を体験する。list メソッドが Stream を返す点については、詳細なストリーム処理には踏み込まず、「後で学ぶStream APIにつながる入口」として位置付ける。あわせて、try-with-resources と組み合わせて利用する必要がある理由を説明し、リソース管理の考え方に軽く触れる。
演習のまとめとして、「数値・配列で処理した結果を、ファイル操作によって管理する」という一連の流れを確認し、本節が“ユーティリティAPIの活用”の締めであることを意識させる。

キーワード ① Files Path/Paths exists Math Random NumberFormat 配列操作 
コマの展開方法 社会人講師 AL ICT PowerPoint・Keynote 教科書
コマ用オリジナル配布資料 コマ用プリント配布資料 その他 該当なし
小テスト 「小テスト」については、毎回の授業時間内に、LMS上において当該コマの小テスト(難易度表示付
復習・予習課題 ◆今回授業の復習
数値の配列を一つ用意し、① 数値処理(計算・整形表示)、② 配列操作、③ ファイル操作のいずれかを組み合わせた簡単なプログラムを作成する。処理の流れをコメントで説明し、「どのAPIがどの役割を担っているか」を整理する。
◆次回授業の予習
次回からはコレクションフレームワークを扱う。配列と比べて、「要素数が変化するデータ」を扱う必要がありそうな場面を考え、配列では不便に感じそうな点を挙げておくこと。

22 コレクションフレームワークの概要とListの復習 科目の中での位置付け 本コマは、第1コマから第21コマまでに学習してきた Java標準APIの個別機能(文字列、日付・時刻、数値、配列、ファイル操作など)を踏まえ、それらを複数まとめて扱うための基盤となる仕組みとして、コレクションフレームワークを再整理する位置づけにある。
環境プログラミングⅡで既に学習している List/Set/Map といった概念を単に復習するのではなく、「標準ライブラリの一部として、どのような思想で設計され、どのように使い分けるのか」という視点から再確認する。
特に本コマでは、コレクションフレームワーク全体の構造を俯瞰したうえで、最も基本となる Listインターフェイスの利用方法と典型的な操作の基本的な考え方を復習する。
これにより、次コマ以降の Set/Map、更にはラムダ式や Stream APIを用いたコレクション操作へと自然につながる理解の土台を形成することを目的とする。

第22回テキスト 
第2章 「コネクションフレームワーク」 第1節「コネクションフレームワーク」
項目1「コレクションフレームワークの概要とListの復習」
コマ主題細目 ① コレクションフレームワークの構造と主要インターフェイス ② Listインターフェイスと代表的実装クラス ③ Listの基本操作とコーディングパターン
細目レベル ①  コレクションフレームワークの全体像についての理解まで。
最初に、商品一覧の管理やユーザ情報の保持、キューによる処理順制御などを例に挙げ、複数データを扱う機能においてコレクションフレームワークがどのように利用されるかをデモサンプルを通して示す。その上で、コレクションフレームワークが「複数のデータをまとめて扱うための共通の枠組み」であることを確認する。List、Set、Map、Queue(Deque)といった主要インターフェイスを図示し、それぞれが「順序を持つ/持たない」「重複を許す/許さない」「キーと値の対応を持つ」といった異なる性質を備えていることを整理する。ここでは、個々のメソッドを詳細に追うのではなく、「どのような性質の集合を扱いたいときに、どのインターフェイスを選ぶのか」という設計判断の視点を重視する。また、変数の型として実装クラスではなくインターフェイス型(List や Set)を用いる理由に触れ、実装の差し替えや変更に強いコードを書くための基本方針を再確認する。

② Listインターフェイスの基本操作と実装クラスの違いについての理解まで。
次に、List を対象として、要素の追加・取得・削除・検索といった基本操作を復習する。ArrayListと LinkedListを取り上げ、それぞれの内部構造と特性を簡潔に整理する。
ArrayList については、「配列を基盤としたサイズ可変のリスト」であり、ランダムアクセスに優れる一方、挿入・削除にはコストがかかる点を確認する。LinkedListについては、「要素同士をリンクで結んだ構造」であり、先頭や末尾への追加・削除に向いている点を理解させる。
ここでは性能の数値比較を目的とせず、「どのような操作が多いかによって、選ぶべき実装が変わる」という考え方を身に付けさせることを重視する。Java標準APIが複数の実装クラスを用意している理由を理解し、ArrayListから一歩進んだ選択ができるようにする。

③ ist 操作における基本イディオムの意味と適切な使い方についての理解まで。
最後に、List を扱う際によく用いられる 代表的なコーディングについて、その基本的な考え方を具体的なコード例をもとに整理する。
要素の初期化、変更不可リストの生成、拡張 for 文や Iterator を用いて、リストの要素を先頭から順に取り出して処理する方法、Iteratorによる安全な削除、配列と List の相互変換などを段階的に確認する。
ここでは、「文法として書けるか」ではなく、「意図が伝わる自然な書き方になっているか」を重視する。例えば、for 文でのインデックス操作が不要な場面では拡張for文を用いること、走査中に要素を削除する場合はIteratorを使うこと、外部から変更させたくないリストには変更不可ビューを用いることなど、それぞれの使い分けの理由を明確にする。また、Arrays.asList や toArrayなどを用いた相互変換を通して、「配列APIとコレクションAPIは役割が異なるが、相互に行き来できる設計になっている」ことを理解させる。本コマを通して、List 操作の基本形を整理し、次回以降のより高度なコレクション操作の前提知識として定着させる。

キーワード ① コレクションフレームワーク List/Set/Map ArrayList/LinkedList ジェネリクス Iterator
コマの展開方法 社会人講師 AL ICT PowerPoint・Keynote 教科書
コマ用オリジナル配布資料 コマ用プリント配布資料 その他 該当なし
小テスト 「小テスト」については、毎回の授業時間内に、LMS上において当該コマの小テスト(難易度表示付)
復習・予習課題 ◆今回授業の復習
ArrayListまたは、LinkedList を用いて、文字列のリストを作成し、要素の追加・取得・削除、拡張 for 文によるリスト要素の順次処理、Iterator を用いたリスト要素の順次処理などについて、含む簡単なプログラムを作成する。また、それぞれについて、「なぜその書き方を選んだのか」を説明する。
◆次回授業の予習
List では扱いにくそうなデータ構造(重複を許したくない集合、キーと値の対応関係など)を日常の例から考え、それをプログラムで扱うにはどのような仕組みが必要になりそうかを整理しておく。

23 セット・マップの復習とスタック・キュー 科目の中での位置付け 本コマは、前回の「コレクションフレームワークの概要とListの復習」に続き、コレクションフレームワーク理解を一層深める学習に位置づけられる。
SetおよびMapは環境プログラミングⅡですでに学習している内容であるが、実務的な利用場面では Listと組み合わせて用いられることが多く、それぞれの特性を正しく理解し、目的に応じて選択できるかどうかが重要となる。
前半では、SetとMapの基本操作を復習し、「重複を許さない」「キーによる管理」「順序保証の有無」といった性質を整理する。特に、HashSet/TreeSet、HashMap/TreeMap の違いを通して、データ構造の選択が処理の意味や効率に直結することを再確認する。
後半では、スタック・キュー構造を取り上げる。DequeインターフェイスとArrayDequeクラスを用い、後入れ先出し(LIFO)・先入れ先出し(FIFO)という代表的なデータ処理モデルを、具体的な API操作を通して理解する。

第23回テキスト 
第2章 「コネクションフレームワーク」 第1節「コネクションフレームワーク」
項目2「セット・マップの復習とスタック・キュー」
コマ主題細目 ① Setの特性と主要実装(HashSet/TreeSet) ② Mapの特性と主要実装(HashMap/TreeMap) ③ Dequeによるスタック・キュー構造
細目レベル
 Setの基本操作と特性を理解できるようになることの理解まで。
はじめに、List と Set の違いを確認し、「要素の重複を許さない」「順序を基本的に保証しない」という Setの特性を整理する。HashSetを用いた基本操作(追加・削除・包含判定・集合演算)を実行し、contains、addAll、retainAll、removeAllなどのメソッドが、数学的な集合操作と対応していることを確認する。
次に、TreeSet を取り上げ、要素が自動的にソートされる点を HashSetと比較する。ceiling、lower、headSet、tailSet などの操作を通して、「順序付き集合」としての利用場面を理解させる。ここでは、順序を管理するために内部構造が異なることを意識させ、「順序が必要な場合には TreeSetを選択する」という設計判断につなげる。

②  Mapの基本操作と実装クラスの違いについての理解まで。
次に、Mapを「キーと値のペアで管理されるデータ構造」として整理し、Listや Setとは構造そのものが異なる点を確認する。HashMapを用いた基本操作を通して、containsKey、containsValue、keySet、values、entrySetによる実行の流れを確認し、キーを基準にデータへアクセスする考え方を定着させる。
更に、IdentityHashMap や WeakHashMap の挙動を簡単な例で紹介し、「キーの比較方法や参照の扱いによって、同じ値でも結果が変わる」ことを理解させる。TreeMapについては、キーが自動的にソートされる点に注目し、Comparatorを指定することで並び順を制御できることを確認する。
ここでは詳細なアルゴリズム理解よりも、「Mapでも順序が重要な場面がある」という設計上の視点を重視する。

③ Deque を用いてスタック・キュー操作を実装できるようになることの理解まで。
後半では、新しい学習内容としてスタック・キュー構造を扱う。まず、スタック(LIFO)とキュー(FIFO)の概念を日常的な例(Undo操作、待ち行列)と結び付けて整理する。次に、Dequeインターフェイスと ArrayDequeクラスを用い、両端からの要素追加・削除を行うプログラムを実行する。
` addFirst/addLast、removeFirst/`removeLast の操作を比較し、「どの操作の組み合わせがスタックになるか」「どの操作がキューになるか」を確認する。
あわせて、例外を投げるメソッドと null/false を返すメソッドの違いに触れ、エラー処理方針によって API を使い分ける必要があることを理解させる。
ここでは、ArrayDequeがStackクラスよりも推奨される理由を示し、「古いクラスが残っている理由」と「現在の推奨設計」を区別する姿勢を養う。

キーワード ① Set(HashSet/TreeSet) Map(HashMap/TreeMap) Deque/ArrayDeque スタック(LIFO)/キュー(FIFO) コレクションフレームワーク
コマの展開方法 社会人講師 AL ICT PowerPoint・Keynote 教科書
コマ用オリジナル配布資料 コマ用プリント配布資料 その他 該当なし
小テスト 「小テスト」については、毎回の授業時間内に、LMS上において当該コマの小テスト(難易度表示付)
復習・予習課題 ◆今回授業の復習
Set と Map をそれぞれ用いた簡単なプログラムを作成し、
・重複データがどのように扱われるか
・キーを使ったアクセスがどのように行われるか
を実行結果とともに整理する。
あわせて、ArrayDeque を用いて「スタック動作」「キュー動作」をそれぞれ実装し、どのメソッドを使うとどの挙動になるかを説明できるようにまとめる。
◆次回授業の予習
複数のデータをまとめて管理し、検索・判定・取り出しを行う処理を想定する。
例えば「重複を除いて集計したい」「キーで情報を管理したい」といった場面を考え、それぞれに適したコレクション(List/Set/Map/Deque)を選ぶとしたら、どれを使うかを理由とともに整理しておくこと。

24 コレクションを用いた実践的演習 科目の中での位置付け 本コマは、「コレクションフレームワーク」の章の最終節として、第22コマおよび第23コマで学習した内容を総合的に振り返る演習回に位置づけられる。
第22コマではListを中心にコレクションフレームワーク全体の構造と基本操作を復習し、第23コマでは Set・Map・スタック/キューといった他の主要なデータ構造の特性と利用方法を整理してきた。
本コマでは、これらを個別の知識として確認するのではなく、実際の処理を想定した演習課題を通して、「どのコレクションを選び、どのように組み合わせて使うか」を考えさせることを目的とする。List・Set・Map・Deque それぞれの役割や性質を踏まえ、処理内容に応じて適切なデータ構造を選択する力を養うことで、以降のラムダ式・Stream API を用いたコレクション操作へとつながる実践的な基盤を形成する。

第24回テキスト 
第2章 「コネクションフレームワーク」 第1節「コネクションフレームワーク」
項目3「コレクションを用いた実践的演習」
コマ主題細目 ① List・Set・Map・Dequeの使い分け ② 複数コレクションを組み合わせた処理設計 ③ 可読性を意識したコレクション操作
細目レベル ① コレクションの特性を踏まえて、適切な選択ができるようになることの理解まで。
はじめに、演習に入る前段階として、List・Set・Map・Deque の特性を簡潔に整理する。
「順序を保持したい」「重複を排除したい」「キーで対応付けたい」「先頭や末尾から処理したい」といった典型的な要件を提示し、それぞれの場合にどのコレクションが適しているかを、言葉で説明できるようにする。
演習教材としては、単一のコレクションで完結する小規模な課題を用意する。
例えば、
・文字列の一覧を List で管理し、順番を保ったまま表示・更新する課題
・数値や文字列の集合から重複要素を取り除き、Set を用いて件数を確認する課題
・英単語と日本語訳の対応を Map で管理し、キーから値を取得する課題
といった、コレクションの特性がそのまま処理内容に反映される問題を扱う。
ここでは実装の正確さやコード量よりも、データ構造の選択そのものが設計の一部であるという意識を持たせることを重視する。

② 複数のコレクションを組み合わせた処理を構築できるようになることの理解まで。
次に、List・Set・Map を組み合わせた、やや実践的な演習課題に取り組む。演習教材では、「役割の異なるコレクションを段階的に使い分ける」流れが分かるような課題設定とする。
例えば、「List で受け取ったデータから Set を用いて重複を除去し、その結果を再び List に変換して表示する課題」「Map に格納されたデータを List に変換し、順序を意識した処理や一覧表示を行う課題」「List に格納されたデータを集計し、Map に“項目と件数”の対応関係としてまとめる課題」などを通して、コレクション同士の相互変換と役割分担**を確認する。
また、Deque を用いたスタック/キュー操作についても、簡単な処理フローを題材に演習を行う。具体的には、「処理待ちのデータを先に登録したものから順に処理する」「最後に追加した処理を取り消す」といった場面を想定し、addFirst/addLast、removeFirst/removeLast の使い分けによって、処理順序がどのように変化するかを実行結果から確認させる。

③ 可読性と保守性を意識したコレクション操作ができるようになることの理解まで。
最後に、これまでの演習で作成したコードを振り返り、処理の意図が伝わりやすい書き方について整理する。演習教材では、同じ処理内容を、拡張 for 文を用いた場合やIterator を用いた場合といった複数の書き方で示し、それぞれの利点や注意点を比較する。
特に、Iterator を用いた安全な削除、拡張 for 文による要素の列挙、変更不可コレクション(unmodifiableList など)の利用といった、22・23コマで扱った基本的な考え方が、実際の処理の中でどのような意味を持つのかを確認する。
「なぜこの場面では Iterator を使うのか」「なぜ変更不可にするのか」といった点を、実行時エラーや処理結果の違いを通して理解させる。
ここでは、「正しく動作するかどうか」だけでなく、後から読み返したときに理解しやすいか、処理の目的がコードから読み取れるかという観点を重視する。
これにより、コレクション操作を単なる API の寄せ集めではなく、意味を持った処理の構成要素として設計する姿勢**を養うことを目標とする。

キーワード ① コレクションフレームワーク List/Set/Map/Deque ArrayList/HashSet/HashMap/ArrayDeque 重複除去 スタック/キュー
コマの展開方法 社会人講師 AL ICT PowerPoint・Keynote 教科書
コマ用オリジナル配布資料 コマ用プリント配布資料 その他 該当なし
小テスト 「小テスト」については、毎回の授業時間内に、LMS上において当該コマの小テスト(難易度表示付)
復習・予習課題 ◆今回授業の復習
本時の演習で扱った課題を振り返り、各課題について次の点を整理する。
・使用したコレクションの種類(List・Set・Map・Deque など)
・そのコレクションを選択した理由(順序・重複・対応関係・処理順などの観点から)
・他のコレクションでは置き換えにくい理由、または不都合が生じる点
これらを簡潔な文章でまとめ、コード中のコメント、または別紙のメモとして整理する。「どの API を使ったか」ではなく、「なぜそのコレクションを選んだのか」について確認する。
◆次回授業の予習
次章では、列挙型(enum)を用いて「取り得る値をあらかじめ限定した設計」について学習する。
準備として、固定的な値の集合(例:状態・種別・区分など)を List や Map で管理した場合に、想定外の値が入ってしまう、値の意味が分かりにくくなる、修正や拡張が難しくなるといった問題がなぜ起こり得るのかを考え、「値を制限する仕組み」が必要となる理由を整理しておくこと。

25 列挙型の基本構文と内部構造 科目の中での位置付け 本コマは、第3章「オブジェクト指向構文」の導入として、Javaにおける「値の制限と安全な設計」を学ぶ回である。これまでの学習では、文字列や数値、コレクションなど、Javaが提供する汎用的な「データの入れ物」を扱ってきた。しかし、実務のプログラムでは、「信号の色(赤・青・黄)」や「季節(春・夏・秋・冬)」のように、選択肢が限定されているデータが数多く存在する。これらを単なる数値や文字列として扱うと、想定外の値が入り込むことで深刻なバグを引き起こす原因となる。本コマでは、特定の選択肢のみを「型」として定義する列挙型(enum)を導入し、不正なデータをコンパイル時点で完全に排除する手法を習得する。
第25回テキスト 
第3章 「オブジェクト指向構文」 第1節「列挙型」
項目1「列挙型の基本構文と内部構造」
コマ主題細目 ①  int型定数管理の限界と型安全性 ②  enumの基本構文と値の限定 ③  列挙型の内部構造と標準メソッド
細目レベル ① 「int型(整数)を用いた定数管理」が抱える落とし穴を体験し、列挙型が必要である理由の理解まで。
まず「四季(春夏秋冬)を処理するプログラム」の完成形を確認する。信号機やカレンダーのように、あらかじめ決まった選択肢から一つを選んで処理するプログラムは、世の中に溢れている。一見簡単そうに見えるが、これを「これまでに学んだ知識だけ」で作ろうとすると、意外な問題に直面する。public final static int SPRING = 0;のように、整数に名前をつけて管理する方法を試す。この方法で四季を判定するメソッド processSeason(int season)を作成すると、一見正しく動いているように見える。このメソッドの引数は「int型」であるため、例えば processSeason(100)や processSeason(-1)といった四季には存在しない数字を渡しても、Javaはコンパイルエラーとならない。更に、別の場所で定義した「1月は0、2月は1...」という月の定数(JANUARY = 0)を間違えて渡しても、どちらも同じ「0」であるため、プログラムは「春」として処理を続けてしまう。
この「何でも受け入れてしまう状態」が、いかに開発現場で恐ろしいバグを招くかを、実際にエラーにならないが正しくも動かないコードを通して実感する。「自由すぎることは、間違いの元である」という感覚を掴むことが目的である。

②  「列挙型(enum)」の基本構文について、特定の選択肢しか許さない「型」としての使い方を習得できるようになることの理解まで。
次に、先ほどの「0, 1, 2, 3」というあやふやな数字でなく、public enum Season { SPRING, SUMMER, AUTUMN, WINTER } という、新しい「型」を作る方法を学ぶ。
列挙型(enum)を使う最大のメリットは、メソッドの引数を intではなく、自分たちが作った Season型に指定できることにある。これにより、processSeason(Season season) というメソッドには、Season.SPRINGなどの決められた選択肢以外、絶対に渡せなくなる。もし間違えて processSeason(4)と書いたり、全く別の型を渡そうとしたりすれば、実行する前の「コードを書いている最中」にJavaが型の違いを警告してくれる。つまり、プログラマのうっかりミスを、Javaのシステムが強制的に阻止してくれるようになる。
ここでは、実際に自分で enumを定義し、それを使ってメソッドを呼び出すコードを記述する。名前そのものが値として機能するスッキリとした感覚と、コンパイラが守ってくれる安心感を体験する。また、定数名にはすべて大文字を用いる「アンダースコア記法」といったプロの現場での慣習についても、実際のコードを書きながら身に付けていく。配列と同じように、最後の要素の後ろにカンマを付けても良いといった、細かな文法上の工夫についても触れ、柔軟な記述方法を学ぶ。

③  列挙型の標準メソッドを自由に使いこなせるようになることの理解まで。
Javaの列挙型は、単なる「便利なラベル」ではない。実はその正体は、Javaが裏側で自動的に生成してくれている「特別なクラス」である。この仕組みを理解することで、なぜ列挙型が強力なのかが明確になる。
授業では、すべての列挙型が共通して持っている便利な「標準メソッド」を一つずつ動かしていく。まずは values()メソッドである。これを使うと、定義したすべての選択肢を配列として一気に取り出すことができる。拡張for文と組み合わせれば、「すべての季節を順番に表示する」といった処理が驚くほど簡単に書ける。
次に、ordinal()メソッドと name()メソッドを確認する。列挙型の各要素には、定義した順に「0, 1, 2...」という背番号(序数)が自動的に割り振られている。また、定義した名前そのものを文字列として取得することも可能である。更に、文字列から対応する列挙型を見つけ出す valueOf()メソッドも扱う。
「なぜ、自分で何も書いていないのにこんな便利なメソッドが使えるのか」。それは、全ての列挙型が java.lang.Enumという親クラスの機能をこっそり受け継いでいるからである。この「列挙型もまたオブジェクトである」という視点を持つことで、Javaという言語の一貫した設計思想が見えてくる。実習では、これらのメソッドを組み合わせて、データの「変換・表示・一括処理」を行うプログラムを作成する。単に値を制限するだけでなく、制限された値をいかに効率よく扱うかという実践的なスキルを磨く。

キーワード ① 列挙型(enum) Enumクラス nameメソッド ordinalメソッド valuesメソッド valueOfメソッド
コマの展開方法 社会人講師 AL ICT PowerPoint・Keynote 教科書
コマ用オリジナル配布資料 コマ用プリント配布資料 その他 該当なし
小テスト 「小テスト」については、毎回の授業時間内に、LMS上において当該コマの小テスト(難易度表示付)
復習・予習課題 授業で作成した `Season`(四季)の enum を参考に、自分の身近な例(例:血液型、スマートフォンのOS、ゲームの難易度など)を enum で定義してみる。
そのenumを引数に受け取るメソッドを作成し、values()メソッドを使って全要素の「名前」と「背番号(序数)」を一覧表示するプログラムを完成させる。
◆次回授業の予習
次回(26コマ目)は、この列挙型を更にカスタマイズする方法を学ぶ。現在は「SPRING」という名前だけを扱っているが、実は列挙型には「春は3月から5月」といった「追加のデータ」を持たせたり、独自のメソッドを追加したりすることができる。予習として、「曜日」を列挙型で作る場合、その曜日の名前以外に「平日か休日か」という情報を持たせるにはどうすれば良いか、これまでの「クラス」の知識(フィールドやコンストラクタ)をヒントに想像しておくこと。また、多数の選択肢から複数の項目を選び出す際に便利な「EnumSet」についても、どのような場面で使えそうか(例:定休日の管理など)を考えておくこと。

26 列挙型のメンバー定義とビットフィールド 科目の中での位置付け 本コマは、第25コマで学習した「列挙型の基本構文と内部構造」を受け、列挙型を単なる定数の集合ではなく、振る舞いや意味を持つ型として設計する方法を学ぶ位置づけにある。
前半では、列挙型がクラスとして振る舞うことを踏まえ、フィールド・コンストラクター・メソッドを定義することで、「定数+付加情報」や「定数ごとの振る舞い」を表現できることを理解する。
後半では、従来から用いられてきたビットフィールドによるフラグ管理を取り上げ、その仕組みと利点・欠点を確認した上で、EnumSet を用いた現代的な設計方法へとつなげる。
本コマを通して、「列挙型で何を表現したいのか」「どの設計が読みやすく、安全か」という設計視点を身に付けることを目的とする。

第26回テキスト 
第3章 「オブジェクト指向構文」 第1節「列挙型」
項目2「列挙型のメンバー定義とビットフィールド」
コマ主題細目 ① 列挙型へのフィールド・コンストラクター・メソッド定義 ② 列挙定数ごとの振る舞いの実装 ③ ビットフィールドとEnumSetによるフラグ管理
細目レベル ① 列挙型にメンバーを定義し、意味を持った定数として扱えるようになることの理解まで。
最初に、列挙型が内部的にはクラスとして定義されており、フィールド・コンストラクター・メソッドを持つことができる点を確認する。Season列挙型を例に、各季節に対応する表示用名称や数値コードといった「列挙定数そのもの以外の情報」をフィールドとして定義し、列挙定数ごとに異なる値を保持できることを、実際のコード例と出力結果を通して確認する。
その際、getNameやgetCodeといったアクセサメソッドを用いることで、列挙定数が「値を返すオブジェクト」として振る舞うことを理解させる。
ここでは、ordinal メソッドによって得られる順序番号が、定義順の変更や定数の追加によって容易に変化してしまうことを確認し、設計上の値として用いるべきでない理由を整理する。その上で、「順序番号」ではなく、「意味を持った値」を明示的なフィールドとして定義することが、安全で意図の伝わりやすい設計につながることを強調する。
あわせて、列挙型のコンストラクターに関する制約(private固定であり、new による生成ができないこと)を確認し、「列挙定数の宣言そのものがインスタンス生成を兼ねている」という列挙型特有の仕組みを理解させる。これにより、列挙型が「単なる定数の集まり」ではなく、「あらかじめ決められた数のインスタンスを持つクラス」であることを意識させる。

② 列挙定数ごとに異なる振る舞いを定義できるようになることの理解まで。
次に、列挙型に抽象メソッドを定義し、各列挙定数ごとに異なる実装を持たせる方法を扱う。Season 列挙型を例に、showメソッドを抽象メソッドとして定義し、SPRING・SUMMER・AUTUMN・WINTER の各定数において、それぞれ異なる処理内容を実装する例を通して、「列挙定数そのものが振る舞いを持つ」ことを確認する。実行結果を比較することで、同じメソッド呼び出しであっても、定数によって動作が切り替わることを体感させる。
ここでは、if 文や switch 文を用いて季節ごとに分岐する設計例と、列挙定数自身に処理を持たせる設計例を並べて示し、後者では分岐条件がコード上に現れず、処理の対応関係が明確になる点を確認する。特に、新しい定数を追加する場合に、条件分岐を修正する必要がないことから、可読性や拡張性の面で優れていることを理解させる。
あわせて、「すべての列挙定数で共通となる処理」は列挙型本体のメソッドとして定義し、「定数ごとに異なる処理」は抽象メソッドの実装として分離するという設計の考え方に触れる。これにより、共通部分と差分を明確に分けて記述できることを確認し、列挙型が単なる定数管理の仕組みではなく、振る舞いを内包したオブジェクトとして、オブジェクト指向設計において重要な役割を果たすことを意識させる。

③ ビットフィールドによるフラグ管理の考え方と、その代替手法の理解まで。
後半では、従来から利用されてきたビットフィールドによるフラグ管理を取り上げる。2 の累乗を用いてフラグを定義し、ビット論理和(|)で複数の状態をまとめ、ビット論理積(&)で特定のフラグの有無を判定する仕組みを、正規表現の Patternクラスを例に確認する。
この手法が「1つの整数で複数のオン/オフを管理できる」という点で効率的である一方、コードの意図が読み取りにくく、拡張や保守が難しくなる場合があることも整理する。その上で、列挙型と EnumSet クラスを用いたフラグ管理を紹介しcontains や 拡張 for 文を用いて、設定されているフラグを順に確認することで、「何が有効になっているのか」をコードからそのまま読み取れる設計が可能になることを示す。
ここでは、「ビット操作を否定する」のではなく、仕組みを理解した上で、より安全で読みやすい APIが用意されている理由を理解させることを重視する。

キーワード ① 列挙型(enum) フィールド定義 ビットフィールド 論理和(|) 論理積(&)EnumSet フラグ管理
コマの展開方法 社会人講師 AL ICT PowerPoint・Keynote 教科書
コマ用オリジナル配布資料 コマ用プリント配布資料 その他 該当なし
小テスト 「小テスト」については、毎回の授業時間内に、LMS上において当該コマの小テスト(難易度表示付)
復習・予習課題 ◆今回授業の復習
列挙型を一つ定義し、定数ごとに表示名や数値コードなどのフィールドを持たせたプログラムを作成する。可能であれば、抽象メソッドを用いて、列挙定数ごとに異なる処理を実装し、「条件分岐を使わない設計」の利点を整理する。
◆次回授業の予習
次回は「列挙型演習」として、これまで学習した列挙型の構文・設計方法を総合的に扱う。列挙型で表現できそうなもの(状態、種類、モードなど)を日常やプログラムの例から考えておく。

27 列挙型演習 科目の中での位置付け 本コマは、第25コマ「列挙型の基本構文と内部構造」および第26コマ「列挙型のメンバー定義とビットフィールド」で学習した知識を、実際のシステム開発に近いシナリオを通して定着させる演習回である。
これまでの学習で、単なる定数管理(static final)が抱える「型安全性の欠如」というリスクと、それを克服する列挙型の強力な保護機能を理解してきた。
本コマでは、銀行口座の「口座種別」の管理を題材に、新米プログラマが陥りがちな設計ミスをあえてトレースし、それを列挙型でリファクタリング(改善)する過程を体験する。これにより、文法知識を「なぜその技術を使うのか」という設計思想へと昇華させ、堅牢なプログラムを書くための実践力を養う。

第27回テキスト 
第3章 「オブジェクト指向構文」 第1節「列挙型」
項目3「列挙型演習」
コマ主題細目 ① String型・int型による状態管理の限界 ② 列挙型による型安全な設計への改善 ③ 列挙型機能を用いた実務的データ処理
細目レベル ① 「自由すぎる型」が招くバグのリスクを、具体的なコードから特定できるようになることの理解まで。
演習の導入として、口座クラス(Accountクラス)の開発プロジェクトに配属されたという設定で、二人のプログラマの失敗例を分析する。まず、口座種別をString型で管理する「Aバージョン」を実行し、本来「普通」「当座」「定期」しかないはずの種別に、空文字や全く関係のない文字列(“その他”、“「」(空白)”“null”など)が指定できてしまう危うさを確認する。次に、int型定数で改善を試みた「Bバージョン」を動かし、コンパイルは通るものの「999」のような無効な数値が渡されるリスクが依然として残っていることを確認する。
ここでは、「型が広すぎる(入れられる値の種類が多すぎる)」ことが、いかに人為的なミスを誘発し、発見の遅いバグ(実行時エラー)を生む原因になるかを言葉で説明できるようにする。

② 列挙型を用いて、特定の選択肢以外を「書くことすらできない」強固なクラスへ作り変えられるようになることの理解まで。
次に、この問題を根本から解決するために「AccountType」という列挙型を定義する。Accountクラスのコンストラクタの引数を、intやStringではなく、自作した AccountType型に書き換える演習を行う。これにより、IDE(開発環境)の補完機能で正しい選択肢が提示され、間違った値を渡そうとすると即座にコンパイルエラーが出る様子を確認する。
ここでは、列挙型が単なる「名前のリスト」ではなく、不正なデータを入り口で遮断する「鉄壁のフィルター」として機能することを、コードを書き換える前後の安心感の違いを通して実感させる。

③ 列挙型の標準機能を活用し、実用的な口座情報管理プログラムを完成させることの理解まで。
演習の後半では、列挙型が持つ標準メソッド(valuesやvalueOfなど)を活用した処理を追加する。
例えば、「現在扱っている全ての口座種別をメニューとして一覧表示する処理」を values() メソッドと拡張for文で実装し、将来的に「積立」などの種別が増えても表示ロジックを修正する必要がない(保守性が高い)設計を体験する。
また、第26コマの発展内容として、ビットフィールドによる管理(Patternクラスなどの例)についても軽く触れ、フラグ管理の歴史的背景とEnumSetへの移行のメリットを再確認する。ただし本演習の主眼は「基本構文による型安全の確保」に置き、列挙型のインスタンスがそのままオブジェクトとして振る舞う感覚を養う。
最終的に、「完成版Accountクラス」を自力で実装し、安全で美しいコードの価値を理解する。

キーワード ① 型安全(Type Safety) 列挙型(enum) AccountType リファクタリング コンパイル時チェック 定数管理の改善
コマの展開方法 社会人講師 AL ICT PowerPoint・Keynote 教科書
コマ用オリジナル配布資料 コマ用プリント配布資料 その他 該当なし
小テスト 「小テスト」については、毎回の授業時間内に、LMS上において当該コマの小テスト(難易度表示付)
復習・予習課題 ◆今回授業の復習
演習で作成した Accountクラスを参考に、列挙型を使わない場合と使う場合で「間違った値を渡した時の動作(エラーが出るタイミング)」がどう変わるかをまとめる。
また、学んだ static インポートを利用して、AccountType.FUTSUを FUTSUと簡潔に記述するようコードを修正してみる。
◆次回授業の予習
次回(28コマ目)は、JDK16から導入された「レコード(Record)」という新しい型を学習する。
今回の演習で作成した Accountクラスのように、「データを保持するためだけのクラス」をより簡潔かつ安全に書くための仕組みである。予習として、クラスを作る際に毎回書いている「フィールド、コンストラクタ、ゲッター」の記述を、もっと短縮できるとしたらどう書けるか想像しておく。

28 レコードの基本(JDK16) 科目の中での位置付け 本コマは、第3章「オブジェクト指向構文」における新しい構文要素として、Java16で正式導入された「レコード(Record)」を学ぶ回として位置づけられる。
これまでの学習では、class命令を用いて、フィールド・コンストラクター・ゲッター・equals/hashCode/toStringといった定型的なメンバーを自ら実装してきた。しかし、実際のアプリケーションでは、振る舞いよりも「データのまとまり」を表現することを主目的としたクラスが多く存在し、そうしたクラスでは同様のコードが繰り返し記述されがちである。
レコードは、このようなデータ中心のクラスを簡潔かつ安全に表現するための仕組みであり、冗長な記述を減らすと同時に、イミュータブルな設計を標準化する役割を担っている。
本コマでは、レコードの基本構文と自動生成されるメンバーの内容を理解し、従来のクラス定義との違いを整理することで、次回扱うパターンマッチングや、後続のオブジェクト指向構文の理解につなげることを目的とする。

【教材・教具】
第28回テキスト 
第3章 「オブジェクト指向構文」 第2節「レコード」
項目1「レコードの基本(JDK16)」
コマ主題細目 ① レコードの基本構文と導入背景 ② 自動生成されるメンバー(コンストラクター・equals・toString等) ③ レコードの生成・比較・文字列表現の特徴
細目レベル ① レコードがデータを表現するための専用構文であることの理解まで。
まず、カプセル化の意義(フィールドを直接操作させず、メソッドを通して安全に扱うことでデータの整合性や保守性を高める考え方)を復習した上で、通常の class定義でデータクラスを作成した場合に必要となるメンバー(フィールド、コンストラクター、ゲッター、equals/hashCode/toString)を確認し、それらが定型的である一方、記述量が多く、実装ミスの温床になりやすい点を整理する。その上で、record命令を用いた宣言構文を紹介し、「型 フィールド名」を並べたレコードヘッダーによって、これらの定型メンバーが自動生成されることを確認する。ここでは、レコードが通常のクラスと同様にオブジェクト指向の一部でありながら、「用途を限定した構文」である点を強調し、何でもレコードで置き換えるものではないことを意識させる。

② レコードにおいて自動生成されるメンバーの役割の理解まで。
次に、簡単な Personレコードを例に、コンストラクター、フィールド名と同名のアクセサメソッド、equals/hashCode、toStringが自動生成されていることを、実行結果を通して確認する。特に、equalsメソッドが「参照の一致」ではなく、「全フィールドの値の一致」に基づいて生成される点に注目し、レコードが「値としての同一性」を表現するための仕組みであることを理解させる。また、レコードが暗黙的に java.lang.Recordを継承したfinalクラスであることを示し、継承ができない理由や、フィールドが暗黙的に final である点から、イミュータブルな設計が標準であることを確認する。これにより、スレッド安全性や値の受け渡しに適した設計であることを、概念的に理解させる。

③ レコードの生成・検証・利用方法の理解まで。
続いて、new演算子によるレコードのインスタンス化を確認し、通常のクラスと同様に扱えることを整理する。あわせて、正規コンストラクター(Canonical Constructor)を定義することで、生成時に値の検証や補正を行えることを紹介する。
ここでは、引数を明示的に受け取らず、レコードヘッダーで宣言されたコンポーネントが暗黙の引数として使われている点に注意を向けさせ、this を用いたフィールド代入が禁止されている理由を確認する。
最後に、printlnによる出力結果を通して、toStringによる文字列表現が自動生成されていることを再確認し、「レコードは値オブジェクトとしてそのまま扱える」ことを理解させる。本コマを通して、レコードが「データの受け渡しを安全かつ簡潔に行うための構文」であることを定着させる。

キーワード ① record イミュータブル 自動生成メンバー equals/hashCode toString Canonical Constructor
コマの展開方法 社会人講師 AL ICT PowerPoint・Keynote 教科書
コマ用オリジナル配布資料 コマ用プリント配布資料 その他 該当なし
小テスト 「小テスト」については、毎回の授業時間内に、LMS上において当該コマの小テスト(難易度表示付)
復習・予習課題 ◆今回授業の復習
任意のデータ(例:商品情報、学生情報、座標データなど)を題材として、① 通常の class定義と、② record定義の2通りでコードを記述し、記述量や可読性の違いを比較する。その上で、「なぜレコードが有効なのか」をまとめる。
◆次回授業の予習
次回は、レコードと組み合わせて用いられる「パターンマッチング」を扱う。instanceofを用いた型判定と、その後のキャスト処理について、これまでに学んだ書き方を振り返っておくこと。

29 レコード型のパターンマッチング 科目の中での位置付け 本コマは、第28コマ「レコードの基本(JDK16)」で学習したレコード型の定義と利用を踏まえ、Java 21 以降で正式に導入された「レコード型のパターンマッチング」について学ぶ回である。
これまでの instanceof 演算子や switch 文では、型判定の後にキャストを行い、アクセサメソッドを通してフィールドを取り出す必要があった。本コマでは、パターンマッチングを用いることで、型判定と同時にレコードの構成要素を分解し、より簡潔で安全な記述が可能になることを理解する。
特に、オブジェクト指向における「データ構造としてのオブジェクト」を、条件分岐の中でどのように扱うかという観点から、従来の記述方法との違いを整理し、可読性・保守性の高いコードを書くための新しい表現手法を身に付けることを目的とする。

第29回テキスト 
第3章 「オブジェクト指向構文」 第2節「レコード」
項目2「レコード型のパターンマッチング」
コマ主題細目 ① instanceofにおけるレコード型パターンマッチング ② switch文によるレコード分解パターン ③ ネスト構造・ジェネリック型に対するパターン適用
細目レベル ① instanceof演算子を用いて、レコード型の分解ができるようになることの理解まで。
最初に、入力データの種類に応じて処理を分岐する(例:異なる形式のデータをまとめて扱う、メッセージ種別ごとに処理を変えるなど)場面をデモサンプルアプリで示し、型に応じた分岐処理が必要となる状況を理解させる。その上で、Object型の変数に格納されたレコードインスタンスを instanceof 演算子で判定し、その際にレコードの構成要素を同時に取り出す基本構文を確認する。従来の「instanceof → キャスト → アクセサ呼び出し」という手順と比較し、パターンマッチングでは型判定と分解が一体化していることを理解させる。
そのうえで、Object型の変数に格納されたレコードインスタンスをinstanceof演算子で判定し、その際にレコードの構成要素を同時に取り出す基本構文を確認する。従来の「instanceof → キャスト → アクセサ呼び出し」という手順と比較し、パターンマッチングでは型判定と分解が一体化していることを理解させる。
次に、varを用いた型推論による記述と、String や int など型を明示した記述の両方を示し、参照型では上位型を指定できる一方で、プリミティブ型では厳密な一致が必要である点を確認する。また、レコード定義時のフィールド順と、パターン側での変数の対応関係に注意を向け、名前を変更できる場合とできない場合の違いを整理する。あわせて、Java 21 で導入された無名変数「_」を用いることで、不要なフィールドを明示的に無視できることを紹介し、「必要な情報だけを取り出す」意図がコード上で表現できる点を理解させる。

② switch文におけるレコード型パターンマッチングの基本的な使い方の理解まで。
次に、switch文にレコード型のパターンマッチングを適用する例を扱う。異なるレコード型を case句で判定し、それぞれの構成要素を取り出して処理する例を通して、switch が「値の分岐」だけでなく「構造による分岐」にも使えることを確認する。
ここでは、異なる case句で同名の変数を使用できる点に触れ、各 case が独立したスコープとして扱われていることを理解させる。一方で、フォールスルーが許可されない理由についても説明し、変数の意味的な安全性を保つための言語仕様であることを整理する。
あわせて、従来の switch 文と比較しながら、「分岐条件が型と構造で表現できる」ことの利点を意識させ、条件分岐の可読性がどのように向上するかを確認する。

③ 複雑なレコード構造に対するパターンマッチングの考え方の理解まで。
後半では、より発展的な例として、ネストされたレコードやジェネリック型レコードに対するパターンマッチングを扱う。
まず、レコードの中に別のレコードが含まれている場合に、パターン側も同様にネストさせることで、内部の値を直接取り出せることを確認する。これにより、「オブジェクトを段階的にたどる」のではなく、「構造として分解する」発想が重要であることを理解させる。
次に、ジェネリック型のレコードを例に、保持している値の型に応じて処理を分岐する switch 式を確認する。ここでは、ジェネリクスとパターンマッチングが組み合わさることで、型安全かつ簡潔な分岐処理が可能になる点を示す。
詳細な型推論の仕組みには踏み込まず、「レコードはデータ構造を表し、パターンマッチングはその構造を安全に取り出すための仕組みである」という位置づけを明確にする。
最後に、これらの内容を整理・定着させるため、ネスト構造や型に応じた分岐を含むまとめの演習を実施し、理解の定着を図る。

キーワード ① レコード型 パターンマッチング instanceof switch文 ネストされたレコード ジェネリック型レコード
コマの展開方法 社会人講師 AL ICT PowerPoint・Keynote 教科書
コマ用オリジナル配布資料 コマ用プリント配布資料 その他 該当なし
小テスト 「小テスト」については、毎回の授業時間内に、LMS上において当該コマの小テスト(難易度表示付)
復習・予習課題 ◆今回授業の復習
簡単なレコード型を一つ定義し、instanceof または switch 文を用いて、レコードの構成要素を取り出して処理するプログラムを作成する。
従来のキャスト+アクセサ呼び出しによる記述と比較し、「どこが簡潔になったか」「安全性がどのように高まったか」を文章で整理する。
◆次回授業の予習
次回は、staticメンバークラスと非 staticメンバークラスを扱う。
クラスの「内側」にクラスを定義することで、どのような情報共有や設計上の利点が考えられるかを、これまでに学んだクラス設計と結び付けて考えておくこと。

30  staticメンバークラスと非staticメンバークラス 科目の中での位置付け 本コマは、第28コマ「レコードの基本」、第29コマ「レコード型のパターンマッチング」に続き、Java における「クラス定義のバリエーション」を学ぶ位置づけにある。
これまでの学習では、クラスは原則としてトップレベルで定義するものとして扱ってきたが、実際のJavaプログラムでは、特定のクラスに強く結び付いた補助的なクラスを、入れ子構造として定義する場面が多く存在する。
本コマでは、「入れ子のクラス(Nested Class)」のうち、staticメンバークラスと非staticメンバークラスを取り上げ、それぞれがどこに属し、何にアクセスでき、どのような設計意図で使われるのかを整理する。
構文の暗記ではなく、「なぜstaticを付けるのか」「なぜ非staticにするのか」という判断基準を理解し、次コマ以降の匿名クラス・ローカルクラスや、コレクション内部実装の理解につなげることを目的とする。

第30回テキスト 
第3章 「オブジェクト指向構文」 第3節「入れ子クラス」
項目1「staticメンバークラスと非staticメンバークラス」
コマ主題細目 ① 入れ子クラスの分類とstaticメンバークラス ② 非staticメンバークラスとエンクロージングオブジェクト ③ static/非staticメンバークラスの設計上の使い分け
細目レベル ①  staticメンバークラスの役割と基本的な使い方の理解まで。
最初に、クラスをクラスの中に定義できることを確認し、これを「入れ子のクラス(Nested Class)」と呼ぶことを整理する。その上で、入れ子のクラスが staticメンバークラスと内部クラス(非staticメンバークラス・匿名クラス・ローカルクラス)に分類されることを示す。
staticメンバークラスについては、「特定のクラスからのみ利用される補助的なクラス」を想定し、トップレベルクラスとして分離した場合との違いを比較する。private 修飾子を付けることで、同一ファイル・同一パッケージ内であっても外部から不可視にできる点を確認し、「ファイル構成」ではなく「アクセス制御」によって関連性を表現できることを理解させる。
あわせて、エンクロージングクラスの内部では単純なクラス名で利用できること、外部からは「エンクロージングクラス名.入れ子クラス名」という型名で表されること、コンパイル後に Outer$Inner.class というクラスファイルが生成される点を確認し、構文と実行結果の対応関係を整理する。

② 非staticメンバークラスの性質と動作の理解まで。
static を付けない非staticメンバークラスを取り上げ、staticメンバークラスとの決定的な違いが「属する対象」にあることを確認する。
非staticメンバークラスはエンクロージングオブジェクトに属し、その生成にはエンクロージングクラスのインスタンスが必要である点を、コード例を通して確認する。非staticメンバークラスからは、「エンクロージングクラス名.this」 を通して、エンクロージングクラスのインスタンスフィールドやメソッドに直接アクセスできることを示し、「内部状態と強く結び付いた処理」を表現するための仕組みであることを理解させる。
一方で、非staticメンバークラスが暗黙的にエンクロージングオブジェクトへの参照を保持するため、不要な参照が残ることでメモリ使用やオブジェクト破棄に影響を与える可能性がある点にも触れ、安易に使うべきではないことを強調する。

③ static/非staticメンバークラスの使い分けを設計の観点から説明できるようになることの理解まで。
最後に、両者の違いを整理し、「エンクロージングクラスのインスタンス状態に依存するかどうか」という判断基準で使い分けることを明確にする。
staticメンバークラスは、エンクロージングクラスの設計上の一部ではあるが、インスタンス状態には依存しない補助的な役割を担う場合に適している。一方、非staticメンバークラスは、エンクロージングクラスの privateフィールドと密接に連携する処理を表現するために用いられる。
具体例として、AbstractList における Iterator 実装を取り上げ、private な非staticメンバークラスを用いることで、カプセル化を維持したまま内部構造にアクセスできる設計が可能であることを確認する。
本コマを通して、「書けるかどうか」ではなく、「なぜその形で定義するのか」を説明できることを重視し、次回扱う匿名クラス・ローカルクラスへの理解の土台を形成する。

キーワード ① 入れ子のクラス(Nested Class) staticメンバークラス 非staticメンバークラス エンクロージングクラス Outer.this
コマの展開方法 社会人講師 AL ICT PowerPoint・Keynote 教科書
コマ用オリジナル配布資料 コマ用プリント配布資料 その他 該当なし
小テスト 「小テスト」については、毎回の授業時間内に、LMS上において当該コマの小テスト(難易度表示付)
復習・予習課題 ◆今回授業の復習
課題コードを例示し、staticメンバークラスと非staticメンバークラスは、それぞれどのようなタイミングでインスタンス化されるか、それぞれがエンクロージングクラスのメンバーにアクセスできるかどうか、mainメソッドの出力結果はどうなるかを確認させる。
◆次回授業の予習
次回は、匿名クラスとローカルクラスを扱う。「その場限りで使うクラス」が必要になりそうな場面を考え、通常のクラス定義では不便に感じる点を整理しておく。

31 匿名クラスとローカルクラス 科目の中での位置付け 本コマは、第30コマ「staticメンバークラスと非staticメンバークラス」に続き、クラス定義のスコープを更に限定した形である「匿名クラス」と「ローカルクラス」を学習する回である。
これらは、入れ子クラスの中でも特に「特定の処理のまとまりを、その場限りで表現する」ために用いられる仕組みであり、クラスを再利用することを前提としない点に特徴がある。
業務プログラムやGUI、イベント駆動型処理では、「ある処理にだけ対応する小さなクラス」を一時的に定義したい場面が多く存在する。本コマでは、そうした場面において、クラスを独立して定義するのではなく、文脈の中に埋め込むという設計の考え方を理解させる。
また、匿名クラスは Java 8以降、ラムダ式へと置き換えられることが多い構文である。本コマは、次回以降に学習するラムダ式の理解に向けて、「従来の書き方が何をしていたのか」を整理する重要な前段階として位置づけられる。

第31回テキスト
第3章「オブジェクト指向構文」 第3節「入れ子クラス」
項目2「匿名クラスとローカルクラス」
コマ主題細目 ①  匿名クラスの基本構文と利用目的 ②  匿名クラスの制約と使用上の注意 ③  ローカルクラスの特徴と匿名クラスとの比較
細目レベル ① 匿名クラスの役割と基本構文の理解まで。
まず、匿名クラスが「クラスでありながら名前を持たない」という特徴を持ち、特定の場所・特定の処理のためだけに使われる一時的なクラスであることを確認する。通常のクラスのように別ファイルとして定義したり、後から何度も呼び出したりすることは想定されておらず、「その場限りの処理」をまとめるための仕組みである点を強調する。
次に、匿名クラスの基本構文として、`new基底クラスまたはインターフェイス名(){ ... }` という形を示し、new演算子の直後でクラス定義とインスタンス生成を同時に行っていることを丁寧に説明する。ここでは、「クラス定義 → インスタンス生成 → 利用」という通常の流れが、匿名クラスでは、一文の中に凝縮されている点を、通常のクラス定義と対比させながら整理する。
具体例として、イベントリスナーを取り上げ、インターフェイスを実装した匿名クラスを生成し、そのインスタンスをそのままメソッドの引数として渡しているコードを確認する。この例を通して、処理内容と利用箇所が物理的に近くなることで、コードの意図が追いやすくなることを理解させる。
また、匿名クラスが「何かの振る舞いを一まとまりの処理として表すための器」として使われている点に注目し、再利用を前提としないクラス設計という考え方を身に付けさせる。

②  匿名クラスの制約と適切な利用範囲の理解まで。
次に、匿名クラスが通常のクラスと同じように見えても、いくつかの重要な制約を持つことを整理する。具体的には、コンストラクターを定義できないこと、他のクラスを継承できない(暗黙的に finalである)こと、抽象クラスとして宣言できないことを一つずつ確認し、自由度は高くないクラスである点を理解させる。
あわせて、匿名クラスは式の中に直接書けるという利点がある一方で、処理内容が長くなりすぎると、コードの流れが一気に読みづらくなるという欠点があることを指摘する。ここでは、処理が増えていく例を示しながら、便利だからといって何でも詰め込むと、かえって理解しづらくなることを具体的に示す。実務上は、おおよそ10行程度までを目安とし、短く・限定的な処理に使うのが望ましいという指針を紹介する。この段階では、匿名クラスを「書けるかどうか」ではなく、「この処理は匿名クラスに向いているかどうか」を判断できることを重視する。「再利用しない」「その場で完結する」「処理が短い」といった条件がそろったときに選択すべき仕組みであることを強調する。

③  ローカルクラスの特徴および匿名クラスとの違いの理解まで。
後半では、ローカルクラスを取り上げる。ローカルクラスとは、メソッドやコンストラクターなどのブロック内部で定義され、そのブロックの中でのみ利用できるクラスであることを確認する。ここでは、ローカル変数のスコープと対比させ、「クラスにも有効範囲がある」という感覚を持たせる。匿名クラスとの違いとして、ローカルクラスには必ず名前を付ける必要があること、また、アクセス修飾子や static 修飾子を指定できない点を整理する。その上で、同じ処理内容を匿名クラスとローカルクラスの両方で記述した例を比較し、「名前を付けることで構造は明確になるが、その分コード量が増える」ことを確認する。
この比較を通して、「名前を付けることによる可読性の向上」と「一時的な処理に名前を付ける手間」とのトレードオフを考えさせる。多くの場合、ローカルクラスは匿名クラスで代替できるため、実務での利用頻度が高くない理由にも触れる。

キーワード ① 匿名クラス ローカルクラス イベントリスナー インターフェイス実装 スコープ
コマの展開方法 社会人講師 AL ICT PowerPoint・Keynote 教科書
コマ用オリジナル配布資料 コマ用プリント配布資料 その他 該当なし
小テスト 「小テスト」については、毎回の授業時間内に、LMS上において当該コマの小テスト(難易度表示付)
復習・予習課題 ◆今回授業の復習
課題コードを例示し、インターフェイスの実装方法として、通常のクラス・ローカルクラス・匿名クラスの違いを説明すること、各実装方法はどのような場面に適しているか、mainメソッドの出力結果はどうなるかを確認させる。
◆次回授業の予習
匿名クラスは、Java 8以降ではラムダ式で書き換えられることが多い。「匿名クラスで1つのメソッドだけを実装している例」を探し、「これをより短く書けそうか」という観点でコードを眺めておくこと。

32 ラムダ式を使わない従来の記述方法とメソッド参照 科目の中での位置付け 本コマは、第4章「ラムダ式/Stream API」の学習をするための導入段階として位置づけられる回である。Java 8 でラムダ式が導入される以前、Javaでは「処理そのもの」を引数として渡すことができなかったため、インターフェイス・具象クラス・匿名クラスといった仕組みを用いて振る舞いを表現してきた。本コマでは、そのようなラムダ式を使わない従来の記述方法を具体例を通して整理する。
特に、処理の流れ(枠組み)と処理の中身(差し替えたい部分)をどのように分離しようとしていたのかに注目し、後続の「メソッド参照」「ラムダ式」が 何を簡潔にしたのか を理解するための土台を作ることを目的とする。

第32回テキスト
第4章「ラムダ式/Stream API」 第1節「ラムダ式」
項目1「ラムダ式を使わない従来の記述方法とメソッド参照」
コマ主題細目 ① 従来の処理記述方法(具象クラス・匿名クラス) ② 関数型インターフェイスの役割 ③ 理の共通部分と差し替え部分の分離設計
細目レベル ① ラムダ式を用いない場合の典型的な処理の書き方の理解まで。
まず、配列やコレクションに格納された複数の要素を、先頭から順に取り出し、各要素に対して同じ処理を繰り返すという、Java における最も基本的な処理の流れを確認する。具体的には、拡張 for文を用いた単純なループ処理を題材とし、「① 要素を1つずつ取り出す処理」と「② 取り出した要素に対して行う具体的な処理」が、同じ場所にまとめて記述されていることを理解させる。その上で、例えば「表示の仕方を変えたい」「条件によって処理内容を少しだけ変えたい」といった要望が出てきた場合を想定し、従来の書き方では、処理内容の違いごとに似たようなメソッドを複数作成せざるを得なくなることを確認する。これにより、「本来は一部分だけ変更したいにもかかわらず、ループ処理を含むメソッド全体を増やしてしまっている」という、保守性や再利用性の低い状態が生じることを理解させる。

② 関数型インターフェイスが「メソッドの型」を表す仕組みであることの理解まで。
次に、処理内容の差し替えを可能にする手段として、関数型インターフェイスの考え方を導入する。ここでは、「メソッドもデータと同様に、型として扱うことができる」という Java 8以降の基本的な発想を前提としつつ、ラムダ式やメソッド参照はまだ使用せず、これまでに学習してきた従来どおりのメソッド定義とクラス実装を用いて説明する。
初めに、なぜ関数型インターフェイスが必要になるのかを確認する。たとえば、同じ流れの処理の中で**「一部の処理だけをあとから差し替えたい」場面では、処理全体を毎回書き直すのではなく、差し替える部分だけを部品として渡せると便利である。関数型インターフェイスは、このような場面で、「どのような引数を受け取り、どのような値を返す処理を渡せるか」を型として表現するために用いられることを理解させる。あわせて、イベント処理、条件判定、計算方法の切り替えなど、実際に処理の差し替えが有効な場面を挙げ、通常のクラス実装よりも柔軟に振る舞いを切り替えられることを確認する。
その上で、関数型インターフェイスが、「引数の個数や型」「戻り値の型」といったメソッドの形(シグネチャ)そのものを定義する役割を持つことを整理する。ここでは、実際にはメソッド名そのものは本質ではなく、どのような形の処理を受け渡すかが重要であることを、複数の具体例を通して確認する。
さらに、関数型インターフェイスの条件として、抽象メソッドが 1 つだけであることを説明する。その際、default メソッドや static メソッドを定義しても関数型インターフェイスとして成立すること、また Object クラス由来の equals、hashCode、toString などのメソッドは抽象メソッドの数に含まれないことを、具体例を用いて確認する。これにより、単に「メソッドが 1 つだけ書かれているインターフェイス」ではなく、「処理を 1 つのまとまりとして扱うための型」であることを理解させる。
あわせて、@FunctionalInterface アノテーションも紹介する。これは、「このインターフェイスは関数型インターフェイスとして使う意図がある」ことを明示するための記述であり、もし抽象メソッドを誤って 2 つ以上定義してしまった場合には、コンパイラが設計ミスを検出してくれるという利点がある。このため、@FunctionalInterface は文法上必須ではないが、意図を明確にし、保守や実務での安全性を高める重要な書き方であることも理解させる。
関数型インターフェイスが、「引数の個数や型」「戻り値の型」といったメソッドの形(シグネチャ)そのものを定義する役割を持つことを確認し、実際にはメソッド名そのものは本質ではない点を整理する。また、抽象メソッドが1つだけであることが関数型インターフェイスの条件であること、defaultメソッドやObjectクラス由来のメソッドは抽象メソッドの数に含まれないことを、具体例を通して確認する。

③ 処理の枠組みと具体的な処理内容を分離した設計についての理解まで。
最後に、配列やコレクションを順に走査する処理そのものは共通のままとし、各要素に対して何を行うかという部分だけを外部から受け取る設計例を確認する。具体的には、walkArray のようなメソッドを題材とし、ループによる走査処理は一切変更せずに、引数として渡す処理だけを差し替えることで、表示処理・集計処理・条件判定などを柔軟に切り替えられることを理解させる。このとき、従来の書き方では「処理を表すメソッドを引数として渡す」ために、関数型インターフェイスという受け皿が必要になることを再確認する。結果としてコード量は増えるものの、その分、処理の共通化が進み、拡張しやすく再利用性の高い設計になっている点を整理する。
本コマのまとめとして、「ラムダ式とは、ここまでに確認した仕組み(関数型インターフェイス+処理の差し替え)を、より簡潔に記述するための省略記法である」ことを示し、次回のラムダ式の基本構文の学習へとつなげる。

キーワード ① 関数型インターフェイス SAM(Single Abstract Method) @FunctionalInterface 処理の差し替え 処理の共通化
コマの展開方法 社会人講師 AL ICT PowerPoint・Keynote 教科書
コマ用オリジナル配布資料 コマ用プリント配布資料 その他 該当なし
小テスト 「小テスト」については、毎回の授業時間内に、LMS上において当該コマの小テスト(難易度表示付)
復習・予習課題 ◆今回授業の復習
配列または List を順に処理するメソッドを一つ用意し、表示処理または、集計処理のいずれかを「外部から渡す処理」として設計した簡単なプログラムを作成する。処理の流れ(走査部分)と、差し替え可能な処理部分がどこで分かれているかを、コメントで説明すること。
◆次回授業の予習
同じ処理を、「もっと簡潔に書けそうだと感じる点」という視点で見直しておくこと。次回扱うラムダ式が、どの部分を省略しているのかを意識して読む。

33 ラムダ式の基本構文 科目の中での位置付け 本コマは、第4章「ラムダ式/Stream API」の導入部として、Javaにおけるラムダ式の基本的な考え方と構文を学習する回である。
前回(第32コマ)では、ラムダ式を使わない従来の記述方法として、通常のメソッド定義や匿名クラスを用いたコレクション操作を確認し、「処理を引数として渡す」ためにどのような冗長さが生じていたかを整理した。
本コマでは、その問題点を解消する仕組みとしてラムダ式を導入し、「その場限りで使う処理を、名前を付けずに直接記述できる」というラムダ式の役割を理解することを目的とする。
ラムダ式は、以降のコレクション操作や Stream API の理解に不可欠な基礎概念であり、本コマではまず「書き方に慣れる」「何を省略しているのかを理解する」ことに重点を置く。複雑な処理や実践的な応用は次回以降に扱い、本コマではあくまで基本構文の理解を到達点とする。

第33回テキスト
第4章「ラムダ式/Stream API」 第1節「ラムダ式」
項目2「ラムダ式の基本構文」
コマ主題細目 ① ラムダ式導入の背景と目的 ② ラムダ式の基本構文 ③ ラムダ式と関数型インターフェイス(Consumer等)の関係
細目レベル ① 「使い捨ての処理」を簡潔に表現する必要性についての理解まで。
初めに、第32コマで確認した従来の書き方を振り返り、walkArrayメソッドに処理を渡すためだけに addQuoteやaddLengthといった専用メソッドを定義することの冗長さを再確認する。これらのメソッドは再利用を目的としたものではなく、「その場で一度使うだけの処理」であるにもかかわらず、名前の決定、メソッド定義、クラス構造への配置といった手続きを必要としていた点に注目する。ここで、「名前は不要だが、処理そのものは必要」という場面が現実のプログラムでは頻繁に発生することを確認し、その問題を解決する仕組みとしてラムダ式が導入されたことを理解させる。
ラムダ式は、「メソッド定義を式(リテラル)として直接記述できる仕組み」であり、処理の中身だけを簡潔に引き渡すための道具である。この単なる書き方の省略として捉えるのではなく、処理を値として扱い、必要な場面に応じて柔軟に差し替えるための手段であることを、コード例を通して直感的に把握することを目的とする。
初めに、従来の匿名クラスによる実装とラムダ式を比較し、同じ処理をより簡潔に記述できることを確認する。これにより、特に一度しか使わない処理や短い処理において、コードの可読性が向上することを理解させる。また、ラムダ式の主な用途について具体例で示す。これらを通して、「処理を部品として扱う」ことができる点が最大の利点であることを確認する。

② ラムダ式の基本構文とその書き方についての理解まで。
次に、ラムダ式の基本構文、(引数リスト) -> { 処理内容 }を取り上げ、引数と処理本体が「->(アロー演算子)」で結ばれている構造を確認する。
ここでは、例示したコードを用い、匿名クラスで書かれていた処理が、ラムダ式によってどのように簡潔に表現できるようになったかを比較する。
特に、「メソッド名が不要になっていること」「accept メソッドの実装だけがそのまま残っていること」に注目し、「ラムダ式とは、匿名クラスから“推論できる情報”を削ぎ落とした形である」という見方を示す。
更に、本体が1文の場合に { } を省略できること、return を明示しなくても戻り値として扱われること、引数型が推論されるため型指定を省略できることなど、ラムダ式の簡略化ルールを段階的に整理する。最初から省略形だけを見るのではなく、非省略形 → 省略形という流れで追うことで、ラムダ式が「記号の暗記」ではなく「省略の積み重ね」であることを理解させる。

③ ラムダ式と関数型インターフェイスの関係についての理解まで。
最後に、walkArrayメソッドの第2引数として使用されている Consumerインターフェイスを取り上げ、ラムダ式がどのような型として扱われているのかを整理する。
Consumerは java.util.function パッケージで提供されている関数型インターフェイスであり、「引数を受け取り、戻り値を返さない処理」を表す型であることを確認する。ここでは、@FunctionalInterface アノテーションと、抽象メソッドが1つだけ定義されている点に注目し、「ラムダ式は、関数型インターフェイスの実装として扱われる」という基本原則を理解させる。また、Java標準APIには Consumer 以外にも、Function、Predicate、Supplier など、よく使われる処理パターンに対応した関数型インターフェイスが多数用意されていることを紹介し、「自分で新しいインターフェイスを作らなくても、多くの場合は標準APIで対応できる」という設計思想に触れる。
本コマでは一覧の暗記を目的とせず、「処理の形に名前が付いている」という感覚を持つことを重視し、次回以降のラムダ式・コレクション操作への橋渡しとする。

キーワード ① ムダ式 関数型インターフェイス Consumer java.util.function ->(アロー演算子) 匿名クラス
コマの展開方法 社会人講師 AL ICT PowerPoint・Keynote 教科書
コマ用オリジナル配布資料 コマ用プリント配布資料 その他 該当なし
小テスト 「小テスト」については、毎回の授業時間内に、LMS上において当該コマの小テスト(難易度表示付)
復習・予習課題 ◆今回授業の復習
walkArray メソッドを用いた簡単なプログラムを作成し、
・匿名クラスを用いた場合
・ラムダ式(省略しない形)を用いた場合
・ラムダ式(最も簡潔な形)を用いた場合
の3通りで同じ処理を書き比べる。それぞれについて、「どの情報が省略されているか」「どこまでが推論されているか」を整理する。
◆次回授業の予習
List などのコレクションに対して、「全要素に同じ処理を行う」「条件に合うものだけ処理する」といった場面を日常の例から考え、それをラムダ式で表現すると、どのように書けそうかをイメージしておくこと。

34 ラムダ式で書き換える操作演習 科目の中での位置付け 本コマは、第4章「ラムダ式/Stream API」第1節「ラムダ式」における演習回として位置づけられる。前回(第33コマ)では、ラムダ式の基本構文と、関数型インターフェイス(Consumer など)との関係について学習し、「名前を持たない処理をその場で記述できる」というラムダ式の考え方を理解した。
本コマでは、その理解を定着させるために、匿名クラスや従来のメソッド定義で書かれているコードを、ラムダ式を用いて書き換えるプログラミング演習を行う。
単に構文を暗記するのではなく、「どの部分がラムダ式に置き換えられるのか」「どの情報が推論によって省略されているのか」を意識しながらコードを比較することで、ラムダ式の本質的な役割を体感的に理解することを目的とする。
本コマは、次回以降に扱う「ラムダ式を用いたコレクション操作」や「Stream API」に進むための重要な橋渡しとなる回であり、「読める」「書き換えられる」状態を到達点とする。

第34回テキスト
第4章「ラムダ式/Stream API」 第1節「ラムダ式」
項目3「ラムダ式で書き換える操作演習」
コマ主題細目 ① 匿名クラス・従来記述からラムダ式への書き換え ② ラムダ式の省略規則と簡潔化 ③ 関数型インターフェイスとラムダ式の対応関係
細目レベル ①  従来の記述とラムダ式の対応関係の理解まで。
はじめに、第32コマ・第33コマで扱ったwalkArrayメソッドを題材に、匿名クラスを用いた記述と、ラムダ式を用いた記述を並べて確認する。
演習では、Consumer を引数として受け取るメソッド呼び出しを例に、「acceptメソッドの実装部分だけがラムダ式として残っている」ことを明確に意識させる。ここでは、いきなり省略形を書くのではなく、「匿名クラス→ラムダ式(省略しない形)」という順で書き換えを行い、「何が消え、何が残っているのか」を一つずつ確認する。
特に、@Override やメソッド名、クラス定義といった要素が、関数型インターフェイスの前提によって不要になっている点を整理し、「ラムダ式は突然現れた新しい構文ではなく、匿名クラスを簡潔に書くための仕組みである」ことを理解させる。

② ラムダ式の省略ルールを用いて、段階的に簡潔な記述ができるようになることの理解まで。
次に、ラムダ式の省略ルールを復習しながら、演習課題に取り組む。
具体的には、
・引数型の省略
・引数が1つの場合の丸カッコの省略
・処理本体が1文の場合の { } と return の省略
といったルールを、実際のコードを書き換えながら確認する。
演習では、「最初はすべて省略しない形で書く → ルールを1つずつ適用して簡潔にする」という流れを重視し、最終形だけを見て理解したつもりになることを避ける。また、引数がない場合には()を省略できないことや、引数型を明示した場合には丸カッコを省略できないといった注意点についても、誤ったコード例を通して確認する。
これにより、ラムダ式を「記号の並び」としてではなく、「省略の積み重ね」として読み解ける力を身に付けさせる。

③ 関数型インターフェイスとラムダ式の対応関係を意識できるようになることの理解まで。
最後に、Consumer以外の関数型インターフェイス(Function、Predicate、Supplier など)を用いた簡単な演習を行い、「処理の形」と「インターフェイス名」の対応関係を整理する。
例えば、
・文字列を受け取り、その長さを返す処理(Function)
・数値を受け取り、条件判定を行う処理(Predicate)
・引数を受け取らず、値を生成する処理(Supplier)
といった課題を通して、「戻り値の有無」「引数の数」によって選ぶべきインターフェイスが変わることを確認する。ここでは、すべてを暗記することを目的とせず、「処理の形に名前が付いている」という感覚を持つことを重視する。
本コマを通して、ラムダ式が単独で存在するのではなく、「関数型インターフェイスという型の実装として使われている」ことを再確認し、次回のコレクション操作への理解につなげる。

キーワード ① ラムダ式 匿名クラス 関数型インターフェイス 省略記法 型推論
コマの展開方法 社会人講師 AL ICT PowerPoint・Keynote 教科書
コマ用オリジナル配布資料 コマ用プリント配布資料 その他 該当なし
小テスト 「小テスト」については、毎回の授業時間内に、LMS上において当該コマの小テスト(難易度表示付)
復習・予習課題 ◆今回授業の復習
以下の処理について、「匿名クラスを用いた記述」「ラムダ式(省略しない形)」「ラムダ式(最も簡潔な形)」の3通りでコードを書き比べる。
各コードについて、「どの情報が省略されているか」「どの部分が型から推論されているか」を文章で整理する。
◆次回授業の予習
List などのコレクションに対して、「全要素に同じ処理を適用する」「条件に合う要素だけを判定・抽出する」といった操作を行う場合、従来の for 文とラムダ式では、どのような違いが出そうかを考えておく。
次回は、これらの操作をラムダ式と組み合わせて記述する方法を学習する。

35 ラムダ式における変数のスコープと処理の受け渡し 科目の中での位置付け 本コマは、第32コマから第34コマまでに学習してきた「ラムダ式の基本構文」と「従来の記述方法との対応関係」を踏まえ、ラムダ式を安全かつ正しく使うための内部ルールを理解することを目的とした回である。
これまでのコマでは、ラムダ式を「短く書ける便利な記法」として扱ってきたが、本コマでは一歩踏み込み、「なぜそのような制約があるのか」「どの範囲の変数を扱えるのか」といった言語仕様としての振る舞いを整理する。
前半では、ラムダ式における変数のスコープを取り上げ、ローカル変数がどのような条件で参照できるのか、また匿名クラスとの違いは何かを、具体的なコード例を通して確認する。
後半では、「処理を引数として渡す」というラムダ式の特徴を、コレクションフレームワークの replaceAllメソッドを題材に確認する。ここでは、多数の要素に対して同じ処理を適用するという典型的な場面を通して、「ラムダ式がどのように使われているのか」を実感的に理解させる。

第35回テキスト
第4章「ラムダ式/Stream API」 第1節「ラムダ式」
項目4「ラムダ式で書き換える操作演習」
コマ主題細目 ① ラムダ式における変数スコープと実質的final ② 匿名クラスとラムダ式のスコープ比較 ③ replaceAllを用いた処理の受け渡し
細目レベル ① ラムダ式における変数のスコープの考え方の理解まで。
はじめに、ラムダ式が「それ自体では独立したスコープを持たない」ことを確認する。ラムダ式内から参照できるローカル変数は、ラムダ式を定義したメソッドやブロックのスコープに属していることを、具体的なコード例を用いて整理する。その上で、ラムダ式から参照されるローカル変数は「実質的に final(effectively final)」でなければならないという制約を取り上げる。変数の再代入を行おうとした場合に発生するコンパイルエラーを確認し、「なぜ変更が許されないのか」を言葉で説明できるようにする。
ここでは、並行処理や設計理論に深入りすることは避け、「ラムダ式と外側の変数を安全に共有するためのルール」であるという理解を重視する。また、Java 7 以前との違いにも触れ、明示的な final 宣言が不要になった背景を簡潔に整理する。

② 匿名クラスとラムダ式におけるスコープの違いについての理解まで。
次に、匿名クラスとラムダ式を比較し、それぞれのスコープの違いを整理する。匿名クラスではクラス自身が新たなスコープを持つため、引数名やthisの指す対象が異なることを確認する。一方で、ラムダ式では thisが外側のクラスを指し、引数名も上位スコープと衝突できない点を、コンパイルエラーを通して理解させる。
ここでは、「ラムダ式は匿名クラスの単なる省略形ではない」という点を明確にし、両者が設計上異なる思想に基づいていることを強調する。違いを暗記させるのではなく、「どちらも処理を渡す仕組みだが、スコープの扱い方が異なる」という整理ができることを目標とする。

③  replaceAllメソッドを通じたラムダ式による処理の受け渡しの理解まで。
後半では、コレクションフレームワークが提供するラムダ式対応メソッドの一例として、List および MapのreplaceAllメソッドを扱う。
まず、List.replaceAll(UnaryOperator)の構文を確認し、「リストの各要素を順に取り出し、指定したルールで置き換える」処理の流れを理解する。ラムダ式が「個々の要素を受け取り、同じ型の値を返す処理」であることを確認し、戻り値の型制約にも触れる。
続いて、Map.replaceAll(BiFunction) を取り上げ、キーと値の両方を受け取ったうえで値のみを書き換える仕組みを確認する。ここでは、複数の引数を受け取るラムダ式の書き方と、処理の意味がコードから読み取れるかどうかを重視する。
これらの例を通して、「ラムダ式とは、繰り返し処理の中身を API に委ねるための仕組みである」という理解を定着させる。for文による明示的なループと比較しながら、コード量の削減だけでなく、処理の意図が明確になる点に注目させる。

キーワード ① 変数のスコープ effectively final 匿名クラス thisの参照先 replaceAllメソッド
コマの展開方法 社会人講師 AL ICT PowerPoint・Keynote 教科書
コマ用オリジナル配布資料 コマ用プリント配布資料 その他 該当なし
小テスト 「小テスト」については、毎回の授業時間内に、LMS上において当該コマの小テスト(難易度表示付)
復習・予習課題 ◆今回授業の復習
ラムダ式内からローカル変数を参照する簡単なプログラムを作成し、
・再代入を行った場合にどのようなエラーが発生するか
・再代入を行わなければ問題なく動作する理由
について整理する。あわせて、List.replaceAllを用いて、文字列や数値のリストを一括変換する処理を1つ作成し、for 文で書いた場合との違いを比較する。
◆次回授業の予習
複数の要素に対して同じ処理を行う場面を日常の例(点数処理、文字列整形など)から考え、「どの部分をラムダ式として渡すと分かりやすいか」を言葉で整理しておく。

36 ラムダ式を用いたコレクション操作 科目の中での位置付け 本コマは、第32コマから第35コマにかけて学習してきた「ラムダ式の基本構文」「従来の記述方法との比較」「ラムダ式における変数のスコープと処理の受け渡し」を踏まえ、それらをコレクション操作に本格的に適用する回として位置づけられる。
本コマでは「ラムダ式を引数として受け取る標準APIを使うことで、コレクション操作がどのように簡潔かつ意味のある形で表現できるか」を具体的に学習する。特に、Collection や Map に追加された removeIf、compute / computeIfPresent / computeIfAbsent、mergeといったメソッドを取り上げる。これらは、従来

第36回テキスト
第4章「ラムダ式/Stream API」 第1節「ラムダ式」
項目5「ラムダ式を用いたコレクション操作」
コマ主題細目 ① removeIfによる条件付き削除 ② Mapのcompute/computeIfPresent/computeIfAbsentの使い分け ③ mergeによるキー重複時の値処理
細目レベル ①  removeIfを用いた条件付き削除の理解まで。
はじめに、従来の List からの要素削除方法を簡単に振り返る。拡張for文の中でremoveを行うと例外が発生すること、Iteratorを用いれば安全に削除できることなど、第22~24コマで学んだ基本事項を確認したうえで、「削除したい条件そのものを API に渡せる」removeIf メソッドを導入する。
removeIf メソッドが Collectionインターフェイスで定義されていることを確認し、Listだけでなく Set にも適用できる汎用的な仕組みである点を押さえる。引数として渡す Predicate は、「要素を受け取り、削除対象であれば true を返す関数」であることを、具体例(文字数が一定以上の文字列を削除する例)を通して理解させる。
ここでは、「どの要素を削除するか」という判断ロジックを for 文の中に埋め込むのではなく、条件を一つの式として外から渡しているという設計思想を重視する。処理の流れはコレクション側に任せ、判断基準だけをラムダ式で指定することで、コードが簡潔になり、意図が読み取りやすくなることを確認する。

② Mapに対するcompute系メソッドの違いの理解まで。
Map を対象とした compute/computeIfPresent/computeIfAbsentメソッドを取り上げる。Map では「キーが存在するかどうか」によって処理の意味が大きく変わるため、この3つのメソッドがどの状態で処理を実行するのかを丁寧に整理する。computeは、キーの存在有無に関わらず処理を実行すること、存在しないキーの場合はvalueがnullとして渡される点を確認する。
computeIfPresent は「すでに値が存在する場合のみ処理を行う」こと、computeIfAbsentは「値が存在しない場合にのみ新しい値を生成する」ことを、同一のコード例を切り替えて実行することで比較する。
このとき、ラムダ式やメソッド参照が「キーと値を受け取り、新しい値を返すルール」として機能している点に注目させる。特に、同じ処理を複数箇所から呼び出す場合には、ラムダ式よりもメソッド参照を用いた方がコードが簡潔になることを確認し、可読性の観点からの使い分けにも触れる。
単に「使い方を覚える」のではなく、「無条件に更新したいのか」「既存データだけを加工したいのか」「初期値を安全に設定したいのか」という設計意図とメソッド選択が結び付くように整理する。

③ mergeを用いた重複キー処理の理解まで。
最後に、Map における merge メソッドを取り上げる。merge は、「キーが存在しない場合はそのまま追加し、存在する場合は現在値と新しい値を使って加工する」という振る舞いを持つことを確認する。具体例として、値が重複した場合にカンマ区切りで連結する処理を題材に、結合関数(BiFunction)が「既存の値」「新しく渡された値」の2つを受け取り、最終的に設定する値を返す仕組みであることを理解させる。
あわせて、結合関数が null を返した場合には、そのキー自体が削除されるという重要な挙動にも触れる。これにより、mergeが単なる「連結用メソッド」ではなく、「条件によっては削除も含めた柔軟な更新処理」を実現できるAPIであることを押さえる。
ここでは、Map 操作において if 文で存在チェックを行い、putやremoveを使い分けていた従来の書き方と比較し、mergeを使うことで処理の流れが一つにまとまる点を確認する。

キーワード ① removeIf compute/computeIfPresent/computeIfAbsent merge Predicate BiFunction
コマの展開方法 社会人講師 AL ICT PowerPoint・Keynote 教科書
コマ用オリジナル配布資料 コマ用プリント配布資料 その他 該当なし
小テスト 「小テスト」については、毎回の授業時間内に、LMS上において当該コマの小テスト(難易度表示付)
復習・予習課題 ◆今回授業の復習
ArrayList を用意し、特定の条件(文字数、特定文字の有無など)に合致する要素を removeIf で削除するプログラムを作成する。
HashMap を用意し、compute/computeIfPresent/computeIfAbsentをそれぞれ使った場合の動作の違いを、実行結果とともに整理する。
merge を用いて、同一キーに対する値の追加・結合・削除がどのように行われるかを確認する。
◆次回授業の予習
次回(第37コマ)では、ラムダ式を用いた数値演算やソート処理を扱う。準備として、Listに格納された数値やオブジェクトを「並び替える」「条件で比較する」といった処理を、これまでの for文や Comparatorを用いた方法でどのように書いていたかを振り返り、ラムダ式を使うとどの部分が簡潔になりそうかを考えておくこと。

37 ラムダ式による数値演算とソート処理演習 科目の中での位置付け 本コマは、第32コマから第36コマまでに学習してきたラムダ式の内容を総合的に用い、実際に動くプログラムを完成させる演習回として位置づけられる。
これまでの授業では、ラムダ式の書き方や考え方、コレクション操作への応用を段階的に学んできたが、本コマではそれらを「知識」としてではなく、「使える技術」として定着させることを目的とする。
題材として扱うのは、「数値データの簡単な計算処理」や「一覧データの並び替え(ソート)」といった、身近でイメージしやすい処理である。
点数の合計や平均を求める、成績順に並べ替える、価格の安い順に商品を並べるなど、日常的な例を通して、「ラムダ式を使うと何が楽になるのか」「for文やif文で書くとどこが大変か」を体験的に理解させる。
本コマは、ラムダ式単元の最後のまとめであり、次回から学習する Stream API への橋渡しとなる回でもある。そのため、複雑な仕様や高度な最適化は扱わず、「ラムダ式を使うと処理の意図が分かりやすく書ける」という感覚を持つことを到達点とする。

第37回テキスト
第4章「ラムダ式/Stream API」 第1節「ラムダ式」
項目6「ラムダ式による数値演算とソート処理演習」
コマ主題細目 ① ラムダ式による数値演算処理 ② ラムダ式によるリスト・オブジェクトのソート ③ 従来記述との比較とラムダ式の利点
細目レベル ① ラムダ式による数値演算処理の理解まで。
本コマの前半では、「数値の一覧データに対する処理」を題材に演習を行う。
最初に、完成形として「複数の数値が格納されたListから、合計・平均・最大値などを求めるプログラム」を実行して見せ、「今日はこれを作ります」と全体像を提示する。
次に、同じ処理を for文だけで書いた場合のコードを示し、
・ループの中で変数を更新する必要がある
・処理の目的(何を計算しているか)がコードから分かりにくい
といった点を確認する。ここでは、「間違ってはいないが、読む側にとっては少し分かりづらい」状態であることを強調し、学生に「もっと簡単に書けそうだ」と感じさせることを狙いとする。
その上で、ラムダ式を用いた処理に書き換え、「各数値に対して何をするか」を式としてまとめて記述できることを示す。例えば、「数値を2倍にする」「一定条件を満たす数値だけを計算対象にする」といった処理をラムダ式で表現し、「処理の内容が一目で分かる」ことを確認する。
  演習では、
・数値の一覧を加工する
・計算ルールをラムダ式として差し替える
といった課題に取り組ませ、「処理の流れはそのまま、計算内容だけを変えられる」ことを体験させる。この段階では、難しい数学処理は扱わず、四則演算や簡単な条件判定に限定する。

② ラムダ式によるソート処理の理解まで。
  後半では、「並び替え(ソート)処理」を題材に演習を行う。まず、完成形として「数値リストを昇順・降順に並び替える」「オブジェクトを特定の基準で並び替える」プログラムを実行して見せる。次に、従来の書き方として、Comparatorを別クラスや匿名クラスで実装した例を提示し、
・クラス定義が長くなる
・何を基準に並び替えているのかが見えにくい
といった点を確認する。ここでは、「並び替えたい基準は一行で説明できるのに、コードは長くなってしまう」という違和感を意識させる。
その後、同じ処理をラムダ式で書き換え、「どちらを先にするか」という比較ルールをそのまま式として書けることを示す。
例えば、
・数値の大小で並べる
・点数の高い順に並べる
・名前の文字列順で並べる
といった、直感的に理解できる例を用いる。
演習では、
・昇順/降順を切り替える
・比較基準を変更する
といった課題に取り組ませ、「ラムダ式を少し変えるだけで並び順が変わる」ことを確認する。ここでは、「正確に書けること」よりも、「読んで意味が分かること」を重視する。

③ ラムダ式を用いる利点を説明できるようになることの理解まで。
最後に、本コマ全体のまとめとして、「for文だけで書いた場合」「匿名クラスを使った場合」「ラムダ式を使った場合」のコードを並べて比較する。「どれが一番短いか」ではなく、
・何をしているプログラムか
・どこを変えれば動きが変わるか
がすぐに読み取れるかという観点で考えさせる。「計算のルールや並び替えの基準を、後から変更しやすいのはどれか」「チーム開発で他人が読んだとき、理解しやすいのはどれか」といった問いかけを行い、ラムダ式が単なる省略記法ではなく、処理の意図を表現するための書き方であることを整理する。

キーワード ① 数値演算 reduce sorted Comparator List 処理の意図 可読性
コマの展開方法 社会人講師 AL ICT PowerPoint・Keynote 教科書
コマ用オリジナル配布資料 コマ用プリント配布資料 その他 該当なし
小テスト 「小テスト」については、毎回の授業時間内に、LMS上において当該コマの小テスト(難易度表示付)
復習・予習課題 ◆今回授業の復習
数値のListまたは簡単なオブジェクトのListを用い、同一の処理(演算処理および並び替え)を「for文」「匿名クラス」「ラムダ式」の3通りで実装する。作成したコードを比較し、処理内容の読み取りやすさや変更のしやすさの観点から、それぞれの特徴を整理することで、ラムダ式の利点と適用場面を理解する。
◆次回授業の予習
複数のデータを「順に処理する」「条件に合うものだけ扱う」といった場面を日常の例から考え、
「その処理をまとめて書けたら便利そうだ」と感じる点を整理しておくこと。
次回は、それらをまとめて扱う Stream API を学習する。

38 Stream APIの概要と処理モデル 科目の中での位置付け 本コマは、第4章「ラムダ式/Stream API」第2節「Stream API」の導入として位置づけられる回である。前回(第37コマ)までに、ラムダ式を用いたコレクション操作や数値演算、ソート処理を通して、「処理そのものを引数として渡す」という考え方に十分に慣れてきた。その発展形として、Java が提供する Stream APIを取り上げる。
Stream API は、コレクションや配列などのデータ集合を対象に、「どのように繰り返すか」を明示的に書かず、「何をしたいか」を処理の流れとして表現するための仕組みである。
最初の回となる本コマでは、細かな構文や個別メソッドの暗記には踏み込まず、「ストリームとは何か」「どのような処理モデルで動いているのか」という全体像を理解することを目的とする。
for 文中心の記述との違いや、宣言的記述という考え方に触れ、次回以降の「生成・中間処理・終端処理」の詳細学習につなげる。

第38回テキスト
第4章「ラムダ式/Stream API」 第2節「Stream API」
項目1「Stream APIの概要」
コマ主題細目 ① Stream API の目的と for 文との比較 ② ストリームの3工程(生成・中間・終端) ③ 宣言的な記述スタイルとメリット
細目レベル ① Stream API が提供する考え方の理解まで。
初めに、コレクションや配列といったデータ集合を処理する際、これまでの授業では for 文を用いて、「どの順番で要素を取り出すか」「どの条件で処理を分けるか」「どこで処理を終えるか」
といった手続きを、一つ一つ明示的に記述してきたことを振り返る。
このような書き方では、正しく動作する一方で、処理の目的よりも手順が前面に出やすいという特徴があることを確認する。その上で、Stream API は、こうした「繰り返し処理の手続き」そのものを Java の API 側に任せ、プログラマは、「要素に対して何をしたいのか」「どのような条件で選別したいのか」といった 処理の内容や意図だけを記述するための仕組みであることを説明する。ここでは、「for 文を書かなくてよい」という点よりも、「考え方が変わる」という点を強調する。ストリームは、「データを処理するためのベルトコンベアー」に例えて説明する。データが一つずつ順に流れ、その途中で加工や選別が行われ、最後に結果だけが取り出されるという流れをイメージさせることで、「データを集めて一気に処理する」のではなく、「データが流れながら処理されていく」という Stream API 特有の発想を、直感的に理解させる。
更に、デモサンプルを通して、フィルタリング(条件による抽出)、変換(map)、並び替え、集約(count や sum など)といった具体的な用途を確認し、従来の for 文による実装と比較することで、処理の意図がコードから読み取りやすくなることを理解させる。あわせて、処理を段階的に組み合わせて記述できることや、変更に強い構造になることなど、Stream APIを用いるメリットについても整理する。

② Stream APIの基本的な処理モデルの理解まで。
Stream API による処理が、大きく次の三つの段階から構成されていることを確認する。
・データソースからストリームを生成する段階
・要素の抽出や変換を行う中間処理の段階
・最終的な結果を得るための終端処理の段階
これらが必ずこの順序で構成されるという点を、具体的なコード例を通して理解させる。
Listから stream()メソッドを呼び出してストリームを生成し、filterや mapによって要素を加工・選別し、forEachなどの終端処理で結果を出力する一連の流れを示す。特に、処理がstream() → filter() → map() → forEach()のように、ドット(.)で連結されて書かれている点に注目させ、「処理が一文の流れとして表現されている」ことを意識させる。
ここでは、各メソッドの細かな引数や戻り値の型には深入りせず、「生成 → 加工 → 結果」という一本の流れとして読めることを理解することを重視する。
また、「途中まで書いても、それだけでは何も実行されない」という点に少し触れ、Stream API の処理が、単なるメソッド呼び出しの集合ではないことを印象づける。

③ Stream APIが宣言的記述であることの理解まで。
最後に、for文を用いた従来の記述と、Stream APIを用いた記述を並べて比較し、両者の発想の違いを整理する。for文では、「ループを何回回すか」「どこで条件分岐するか」「途中で break するか」といった **処理の進め方**がコードの中心になることを確認する。
一方、Stream API を用いた記述では、「どの条件に合う要素を扱いたいのか」「要素をどのように変換したいのか」「最終的に何を得たいのか」といった 処理の目的そのものがコードに表れている点に注目する。
このように、実現方法の詳細には踏み込まず、目的や条件をそのままコードとして表現する書き方を「宣言的記述」と呼ぶことを確認する。Stream API が、人間が考える手順に近い形で処理を記述できる仕組みであることを整理し、「読めば何をしているかが分かるコード」である点を強調する。あわせて、中間処理は終端処理が呼ばれるまで実行されない「遅延処理」であることにも触れ、「書いた順にすぐ実行されるわけではない」という特徴を少し紹介することで、次回以降の詳細な学習への導入とする。

キーワード ① Stream API 中間処理/終端処理 メソッドチェーン 宣言的記述 遅延処理
コマの展開方法 社会人講師 AL ICT PowerPoint・Keynote 教科書
コマ用オリジナル配布資料 コマ用プリント配布資料 その他 該当なし
小テスト 「小テスト」については、毎回の授業時間内に、LMS上において当該コマの小テスト(難易度表示付)
復習・予習課題 ◆今回授業の復習
List を対象に、
・for 文を用いた処理
・Stream API を用いた処理
の2通りで、同じ目的を持つ簡単なプログラムを作成し、「コードから何をしたいかが読み取りやすいのはどちらか」を文章で整理する。
◆次回授業の予習
Stream API で扱われる「ストリームの生成方法」には、どのような種類がありそうかを調べ、List 以外のデータソースの例を挙げてみる。

39 ストリームの生成方法 科目の中での位置付け 本コマは、「Stream API」における実質的な導入第2回として位置づけられる。
前回では、Stream API の全体像を俯瞰し、ストリームとは何かについて学習した。本コマでは、その理解を踏まえ、ストリーム処理の出発点となる「ストリームの生成方法」に焦点を当てる。
コレクションや配列といった既存データからの生成に加え、値の列やラムダ式から新たにストリームを作り出す方法を学ぶことで、「ストリームはどこから生まれ、どのように処理の流れに入っていくのか」を具体的に理解することを目的とする。
以降の中間処理・終端処理の学習において、生成方法の違いが処理の性質(有限/無限、順序性、並列化など)に影響することを意識できるようになることが、本コマの重要な位置づけである。

第39回テキスト
第4章「ラムダ式/Stream API」 第2節「Stream API」
項目2「ストリームの生成方法」
コマ主題細目 ① コレクション・配列からストリームを生成する方法 ② 引数やラムダ式を用いてストリームを生成するファクトリーメソッド ③ 基本型ストリーム(IntStream など)の役割と生成方法
細目レベル ① 既存のデータ構造からストリームを生成できるようになることの理解まで。
はじめに、最も基本的なストリーム生成方法として、コレクションや配列からストリームを生成する方法を確認する。Listや Setといったコレクションではstreamメソッドを呼び出すことで、要素の並びをストリームとして扱えることを確認し、forEach を用いた簡単な出力処理を通して、「要素を1つずつ取り出して処理する流れ」をストリームに委ねていることを理解させる。
あわせて、配列に対しては Arrays.streamを用いる点や、Mapでは entrySetを介してストリームを生成する必要がある点など、データ構造ごとに生成方法が異なる理由にも触れる。
ここでは構文の暗記ではなく、「ストリームはあくまで“要素の流れ”であり、どの単位を流すかは型によって決まる」という視点を持たせることを重視する。
また、parallelStreamメソッドによる並列ストリームの生成にも触れ、記述はほぼ変えずに並列処理へ切り替えられる利便性を確認する。その一方で、並列化にはオーバーヘッドがあり、常に高速化されるわけではないことにも言及し、使えば速くなるではないという現実的な理解につなげる。

② 値やラムダ式からストリームを生成する方法の理解まで。
次に、Stream クラスが提供するファクトリーメソッドを用いた生成方法を扱う。
まず、Stream.ofメソッドを取り上げ、複数の値をそのままストリームとして扱える最も基本的な生成方法であることを確認する。
続いて、generate メソッドおよび iterate メソッドを用いた生成方法を紹介し、これらが「ラムダ式によって次々と値を生み出すストリーム」である点に注目する。ここでは、乱数生成や数値の増加といった具体例を通して、「ストリームには有限なものだけでなく、無限に生成され続けるものがある」ことを理解させる。その上で、limit などの中間処理を用いて明示的に処理を制限しなければならない理由を確認し、無限ストリームの扱いにおける注意点を整理する。
更に、builderメソッドによるストリーム生成を紹介し、値を段階的に追加してからまとめてストリーム化できる仕組みを確認する。
これにより、「すでにあるデータを流す」だけでなく、「処理の都合に合わせてストリームそのものを組み立てる」という考え方があることを理解させる。

③ 基本型ストリームの特徴と利点の理解まで。
最後に、IntStream・LongStream・DoubleStream といった基本型に特化したストリームを取り上げる。これらは Stream のようなラッパークラスを用いたストリームとは異なり、ボクシング・アンボクシングの負担を避けられる点に特徴があることを確認する。
特に、IntStream.rangeおよび rangeClosedを用いた生成方法を例に、指定範囲の数値を簡潔にストリームとして扱える点を理解させる。
ここでは、「上限値を含むか含まないか」という違いを出力結果から読み取らせ、API名と動作を結び付けて理解することを重視する。
あわせて、ジェネリクスでは基本型を直接扱えないという制約にも触れ、「なぜ基本型ストリームが用意されているのか」という設計上の理由を整理する。本コマのまとめとして、「ストリーム処理は、まずどうやって流れを作るかを決めるところから始まる」という視点を確認し、次回以降の中間処理の学習へとつなげる。
更に、本コマのまとめとして、基本型ストリームを用いた簡単な課題演習を行い、「どの範囲の値が生成されるか」「どのメソッドを使えば意図した結果になるか」を確認し、「ストリーム処理は、まずどうやって流れを作るかを決めるところから始まる」という点を認識させる。時間内に実施が難しい場合は復習課題とし、rangeと rangeClosedの違いを含め、ストリームの生成方法を適切に選択できるようにする。

キーワード ① stream / Stream.of generate / iterate / limit IntStream / range / rangeClosed
コマの展開方法 社会人講師 AL ICT PowerPoint・Keynote 教科書
コマ用オリジナル配布資料 コマ用プリント配布資料 その他 該当なし
小テスト 「小テスト」については、毎回の授業時間内に、LMS上において当該コマの小テスト(難易度表示付)
復習・予習課題 ◆今回授業の復習
以下のいずれかについて、ストリームを生成し forEachで出力する簡単なプログラムを作成する。
・List または配列から生成したストリーム
・Stream.of を用いて生成したストリーム
・IntStream.range を用いて生成した数値ストリーム
それぞれについて、「どこでストリームが生成されているか」をコメントで説明する。
◆次回授業の予習**
生成したストリームに対して、「要素を変換する」「一部だけを取り出す」といった処理を行うには、どのような操作が必要になりそうかを考えておく。次回扱う「中間処理」が、どの位置で使われるのかを想像する。

40 中間処理の基本 科目の中での位置付け 本コマは、第4章「ラムダ式/Stream API」において、ストリーム処理の中核となる中間処理(intermediate operation)を体系的に学習する回である。
前回までに、ストリームの生成方法(Stream.of、rangeなど)と、終端処理の存在について概観してきた。本コマではその間に位置する中間処理に焦点を当て、「ストリームを流れてくる値をどのように加工・選別できるのか」を理解する。
特に、「 中間処理は実行されずに連結されるだけであること」「実行のタイミングは終端処理が呼び出されたときであること」という 遅延評価(lazy evaluation)の考え方を、具体的なコード例を通して確認する。
本コマでは、中間処理の代表的なメソッドを取り上げ、「何ができるのか」「どのような型変換が起こるのか」を理解することを到達点とし、複雑な組み合わせや設計的な使い分けは次回の演習回で取り扱うこととする。

第40回テキスト
第4章「ラムダ式/Stream API」 第2節「Stream API」
項目3「中間処理の基本」
コマ主題細目 ① 中間処理の役割と、ストリームが終端処理で実行される仕組み ② filter・map を中心とした基本的な中間処理の使用 ③ sorted・limit・skip による要素数や順序の操作
細目レベル ① 中間処理が処理を実行するものではないことの理解まで。
はじめに、Stream API による処理が「ストリームの生成 → 中間処理 → 終端処理」という一連のパイプライン構造を持っていることを改めて確認する。特に、中間処理は複数回連続して記述できる一方で、その記述時点では実際の要素処理が行われていない点に着目させる。
簡単なコード例を用い、filterや mapを連続して呼び出しても、終端処理(forEachやcollectなど)を呼び出すまでは処理結果が出力されないことを確認し、「中間処理は処理内容を予約している段階である」という理解につなげる。
更に、parallel()や sequential()メソッドも中間処理に分類されることを示し、これらが要素そのものを変換・抽出するのではなく、ストリーム全体の処理方法(並列か逐次か)を指定する役割を持つことを整理する。これにより、「中間処理=値を加工・絞り込む操作」という単純な理解にとどまらず、「ストリームの性質や振る舞いを変更する操作も含まれる」ことを体系的に理解させる。

② filter・map メソッドの役割と違いの理解まで。
次に、最も基本的かつ使用頻度の高い中間処理として、filterメソッドと mapメソッドを取り上げる。filter は条件に合致する要素のみを残す「要素の絞り込み」を行う操作であり、map は各要素を別の値に変換する「要素の変換」を行う操作であることを明確に区別する。
それぞれが PredicateやFunctionといった関数型インターフェイスを引数として受け取る点を確認し、ラムダ式との対応関係を復習しながら理解を深める。
具体例として、文字列のリストから特定の条件を満たす要素のみを抽出する例や、文字列を整数(文字列長など)に変換する例を扱い、filterと mapの役割の違いを視覚的に確認する。その際、map を通過するとストリームの要素型が変化する場合があることに注意を向け、ジェネリクスや型推論との関係にも軽く触れる。
あわせて、mapToIntなどの基本型ストリームを生成するメソッドを紹介し、後続のsumやaverageといった集計処理へ自然につながることを示すことで、次の学習内容への見通しを持たせる。

③ 要素の順序や個数を操作する中間処理の理解まで。
最後に、ストリーム中の要素の並び順や取り扱う個数を制御する中間処理として、sorted・skip・limitメソッドを扱う。sortedメソッドでは、要素がComparableを実装している場合の自然順序による並び替えと、Comparatorを用いた独自ルールによる並び替えの違いを確認する。for 文と Collections.sortを用いた従来の並び替え処理と比較し、Stream APIを用いることで処理の流れを保ったまま簡潔に記述できる点を実感させる。
また、skipとlimitを組み合わせることで、「先頭からm個を飛ばし、そこからn個分を取り出す」といった範囲指定が可能であることを示し、配列やリストにおけるインデックス操作との対応関係を整理する。これにより、従来の for 文による制御構造と、ストリームによる宣言的な記述との違いを意識させ、Stream API の利点を理解させる。

キーワード ① 中間処理 遅延評価(lazy evaluation) filter map sorted/limit/skip
コマの展開方法 社会人講師 AL ICT PowerPoint・Keynote 教科書
コマ用オリジナル配布資料 コマ用プリント配布資料 その他 該当なし
小テスト 「小テスト」については、毎回の授業時間内に、LMS上において当該コマの小テスト(難易度表示付)
復習・予習課題 ◆今回授業の復習
Listを用意し、「条件に合う要素だけを抽出する処理」「要素を別の値に変換する処理」「並び替えや要素数制限を行う処理」をそれぞれ中間処理として記述し、for文で書いた場合と比較して違いを整理する。
◆次回授業の予習
「入れ子になったデータ(リストのリストなど)を処理したい場合」、for 文ではどのようなコードになるかを考えておく。次回は、それをストリームでどのように表現できるかを学習する。

41 中間処理の応用演習 科目の中での位置付け 本コマは、これまでに学習した中間処理の基本事項を踏まえ、より複雑なデータ構造や実践的な操作を扱う演習回である。
ここでは、flatMap・mapMulti・distinct・takeWhile/dropWhile・peek などを取り上げ、「単に書ける」段階から、「状況に応じて使い分けられる」段階への移行を目指す。
特に、「要素を“1対多”に変換する処理」「ストリームの途中状態を確認する考え方」「中間処理を組み合わせたときの振る舞い」に注目し、ストリームAPIをコレクション操作の道具として使いこなす感覚を養う。

第4章「ラムダ式/Stream API」 第2節「Stream API」
項目4「中間処理の応用演習」
コマ主題細目 ① flatMap/mapMultiを用いた要素の展開処理 ② distinct・takeWhile・dropWhile など条件系中間処理の使い分け ③ peekを用いたストリーム処理
細目レベル ① flatMapによる「入れ子構造の平坦化」の理解まで。
はじめに、List>や Listなどの入れ子構造を題材とし、従来の for文を用いた処理を確認する。外側と内側の二重ループを用いて要素を順に取り出すコードを示し、「ネストが深くなると処理の意図が読み取りにくくなる」ことを意識させる。その上で、同じ処理を StreamAPIを用いて書き換え、flatMapを利用することで入れ子構造を1段階平坦化し、単一のストリームとして扱えることを確認する。flatMapは「各要素をストリームに変換し、それらを1本のストリームとして結合する中間処理」であることを明確に説明し、mapを用いた場合との違いを出力結果から比較する。
特に、mapを用いると「StreamのStream」が生成されるのに対し、flatMap では要素がそのまま横に並ぶ点に注目させ、両者の役割の違いを整理する。
更に、flatMapの内部で mapを併用する例を示し、「要素を加工しながら展開する」ことが可能である点を確認することで、flatMapが単なる平坦化のためのメソッドではなく、柔軟な変換処理を担う中間処理であることを理解させる。

② apMultiを用いた要素展開の別表現の理解まで。
次に、Java16以降で利用可能な mapMultiメソッドを紹介し、flatMapと同様に「1要素から複数要素を生成できる中間処理」であることを確認する。その上で、flatMapとの考え方の違いを丁寧に整理する。
mapMulti では「新たなストリームを生成して返す」のではなく、Consumerを通じて出力用のストリームに値を直接流し込むという発想が採られている点に注目させる。for 文で条件に応じて要素を追加していく処理と対応づけながら説明し、命令的な処理に近い書き方であることを理解させる。具体例を通して、条件分岐や要素数が0個または複数個になる場合の記述を比較し、flatMapよりも簡潔に書ける場面があることを確認する。一方で、処理の見通しや可読性の観点から、flatMap の方が適している場合もあることを示し、「どちらが正解か」ではなく「意図が伝わる書き方を選ぶ」という設計上の視点を持たせる。

③ 条件系・補助的中間処理についての理解まで。
最後に、distinct・takeWhile・dropWhile・peek といった、補助的な役割を持つ中間処理を取り上げる。distinctについては、単純に重複した要素を除去する基本的な使い方を確認した後、オブジェクトの特定フィールドをキーとした重複除去を行う例を示す。filterを組み合わせた実装例と比較することで、「中間処理は目的に応じて自由に組み合わせられる」ことを理解させる。
takeWhileおよび dropWhileでは、「先頭から条件が成り立つ連続部分のみを対象とする」という性質を強調し、すべての要素に条件を適用する filter との違いを整理する。データがあらかじめ並んでいる場合に有効であることを具体例から確認し、適切な使い分けにつなげる。
peekについては、要素を変更せずに途中経過を確認するための中間処理であることを明確にし、主にデバッグ用途で用いられる点を確認する。処理結果に影響を与えないことを理解させたうえで、本番コードでの過度な使用は避けるべきであるという注意点にも触れ、補助的メソッドとしての位置づけを整理する。

キーワード ① latMap mapMulti distinct takeWhile dropWhile peek Consumer
コマの展開方法 社会人講師 AL ICT PowerPoint・Keynote 教科書
コマ用オリジナル配布資料 コマ用プリント配布資料 その他 該当なし
小テスト 「小テスト」については、毎回の授業時間内に、LMS上において当該コマの小テスト(難易度表示付)
復習・予習課題 ◆今回授業の復習
List> または List などのデータを用意し、「flatMap または mapMulti を使った処理」「distinct または filter を使った重複除去」を含むストリーム処理を1つ作成してみる。
◆次回授業の予習
ストリーム処理の最終結果を「1つの値にまとめる」場面には、どのような操作が必要かを考えておく。次回は、終端処理(forEach/collect/reduce など)を扱う。

42 終端処理の基本 科目の中での位置付け 本コマは、第4章「ラムダ式/Stream API」において、中間処理で構築されたストリーム処理を実際に「実行し、結果を得る」ための終端処理(terminal operation)を体系的に学習する回である。
前回までに学習した中間処理は、処理内容を連結していく段階であり、それ自体は処理を実行しない。本コマでは、終端処理が呼び出された瞬間に初めてストリーム全体が評価されるというStream APIの根本原理を、具体例を通して確認する。
forEachやfindFirst、countなどの基本的な終端処理を中心に、「どのような結果が得られるのか」「戻り値の型は何か」「Optional型が用いられる理由は何か」といった点を整理し、次コマ以降の集計・変換・演習へとつなげる基礎理解の確立を目的とする。

第42回テキスト
第4章「ラムダ式/Stream API」 第2節「Stream API」
項目5「終端処理の基本」
コマ主題細目 ① 終端処理の役割と、ストリームが実行される仕組み ② 要素の取得・判定を行う終端処理 ③ 個数・最小値・最大値などの基本的な集計処理
細目レベル ① 終端処理が「ストリームを実行する唯一の操作」であることの理解まで。
まず、Stream API における処理の流れが「生成 → 中間処理 → 終端処理」という一方向のパイプラインで構成されていることを再確認する。中間処理は複数回連結できるが、それだけでは実行されず、必ず終端処理の呼び出しが必要である点を強調する。
簡単なコード例を示し、filterやmapをいくら記述しても、forEachやcountなどの終端処理がなければ処理結果が得られないことを確認することで、「終端処理が実行のトリガーである」という理解を定着させる。また、一度終端処理を呼び出したストリームは再利用できず、再度処理を行うにはデータソースから新しいストリームを生成する必要がある点にも触れる。これは、ストリームが「使い捨て」である設計思想を持つことを理解する重要なポイントである。

② 要素を順に処理・取得・判定する代表的な終端処理についての理解まで。
次に、最も基本的な終端処理であるforEachメソッドを取り上げる。forEachは、ストリームを流れる各要素に対して処理を実行するためのメソッドであり、主に結果の出力や副作用を伴う処理に用いられる。
ここでは、ラムダ式とメソッド参照の両方の記述方法を確認し、処理内容自体は中間処理ではなく終端処理で実行されていることを改めて整理する。また、並列ストリームにおけるforEachでは要素の順序が保証されない点に触れ、順序が必要な場合にはforEachOrderedを用いるという選択肢があることを理解させる。
続いて、findFirstおよびfindAnyメソッドを取り上げ、「条件に合致する要素を1つ取得する」という処理の意味を整理する。ストリームが空になる可能性があるため、戻り値がOptional型となる理由を説明し、orElseによる安全な値の取り出し方法を確認する。並列ストリームにおけるfindAnyの挙動にも触れ、「最初の要素」ではなく「最初に見つかった要素」を返すことで、処理効率が優先される場合があることを理解させる。

③ 要素数や最小値・最大値などの基本的な集計処理についての理解まで。
最後に、集計系の終端処理としてcount、min、maxを取り上げる。countメソッドは、ストリーム内の要素数を取得する最も基本的な集計処理であり、filterと組み合わせることで条件付き集計が可能である点を確認する。
minおよびmaxメソッドでは、Comparatorを用いて比較規則を指定する必要があることを説明し、naturalOrderによる自然順比較を例に、文字列や数値の大小判定が行われる仕組みを理解させる。これらのメソッドも戻り値はOptional型であることを確認し、「結果が存在しない場合を考慮したAPI設計」というStream API全体の一貫した思想を読み取らせる。
本コマを通じて、終端処理が「結果を得るための操作」であると同時に、「ストリーム全体を動かす引き金」であることを明確に理解させる。

キーワード ①  終端処理 forEach findFirst Optional count min max
コマの展開方法 社会人講師 AL ICT PowerPoint・Keynote 教科書
コマ用オリジナル配布資料 コマ用プリント配布資料 その他 該当なし
小テスト 「小テスト」については、毎回の授業時間内に、LMS上において当該コマの小テスト(難易度表示付)
復習・予習課題 ◆今回授業の復習
filterとforEachを組み合わせた簡単なストリーム処理を自分で記述し、終端処理がない場合とある場合の違いを説明できるようにする。
◆次回授業の予習
collectメソッドとは何を行うための終端処理なのかを調べ、toListというメソッド名から想像できる役割をまとめておくこと。

43 終端処理演習 科目の中での位置付け 本コマは、前回学習した終端処理の基本を踏まえ、実際に複数の終端処理を組み合わせながら、ストリーム処理全体の理解を深める演習回である。
単にメソッドの使い方を覚えるのではなく、「どの終端処理を選択すべきか」「中間処理との役割分担はどうなっているか」を意識しながらコードを読解・記述することを重視する。
特に、collectメソッドによる配列・コレクションへの変換や、reduceによる値の集約を通して、従来のfor文による処理との対応関係を整理し、Stream APIを用いる意義を理解することを目的とする。

第43回テキスト
第4章「ラムダ式/Stream API」 第2節「Stream API」
項目6「終端処理演習」
コマ主題細目 ① collectによるコレクション変換の基本 ② reduceによるリダクション処理の理解 ③ 終端処理の選択と設計上の注意点
細目レベル ① collectメソッドによってストリーム結果をコレクションに変換できるようになることの理解まで。
まず、collectメソッドが「ストリーム内の要素を最終的にまとめ、別のデータ構造へ変換するための代表的な終端処理」であることを確認する。これまで学習してきた中間処理は要素を加工・選別する役割を担っていたが、collectはその処理結果を実体のあるデータとして取り出すための操作であることを明確にする。
toListやtoSetといった基本的なCollectorsを例に、ストリームの各要素が新しいコレクションへ順に格納されていく流れを確認し、元の配列やコレクションが変更されるのではなく、新たなコレクションが生成される点を理解させる。また、ListとSetの違いに着目し、重複要素の扱いが結果に影響することを具体例で示す。
更に、Java 16以降で追加されたStream.toListメソッドについても取り上げ、collect(Collectors.toList())との記述上の違いや、簡潔さ・可読性の向上といったAPI進化の背景を整理する。その上で、返されるリストが変更不可である点に触れ、用途に応じた使い分けの必要性を理解させる。加えて、toMapを用いた変換例を通して、キーと値をどのように対応づけるのかを確認し、キーの重複が発生した場合に例外が発生する仕組みを理解させる。その上で、merge関数を指定することで重複時の処理方針を明示できることを学び、データ変換における設計上の注意点を意識させる。

② reduceメソッドによるリダクション処理の考え方の理解まで。
reduceは、ストリームを流れる複数の要素を順に結合・計算し、最終的に1つの値へまとめるための汎用的な終端処理であることを確認する。合計値の算出や積の計算など、従来for文で行っていた処理との対応関係を意識しながら理解を進める。
引数が1つの場合、2つの場合、3つの場合のreduceの違いを整理し、それぞれがどのような場面で用いられるのかを具体例を通して確認する。特に、初期値を指定する場合としない場合で戻り値の型が異なる点や、初期値が計算結果にどのような影響を与えるのかを丁寧に説明する。
更に、並列ストリームにおけるreduceの挙動に触れ、初期値がスレッドごとに適用される可能性があることを確認する。これにより、処理内容によっては想定外の結果が生じることがある点を理解させ、「並列処理を前提とした安全な演算」とは何かを考えさせる。

③ 終端処理を適切に選択するための判断基準の理解まで。
最後に、forEach・collect・reduceといった代表的な終端処理を比較し、それぞれの役割と適した利用場面の違いを整理する。forEachは処理結果を外部に出力するための操作であり、collectは結果をコレクションとして保持・再利用するための操作、reduceは複数の値を1つに集約するための操作であることを明確にする。「単に表示したいのか」「数値として計算結果を得たいのか」「後続処理のためにデータ構造として保持したいのか」といった目的の違いによって、選択すべき終端処理が変わることを、具体的な処理例を通して理解させる。
また、無理にreduceで書くべきでない場面や、forEachで副作用のある処理を行う際の注意点にも触れ、可読性と安全性の観点からの判断基準を身につけさせる。
本コマ全体を通して、Stream APIを単なる簡潔な記法として扱うのではなく、「処理の意図や目的をコードとして明確に表現するための道具」として使い分けられる力の育成を目指す。

キーワード ①  Collect toList toMap reduce リダクション Optional
コマの展開方法 社会人講師 AL ICT PowerPoint・Keynote 教科書
コマ用オリジナル配布資料 コマ用プリント配布資料 その他 該当なし
小テスト 「小テスト」については、毎回の授業時間内に、LMS上において当該コマの小テスト(難易度表示付)
復習・予習課題 ◆今回授業の復習
reduceを用いた処理をfor文で書き直し、両者の対応関係を文章で説明できるようにする。
◆次回授業の予習
スレッドとは何かを調べ、「同時に処理する」とはどういう意味かをまとめておくこと。

44 スレッド処理の基本とRunnable 科目の中での位置付け 本コマは、第5章「高度なプログラミング」第1節「マルチスレッド」における導入回として位置づけられる。第4章では、Stream API を通して「処理を流れとして組み立てる」考え方を学んできたが、本章では視点を変え、「処理そのものを同時に実行する」ための仕組みとしてマルチスレッドを扱う。
これまでの学習では、プログラムは基本的に上から順に一つずつ処理されるものとして理解してきた。しかし、実際のアプリケーションでは、通信処理や時間のかかる処理を行いながら、同時に別の処理を継続したい場面が多く存在する。
本コマでは、そうした状況を支える基礎技術として、「スレッドとは何か」「なぜ複数のスレッドが必要になるのか」を概念的に理解することを主目的とする。
また、Thread クラスと Runnable インターフェイスという、Java における代表的なスレッド定義方法を比較しながら学習することで、後続の排他制御・スレッドプール・仮想スレッドといった発展内容への礎を築く回とする。

第44回テキスト
第5章「高度なプログラミング」 第1節「マルチスレッド」
項目1「スレッド処理の基本とRunnable」
コマ主題細目 ① スレッドとマルチスレッド処理の基本概念 ② ThreadクラスとRunnableインターフェイスによるスレッド定義 ③ Runnableを用いたスレッド設計の考え方
細目レベル ① レッドとマルチスレッド処理の基本的な考え方の理解まで。
はじめに、スレッドとは「プログラムを実行する処理の最小単位」であることを確認する。通常の Java アプリケーションでは、main メソッドから始まる メインスレッドが1本だけ存在し、その中で処理が順番に実行されていることを振り返る。
その上で、シングルスレッド環境では、時間のかかる処理(ネットワーク通信やファイル入出力など)が発生すると、その処理が終わるまで次の操作に進めないという問題があることを具体例を通して理解させる。
このような状況を改善するために、処理を複数のスレッドに分けて同時に実行する仕組みがマルチスレッド処理であることを説明する。
更に、プロセスとスレッドの違いにも簡単に触れ、「プロセスは独立した実行単位であり、スレッドは同一プロセス内でメモリを共有しながら動作する」という関係を整理する。
メモリを共有することで効率は向上する一方、同時アクセスによる問題が起こり得ることを示し、詳細は次回以降の排他制御で扱うことを予告する。
この段階では、並列処理を「難しい制御技術」として捉えるのではなく、「ユーザー体験を損なわないための自然な仕組み」として理解することを重視する。

② ThreadクラスおよびRunnableインターフェイスによる基本的なスレッド生成方法の理解まで。
次に、Java において新しいスレッドを生成・実行する基本的な方法として、Thread クラスを継承する方法と、Runnable インターフェイスを実装する方法の2つを取り上げる。
まず、Thread クラスを継承した例を通して、runメソッドが「スレッド開始時に実行される処理の入口」であることを確認する。startメソッドを呼び出すことで、新たなスレッドが生成され、runメソッドの処理がメインスレッドとは独立して実行される点を、実行結果の出力順が不規則になる様子から理解させる。
続いて、同じ処理を Runnableインターフェイスを用いて記述し直し、スレッドの処理内容(Runnable)と、スレッドの生成・実行(Thread)を分離できる点に注目する。Runnableはrun メソッドのみを持つシンプルなインターフェイスであり、「実行可能な処理」を表す役割を担っていることを明確にする。
ここでは、「どちらの書き方を覚えるか」よりも、「スレッドとは 処理を並行して実行する仕組みであり、runメソッドにその中身を書く」という本質的な理解を重視する。

③ Runnableを用いたスレッド設計の考え方の理解まで。
最後に、Runnable インターフェイスを用いる設計が、実務や後続の高度な並行処理において重要になる理由を整理する。Runnable を用いることで、「何をする処理なのか」と「それをどのスレッドで実行するのか」を分離して考えられる点を強調する。
この考え方は、後に学習するスレッドプールや ExecutorService、更には Java 21の仮想スレッドにおいても共通する基本原則であることを示す。
また、匿名クラスやラムダ式を用いて Runnableを簡潔に記述できる点に触れ、これまで学習してきた「匿名クラス」「ラムダ式」「関数型インターフェイス」の知識が、マルチスレッド処理の中でも自然につながっていることを確認する。
本コマのまとめとして、スレッド処理は特別な技術ではなく、処理を分担させるための基本的な道具であることを整理し、次回扱う排他制御の必要性へとつなげる。

キーワード ① マルチスレッド メインスレッド プロセス Thread Runnable run/start
コマの展開方法 社会人講師 AL ICT PowerPoint・Keynote 教科書
コマ用オリジナル配布資料 コマ用プリント配布資料 その他 該当なし
小テスト 「小テスト」については、毎回の授業時間内に、LMS上において当該コマの小テスト(難易度表示付)
復習・予習課題 ◆今回授業の復習
Runnable を実装したクラス、またはラムダ式を用いて、「スレッド名を出力しながらカウントアップする」簡単なスレッド処理を1つ作成し、どこがメインスレッドで、どこが新しいスレッドかを説明する。
◆次回授業の予習**
複数のスレッドが同じ変数を同時に変更すると、どのような問題が起こり得るかを考えておく。
次回は、それを防ぐための「排他制御」を学習する。

45 排他制御 科目の中での位置付け 本コマは、マルチスレッド処理を安全に成立させるための必須概念である「排他制御」を学習する回である。
前回では、Runnableを用いて複数のスレッドを生成・実行し、処理が並行して進む仕組みを確認した。本コマでは、その発展として、複数スレッドが同じデータを同時に扱った場合に何が起こるのか、そしてそれをどのように防ぐのかに焦点を当てる。
マルチスレッド処理は「速く動く」ことばかりが注目されがちであるが、実際には「正しく動かす」ための設計が不可欠である。本コマでは、synchronized による基本的な排他制御を中心に、ReentrantLock や Atomic クラスといった他の手段にも触れながら、状況に応じた排他制御の考え方を身に付けることを目的とする。次回以降のスレッドプールや非同期処理を安全に理解するための、重要な基礎回として位置づけられる。

第45回テキスト
第5章「高度なプログラミング」 第1節「マルチスレッド」
項目2「排他制御」
コマ主題細目 ① 共有データと競合状態(レースコンディション) ② synchronized による排他制御の基本 ③ 排他制御のその他の手段と使い分けの考え方
細目レベル ① マルチスレッド環境における共有データの問題点の理解まで。
はじめに、マルチスレッド処理では、複数のスレッドが同一のメモリ空間を共有しながら同時に実行されるという前提を改めて確認する。各スレッドは独立して動作しているように見えるが、実際にはヒープ領域に配置されたオブジェクトやそのフィールド変数を共通で参照・更新することができる点を押さえる。
その上で、複数のスレッドが同じフィールド変数に対して同時に読み書きを行った場合、どのスレッドの処理が先に実行されるかは実行環境やタイミングに依存し、処理順序が保証されないことを説明する。これにより、同じプログラムであっても、実行するたびに結果が変化する可能性があることを具体的に示す。
例として、共有された value フィールドを++演算子でインクリメントする簡単なコードを取り上げる。一見すると「1ずつ増やすだけ」の単純な処理に見えるが、実際には内部的に「現在の値を取得する → 値を加算する → 計算結果を再代入する」という複数段階の処理に分解されて実行されていることを確認する。
この一連の処理の途中で別のスレッドが割り込むと、片方のスレッドの更新結果が上書きされ、結果として加算が失われてしまう場合がある。このように、複数のスレッドが競うように処理を行うことで、実行結果が不正になる状態を「競合状態(レースコンディション)」として整理する。
ここでは、「エラーが必ず発生するわけではない」点が、マルチスレッド処理を難しくしていることにも触れる。正常に動作する場合と不具合が発生する場合が混在するため、偶然正しく見えるコードをそのまま放置することが危険であることを強調し、マルチスレッド処理では処理結果の正しさが偶然に左右されてはいけないという設計上の重要な前提を理解させる。

② synchronized を用いた基本的な排他制御を実装できるようになることの理解まで。
次に、前項で確認した競合状態を防ぐための基本的な手段として、Javaにおける排他制御の代表例である synchronized 命令および synchronized 修飾子を取り上げる。
まず、synchronized ブロックを用いることで、「ある特定の処理区間において、同時に実行できるスレッドを必ず1つに制限できる」ことを確認する。この仕組みにより、共有データの更新処理を安全に行えるようになることを説明する。このとき、「ロックを獲得する」「ロックを解放する」といった用語を導入し、synchronizedによる排他制御は、特定のオブジェクトに対するロックをスレッドが占有することで成立していることを整理する。
ロック対象として this を指定した場合と、専用の lock オブジェクトを用意した場合のコード例を比較し、同期が成立する条件は「どのオブジェクトを共有しているか」によって決まることを強調する。単に synchronized を付けるだけではなく、複数のスレッドが同じロックオブジェクトを参照していることが不可欠である点を理解させる。
更に、メソッド宣言に synchronized 修飾子を付与した場合についても取り上げ、これは「メソッド全体を synchronized ブロックで囲んだ場合」と等価であることを確認する。これにより、ブロック形式とメソッド形式の対応関係を整理し、用途に応じた使い分けができるようにする。
最後に、排他制御を行う際の設計上の注意点として、同期範囲は必要最小限に抑えるべきであることに触れる。同期範囲が広すぎると、スレッドが待たされる時間が増え、プログラム全体の性能が低下する可能性があることを説明する。特に、ループ処理や時間のかかる処理を synchronized 内に含めることの影響を示し、排他制御は「正しさ」を確保しつつ、「性能」とのバランスを考えて設計するものであるという視点を持たせる。

③ synchronized 以外の排他制御手段の特徴の理解まで。
最後に、synchronized 以外にも排他制御を実現する手段が存在することを示す。
まず、ReentrantLock を用いた明示的なロックについて取り上げる。synchronized と異なり、lock メソッドと unlock メソッドを用いてロックの取得と解放をプログラマ自身が制御する必要がある点を説明する。その代わりに、メソッドをまたいだロック管理や、tryLockによるロック取得可否の判定など、より柔軟な制御が可能であることを確認する。特に、unlock の呼び忘れが深刻な不具合につながる点を強調し、必ず finallyブロック内でロックを解放するという設計上の原則を明確にする。これは、例外発生時にも安全にロックを解放するための重要な考え方である。
次に、AtomicIntegerなどの Atomicクラスを取り上げ、単一の変数に対する加算や更新処理を、ロックを使わずに安全に実行できる「ロックフリーな排他制御」の考え方を紹介する。これにより、処理内容が限定される場合には、高い性能を保ちながら競合状態を防げることを理解させる。あわせて、volatile 修飾子についても触れ、volatile は排他制御を行うものではなく、変数の変更を他のスレッドから確実に見えるようにするための可視性の保証であることを整理する。排他制御との役割の違いを明確に区別することで、誤った使い方を防ぐ。
本コマのまとめとして、排他制御の方法には複数の選択肢があり、「どの手段を使うかは、共有データの性質や処理の粒度、設計上の目的によって決まる」という原則を確認する。これにより、次回以降に学習するスレッドプールや高度な並行処理を、安全に理解するための土台を完成させる。

キーワード ① 排他制御 競合状態(レースコンディション) synchronized ReentrantLock AtomicInteger
コマの展開方法 社会人講師 AL ICT PowerPoint・Keynote 教科書
コマ用オリジナル配布資料 コマ用プリント配布資料 その他 該当なし
小テスト 「小テスト」については、毎回の授業時間内に、LMS上において当該コマの小テスト(難易度表示付)
復習・予習課題 ◆今回授業の復習
共有フィールドを持つクラスについて、「synchronized を使わない場合」「synchronized を使った場合の2通りのコードを見比べ、「なぜ結果に違いが出るのか」をまとめる。
◆次回授業の予習
複数のスレッドを毎回 new Thread で生成する方法には、どのような問題がありそうかを考えておく。次回扱う「スレッドプール」が、どの点を改善する仕組みなのかを予想する。

46 スレッドプールとExecutorService 科目の中での位置付け 本コマは、これまでに学習してきたスレッドの基本(第44コマ)および排他制御(第45コマ)を踏まえ、「スレッドをどのように管理し、安全かつ効率的に利用するか」という実践的な観点を学ぶ回である。前回までは、Threadクラスや Runnableを用いて「スレッドとは何か」「同時に動く処理で何が問題になるのか」を理解してきた。
本コマではその発展として、スレッドを個別に生成・管理するのではなく、あらかじめ用意したスレッドを再利用する仕組みであるスレッドプールを取り上げる。
Java では、この仕組みがExecutorServiceを中心としたAPIとして標準提供されており、実務においてもマルチスレッド処理の基本的な土台となっている。本コマでは、細かな設定や高度なチューニングには踏み込まず、「なぜスレッドプールが必要なのか」「どのように使うのか」「何に注意すべきか」という全体像を理解することを目的とする。

第46回テキスト
第5章「高度なプログラミング」 第1節「マルチスレッド」
項目3「スレッドプールと ExecutorService」
コマ主題細目 ① スレッドプールの考え方と、個別スレッド生成との違い ② ExecutorService を用いた基本的なスレッドプールの利用 ③ スレッドプールの終了処理とライフサイクル管理
細目レベル ① スレッドプールの目的と役割についての理解まで。
はじめに、これまで学習してきたスレッド生成の方法を振り返り、Thread クラスを直接生成したり、Runnable を渡して実行したりする方法では、タスクの数だけスレッドを作成してしまう可能性があることを確認する。
授業では、まず簡単なデモアプリケーションを用いて複数スレッドを生成・実行し、スレッド数の増加や挙動を実際に観察する。さらにタスク数を増やした場合の動作を確認し、問題点を体感的に理解させる。
次にスレッドプールを取り上げる。ExecutorService を用いた実装例を提示し、同様の処理をスレッドプールで実行するデモを通して、スレッド数が制御され、既存のスレッドが再利用される様子を確認する。スレッドはプロセスよりも軽量とはいえ、生成や破棄には一定のコストがかかり、多数のスレッドを短時間に繰り返し生成すると、アプリケーション全体のパフォーマンス低下や、リソース枯渇の原因となることを説明する。そこで、「あらかじめ一定数のスレッドを用意しておく」「必要になったら取り出して使う」「処理が終わったら破棄せず、再び使い回す」という考え方として スレッドプールが用意されていることを確認する。
この仕組みにより、「スレッドを何個作るか」を毎回考える必要がなくなり、プログラマは実行したい処理(タスク)そのものに集中できる点を強調する。スレッドプールは「作業員を必要な人数だけ確保しておく工場」に例え、タスクが来るたびに作業員を新規雇用するわけではない、というイメージで理解させる。
本回を通して、効率的な並行処理の実現におけるスレッド管理の重要性と、スレッドプールの基本的な利用方法を習得することを目標とする。

② ExecutorServiceを用いてスレッドプールを利用できるようになることの理解まで。
次に、Java におけるスレッドプールの標準的な実装として、java.util.concurrentパッケージの ExecutorServiceを取り上げる。
まず、Executorsクラスが提供する。newFixedThreadPoolメソッドを用いて、指定した数のスレッドを持つスレッドプールを生成できることを確認する。
var es = Executors.newFixedThreadPool(10);この時点では「スレッドを10本用意したプールができただけ」であり、まだ何も処理は実行されていない点に注意を向ける。
続いて、executeメソッドを用いて、Runnableを実装したオブジェクトを タスクとして投入 する流れを確認する。
es.execute(new ThreadPool());この呼び出しによって、空いているスレッドがあれば即座に実行される、空きがなければ、順番待ちになるという動作が、内部で自動的に行われていることを説明する。
ここでは、どのスレッドがどのタスクを担当するかを自分で指定していないにもかかわらず、処理が正しく並行実行されている点に注目させる。実行結果として表示されるpool-1-thread-1 のようなスレッド名を確認し、スレッドプール内で管理されているスレッドであることを視覚的に理解させる。

③ スレッドプールの終了処理と安全な利用方法の理解まで。
最後に、スレッドプールを利用する際の **終了処理の重要性** について扱う。スレッドプールは、明示的に終了させない限り、内部のスレッドを保持し続けるため、プログラムが終了しない原因になることがある点を説明する。
Java 19 以降では、ExecutorServiceが、try-with-resources構文に対応しており、次のように記述できることを確認する。
try (var es = Executors.newFixedThreadPool(10)) {
  es.execute(new ThreadPool());
   es.execute(new ThreadPool());
  }
この構文を用いることで、ブロック終了時に自動的に shutdownが呼び出され、スレッドプールが安全に終了される点を理解させる。あわせて、Java 19より前の環境では、try...finallyを用いて明示的にshutdownを呼び出す必要があることも紹介する。
finally {
   es.shutdown();
  }
shutdownは「新しいタスクの受付を停止する」メソッドであり、すでに実行中のタスクは最後まで処理されること、一方で shutdownNowを用いると、可能な限り即座に停止を試みる点も補足として説明する。ここでは、「とにかく止める」ではなく、処理の安全性を保ちながら終了するという設計上の考え方を重視し、次回の「マルチスレッド処理の統合演習」へとつなげる。

キーワード ① スレッドプール ExecutorService newFixedThreadPool execute shutdown
コマの展開方法 社会人講師 AL ICT PowerPoint・Keynote 教科書
コマ用オリジナル配布資料 コマ用プリント配布資料 その他 該当なし
小テスト 「小テスト」については、毎回の授業時間内に、LMS上において当該コマの小テスト(難易度表示付)
復習・予習課題 ◆今回授業の復習
Runnable を実装した簡単なクラスを1つ作成し、ExecutorServiceを用いて複数回executeするプログラムを作成する。
実行結果を確認し、「どの処理が、どのスレッドで実行されているか」をスレッド名から読み取る。
◆次回授業の予習
複数のスレッド処理を組み合わせた場合、「処理の順序」や「共有データの安全性」をどのように保つ必要があるかを考えておく。次回は、これまで学習した内容を統合したマルチスレッド演習を行う。

47 マルチスレッド処理の統合演習 科目の中での位置付け 本コマは、第5章「高度なプログラミング」におけるマルチスレッド処理の学習内容を総合的に確認し、実際のプログラム設計と実装に応用できるようにするための演習回として位置づける。第44コマから第46コマまでに学習したRunnableによるスレッドの基本的な生成と実行、排他制御の必要性とその方法、ExecutorServiceによるスレッド管理の考え方を統合し、複数スレッドが同時に動作する状況を自ら設計し、問題点を発見し、改善する一連の流れを体験させることを目的とする。文法やAPIの知識を確認する段階から一歩進み、マルチスレッド処理を安全に用いるための設計上の視点を身に付ける位置づけとする。
第47回テキスト
第5章「高度なプログラミング」 第1節「マルチスレッド」
項目4「マルチスレッド処理の統合演習」
コマ主題細目 ① Runnableとスレッドプールを用いた並行処理の実装 ② 共有データの競合の再現と排他制御の適用 ③ 実装結果の振り返りとマルチスレッド設計上の留意点
細目レベル ① unnableとスレッドプールを用いた並行処理の実装の理解まで。
Runnableインタフェースを実装したタスクを作成し、ExecutorServiceによるスレッドプールを用いて複数の処理を同時に実行できるようにする。まず、単純な処理内容を持つRunnable実装クラスを用意し、同一のタスクを複数回実行することで、同時並行に処理が進む様子を確認させる。処理内容としては、一定回数のカウント処理や、簡単な文字列出力、疑似的に時間のかかる処理など、結果が目に見えて確認できるものを用いることで、学生が実行結果からスレッドの動作を直感的に理解できるようにする。
この過程において、これまで学習してきたnew Thread().start()による実行方法と、ExecutorServiceを用いた実行方法を比較し、スレッドを直接生成する方法では管理が煩雑になりやすいこと、スレッドプールを用いることでスレッドの生成と破棄をフレームワーク側に任せられることを理解させる。特に、実際のアプリケーション開発では、スレッドの数を無制限に増やす設計は望ましくなく、一定数のスレッドを再利用する設計が現実的であることを説明し、スレッドプールの意義を具体的に示す。
また、実行時にスレッド名を出力するなどして、同一のRunnableが異なるスレッドによって実行されていることを可視化し、処理の順序が実行ごとに変化し得ることを確認させる。これにより、並行処理では処理順序が保証されないというマルチスレッド特有の性質を体験的に理解させることを意図する。単に「同時に動く」ことを理解するだけでなく、処理の流れが固定されないことを前提としてプログラムを設計する必要があるという認識を持たせることを重視する。

② 共有データの競合の再現と排他制御適用の理解まで。
複数のスレッドが同一のデータを同時に操作することで発生する問題を実際に再現し、その解決手段として排他制御を適切に適用できるようになることを到達点とする。具体的には、複数のタスクから同一のカウンタ変数をインクリメントする簡単なプログラムを作成し、排他制御を行わない状態で実行した場合に、期待した回数分だけカウントされない現象が発生することを確認させる。このような結果の乱れを通じて、マルチスレッド環境では単純な代入や加算処理であっても、実行のタイミングが重なることで不整合が生じることを具体的に理解させる。
次に、同じ処理に対してsynchronizedを用いた同期化を施し、結果が安定することを確認させる。ここでは、メソッド全体を同期化する場合と、必要な処理部分のみを同期化する場合を比較し、同期の範囲を広く取りすぎると不要にスレッドの待ちが発生し、性能が低下する可能性があることにも触れる。その上で、ReentrantLockを用いた明示的なロック制御の例を示し、ロックの取得と解放を自分で管理できる反面、記述が複雑になり、解放忘れなどのミスがバグにつながる危険性があることを説明する。更に、単純な数値の更新処理についてはAtomicIntegerなどのアトミッククラスを用いることで、簡潔かつ安全に排他制御を実現できることを示し、用途に応じた手法の選択が重要であることを理解させる。

③ 実装結果の振り返りとマルチスレッド設計上の留意点についての理解まで。
これまでの演習内容を踏まえ、マルチスレッド処理を設計・実装する際の基本的な考え方や留意点を理解することを到達点とする。まず、なぜ排他制御が必要であったのか、排他制御を行わなかった場合にどのような問題が発生したのかを振り返り、マルチスレッド環境では処理の順序やタイミングが不確定であることが根本的な原因であることを整理する。これにより、単に「うまく動かなかったから直した」という経験に留まらず、その背景にある並行処理の性質を言語化できるようにする。
次に、排他制御を行う位置や範囲の設計がプログラムの性能や可読性に与える影響について考察する。必要以上に広い範囲を同期化すると、複数のスレッドが同時に動作できず、結果として並行処理の利点が失われる可能性があることを説明し、排他制御は最小限の範囲に留めることが望ましいという設計上の原則を示す。また、スレッドを無制限に生成する設計と、スレッドプールを用いて管理する設計を比較し、実際のシステムでは後者が一般的である理由についても触れる。
更に、マルチスレッド化そのものが常に性能向上につながるわけではないことを説明し、処理内容や処理量によっては、スレッド管理のオーバーヘッドの方が大きくなる場合があることを理解させる。これにより、マルチスレッドは「使えば速くなる魔法の手段」ではなく、目的や状況に応じて慎重に導入すべき技術であるという認識を持たせる。最終的には、マルチスレッド処理は正しく設計すれば有効な道具である一方で、扱いを誤ると不具合や性能低下の原因となる危険な側面も持つことを理解し、今後のプログラミング学習や実務においても注意深く活用できる基礎的な判断力を身に付けることを目標とする。

キーワード ① ExecutorService スレッドプール Runnable(ラムダ式) synchronized AtomicInteger
コマの展開方法 社会人講師 AL ICT PowerPoint・Keynote 教科書
コマ用オリジナル配布資料 コマ用プリント配布資料 その他 該当なし
小テスト 「小テスト」については、毎回の授業時間内に、LMS上において当該コマの小テスト(難易度表示付)
復習・予習課題 ◆今回授業の復習
本時で学習したマルチスレッド処理と排他制御について、「ExecutorServiceを用いると、どのように複数の処理を同時に実行できるか」「複数スレッドで同じデータを操作すると、どのような問題が起こり得るか」「synchronizedなどの排他制御を行うことで、何が防げるのか」について整理する。
◆次回授業の予習
次回は「定期実行処理とスケジューリング」について学習する。
一定時間ごとに同じ処理を実行する仕組みが、どのような場面で使われそうか考えておく。また、ScheduledExecutorServiceという名前から、どのような役割を持つクラスかを予想しておく。

48 定期実行処理と仮想スレッド生成(JDK21) 科目の中での位置付け 本コマは、「マルチスレッド」における発展内容として位置づけられる。これまでに、スレッドの基本的な仕組み、排他制御による安全性の確保、ExecutorServiceを用いたスレッド管理、そしてそれらを統合した実践的な演習を通して、マルチスレッド処理の基礎と設計上の考え方を一通り学習してきた。本コマでは、その延長として「時間に基づいて処理を実行する仕組み」と「大量の並行処理を現実的に実現するための新しいスレッドモデル」という二つのテーマを扱う。定期実行処理は、サーバ監視や定期的なデータ更新など実務的な利用場面が多く、マルチスレッドの応用として位置づけられる。一方、JDK21で正式化された仮想スレッドは、従来のスレッドモデルの制約を緩和し、大量の並行処理をより扱いやすくする新しい仕組みであり、これまで学んできたスレッドプールやExecutorServiceの考え方がどのように発展しているのかを理解するための重要な題材となる。本コマは、マルチスレッドの実務的な利用イメージと、今後のJavaの並行処理モデルの方向性を理解するための節目となる回として位置づける。
第48回テキスト
第5章「高度なプログラミング」 第1節「マルチスレッド」
項目5「定期実行処理と仮想スレッド生成(JDK21)」
コマ主題細目 ① ScheduledExecutorServiceによる定期実行処理の基本 ② 定期実行方式の違いと設計上の注意点 ③ 仮想スレッドの概念とExecutorServiceによる生成
細目レベル ① ScheduledExecutorServiceを用いた定期実行処理の基本的な仕組みの理解まで。
本回では、ScheduledExecutorService を用いた定期実行処理の基本的な仕組みを理解することを目的とする。はじめに、これまで学習してきた ExecutorService が「タスクを非同期に実行する仕組み」であったことを振り返り、その発展として「時間を指定して処理を実行する仕組み」が存在することを確認する。
導入として、一定時間ごとのログ出力、定期的なデータ保存、サーバ状態の監視といった実際の利用例を提示し、「決められたタイミングで処理を繰り返す」必要性を理解させる。続いて、これらの処理をループと sleep を用いて実装したデモアプリケーションを実行し、動作を確認することで、継続的な処理が実現できる一方で、例外処理やスレッド管理の煩雑さ、制御の難しさといった問題点を体感的に理解させる。
その上で、これらの課題を解決する仕組みとして ScheduledExecutorService を導入する。Executors クラスの newScheduledThreadPool や newSingleThreadScheduledExecutor を用いてスケジュール実行用のスレッドプールを生成し、Runnable 形式のタスクを登録することで、指定した時間間隔で処理が自動的に実行される仕組みを理解する。また、これまでと同様にラムダ式を用いてタスクを記述できることから、既習内容がそのまま活用できる点を強調する。
更に、定期実行処理においては、メインスレッドの終了によって処理が途中で停止する可能性があることを確認し、「アプリケーションをどのタイミングまで動作させるか」というライフサイクル設計の重要性についても扱う。
本回を通して、時間を基準としたタスク実行の考え方とその実現方法を理解するとともに、手動実装との比較を通じて、適切な抽象化されたAPIを利用することの重要性を学ぶ。

② scheduleAtFixedRateとscheduleWithFixedDelayの違いと使い分けの理解まで。
次に、ScheduledExecutorServiceが提供する代表的な定期実行メソッドとして、scheduleAtFixedRateとscheduleWithFixedDelayの違いを整理する。両者はいずれも「一定間隔で処理を繰り返す」という点では共通しているが、実際には「次の実行時刻をどの基準で決定するか」という点において設計思想が異なることを理解させる。scheduleAtFixedRateは、初回実行時刻を基準として、一定の周期で処理の開始時刻を決定する方式であり、処理時間に関わらず、可能な限り一定のリズムで実行されることを目指す仕組みである。一方、scheduleWithFixedDelayは、直前の処理が終了した時点から一定時間後に次の処理を開始する方式であり、処理時間によって実行間隔が変動する特徴を持つ。
この違いを具体的な利用場面と結び付けて説明し、例えば「一定間隔で状態を監視したい」「できるだけ正確な周期でログを出力したい」といった場合にはscheduleAtFixedRateが適している一方で、「前回の処理が終わってから一定時間休ませたい」「処理の重なりを避けたい」といった場合にはscheduleWithFixedDelayが適していることを理解させる。これにより、定期実行処理は単に「自動で繰り返す仕組み」ではなく、処理の性質に応じた設計判断が必要であることを意識させる。
また、定期実行される処理の中で例外が発生した場合や、処理時間が想定よりも長くなった場合の挙動にも簡単に触れ、定期実行処理は「常に安定して動き続ける」ことを前提とした設計が求められることを確認する。これにより、マルチスレッド処理と時間制御が組み合わさることで、設計上の配慮事項が増えることを理解させ、実務的な視点へとつなげる。

③ 仮想スレッドの概念とExecutorServiceを用いた基本的な生成方法についての理解まで。
最後に、JDK21で正式に利用可能となった仮想スレッドの考え方を導入する。これまで学習してきたスレッドは、OSのネイティブスレッドと対応づけられる「比較的重い実行単位」であり、多数のスレッドを同時に生成すると、メモリ消費やスケジューリング負荷の面で現実的な制約があることを振り返る。その制約を緩和し、「大量の並行処理をより扱いやすくする」ことを目的として導入されたのが仮想スレッドであることを説明する。
仮想スレッドは、従来のスレッドと同じようにRunnableを実行できる一方で、実際にはJVMによって効率的に管理される軽量なスレッドであり、大量に生成しても従来ほどの負荷がかからないという特徴を持つ。この点を、ネイティブスレッドを大量に生成しようとすると現実的に困難である例と対比しながら説明することで、「なぜ新しいスレッドモデルが必要とされたのか」という背景理解につなげる。
更に、仮想スレッドはExecutorServiceの仕組みと自然に統合されており、newVirtualThreadPerTaskExecutorを用いることで、タスクごとに仮想スレッドを生成する実行モデルを簡潔に記述できることを確認する。ここでは、これまで学習してきたRunnableやExecutorServiceの知識がそのまま活用できる点を強調し、仮想スレッドは「全く新しい考え方」ではなく、「既存の並行処理モデルをより使いやすく拡張したもの」であることを理解させる。
最後に、仮想スレッドは万能ではなく、すべての場面で従来のスレッドに置き換えればよいわけではないことにも触れ、設計の目的や処理の性質に応じて適切な実行モデルを選択する視点が重要であることを整理する。本コマのまとめとして、定期実行処理と仮想スレッドはいずれも「マルチスレッド処理を実務的に活用するための発展的な手段」であり、これまでの学習内容の延長線上に位置付けられることを確認する。

キーワード ① ScheduledExecutorService 定期実行 Executors 仮想スレッド(Virtual Thread)  newVirtualThreadPerTaskExecutor
コマの展開方法 社会人講師 AL ICT PowerPoint・Keynote 教科書
コマ用オリジナル配布資料 コマ用プリント配布資料 その他 該当なし
小テスト 「小テスト」については、毎回の授業時間内に、LMS上において当該コマの小テスト(難易度表示付)
復習・予習課題 ◆今回授業の復習
ScheduledExecutorServiceを用いて、一定時間ごとに現在時刻を出力する簡単なプログラムを作成し、実行結果から「定期実行されていること」と「処理の開始タイミング」を確認する。
◆次回授業の予習
非同期処理の結果を受け取る仕組みとして、どのような設計が考えられるかを調べ、Runnableでは結果を受け取れない理由を考えておく。

49 非同期処理の結果を受け取る仕組み 科目の中での位置付け 本コマは、第5章「高度なプログラミング」第1節「マルチスレッド」における発展内容として、非同期処理の「実行」だけでなく、その「結果をどのように受け取るか」に焦点を当てる回である。
これまで、Runnableを用いたスレッド処理の基本、排他制御、スレッドプール(ExecutorService)、定期実行や仮想スレッドといった「並行して処理を走らせる仕組み」を学習してきた。しかし、これらは主に「処理を投げる」側の視点が中心であり、サブスレッドで計算した結果をメインスレッド側で受け取る設計については十分に扱っていない。
実際のアプリケーション開発では、別スレッドで行った計算結果や通信結果を受け取り、その値に基づいて次の処理を進める場面が頻繁に現れる。本コマでは、Runnableでは結果を返せないという制約を確認した上で、CallableインターフェイスとFutureインターフェイスを用いて、非同期処理の結果を安全に受け取る基本的な方法を理解することを目的とする。
また、Futureによる結果取得が「待ち(ブロッキング)」を伴う仕組みであることにも触れ、次回扱う CompletableFutureによる「後処理の連結」へと自然につながる位置づけとする。

第49回テキスト
第5章「高度なプログラミング」 第1節「マルチスレッド」
項目6「非同期処理の結果を受け取る仕組み」

コマ主題細目 ① Runnable と Callable の違いと、戻り値を持つ非同期処理の考え方 ② Future を用いた非同期処理結果の取得と待機の仕組み ③ 非同期処理の設計上の注意点と、CompletableFuturへの導入
細目レベル ① Runnableと Callableの役割の違いの理解まで。
本回では、Runnable と Callable の役割の違いを理解するとともに、非同期処理(並列処理)の必要性とその利用場面について学ぶ。
初めに、同期処理と非同期処理の違いを確認する。同期処理では処理を順番に実行するため、複数の時間のかかる処理を連続して実行すると、その合計時間だけ待機が発生する。一方、非同期処理(並列処理)では、複数の処理を同時に実行することで、全体の処理時間を短縮できる場合がある。
導入として、「3つの外部サービスからデータを取得する」処理を例に、順次実行(同期処理)と並列実行(非同期処理)のデモアプリケーションを提示する。例えば、各処理に3秒かかる場合、順次実行では約9秒、並列実行では約3秒で完了することを実行結果から確認し、非同期処理の有効性を体感させる。次に、これまで使用してきた Runnable インターフェイスについて振り返り、run メソッドが戻り値を持たないことを確認する。Runnable は「処理を実行すること」に特化しており、並列処理の完了を join() などで待つことはできるものの、処理結果を呼び出し元に返す用途には適していない。このため、結果を共有変数に格納するなど、設計が複雑になる場合があることを説明する。
続いて、これらの制約を解決する仕組みとして Callable インターフェイスを導入する。Callable は call メソッドによって戻り値を返すことができ、Callable の型引数 T によって非同期処理の結果を型安全に扱える点を理解する。また、ExecutorServiceと Futureを組み合わせることで、並列処理の結果を取得できることを、デモアプリケーションを通して確認する。
ただし、Future#get() は結果が返るまで処理を待機するため、呼び出し順によっては並列処理の利点を十分に活かせない場合があることにも触れる。
本回では、これらの内容を通して、「Runnable は結果を返さない単純な非同期処理向け」「Callable は結果を伴う並列処理向け」という役割の違いを理解し、用途に応じて適切に使い分ける視点を身に付けることを目標とする。

② Future を用いて非同期処理の結果を取得できるようになることの理解まで。
次に、Callable で定義した処理を ExecutorServiceに渡して実行する流れを確認し、submit メソッドが Future 型の戻り値を返すことを理解させる。Futureは「まだ完了していないかもしれない処理の結果」を表すオブジェクトであり、非同期処理の状態を表現するハンドルのような役割を持つことを説明する。
Futureのgetメソッドを呼び出すことで、実際の戻り値を取得できるが、その際、非同期処理が完了していなければ呼び出し元のスレッドは待機状態(ブロッキング)になる点を強調する。これにより、「非同期で実行しているつもりでも、結果取得のタイミングによっては処理が止まってしまう」ことが起こり得ることを理解させる。また、isDone や isCancelled といった状態確認用メソッド、cancel によるキャンセルの考え方にも触れ、Future は単なる結果格納用オブジェクトではなく、「非同期処理の進行状況を管理するための仕組み」であることを整理する。
あわせて、複数の Callable を submit した場合、それぞれの Future から個別に結果を取得できる点を確認し、「どの処理の結果を、どのタイミングで受け取るか」を設計者が明示的に制御できることを理解させる。
この過程で、「結果をすぐに取りに行く設計」と「ある程度処理を進めてからまとめて結果を取得する設計」の違いにも触れ、非同期処理の設計では「結果を受け取るタイミング」そのものが設計要素になることを意識させる。

③ 非同期処理の設計上の注意点と、次回内容へのつながりの理解まで。
最後に、Futureを用いた結果取得の特徴と限界について整理する。Futureは単一の非同期処理の結果を受け取る用途には非常に分かりやすい一方で、複数の非同期処理を連結したり、完了後の処理を次々に定義したりする場合には、getによる待機が増え、コードが読みにくくなりがちである点を指摘する。このような場合、「結果を待ってから次の処理を書く」という同期的な発想では、非同期処理の利点を十分に活かせないことを説明する。
ここで、次回扱う CompletableFutureの位置づけを簡単に予告し、「Future は結果を“取りに行く”仕組みであるのに対し、CompletableFuture は結果が“届いた後の処理”をあらかじめつないでおける仕組み」であるという対比を示す。非同期処理を設計する際には、「どの処理を別スレッドに任せるのか」「結果をいつ、どのスレッドで受け取るのか」「結果取得時に待ちが発生しても問題ないか」といった観点を意識する必要があることを整理し、次回の「非同期処理の連結と事後処理」への理解の土台を作る

キーワード ① Callable Future submit get 非同期処理 戻り値 ブロッキング ExecutorService
コマの展開方法 社会人講師 AL ICT PowerPoint・Keynote 教科書
コマ用オリジナル配布資料 コマ用プリント配布資料 その他 該当なし
小テスト 「小テスト」については、毎回の授業時間内に、LMS上において当該コマの小テスト(難易度表示付)
復習・予習課題 ◆今回授業の復習
Callable を実装したクラスを作成し、乱数計算や簡単な集計処理などを別スレッドで実行して、Future.get()により結果を取得するプログラムを作成する。その際、「getを呼ぶ位置を変えると、処理の流れや待ち時間がどう変わるか」を確認し、簡単にまとめる。
◆次回授業の予習
Future.get()は処理が終わるまで待機する仕組みであるが、「結果が返ってきたタイミングで自動的に次の処理を実行できたら、どのような書き方になるか」をイメージしておく。次回は CompletableFuture を用いた非同期処理の連結を学習する。

50 非同期処理の連結と事後処理演習 科目の中での位置付け 本コマは、「マルチスレッド」における発展内容として、非同期処理の結果を受け取り、その後の処理を「連結」して記述する方法を学習する回である。
前コマでは、Futureや Callableを用いて「非同期処理の結果を受け取る」基本を学んだ。しかし、Futureは getメソッドによる待機が発生しやすく、複数の非同期処理をつなげて扱う場合には、コードが煩雑になりやすいという課題がある。
本コマでは、CompletableFutureを用いることで、非同期処理の流れを直列・並列に連結し、成功時/失敗時の後処理までを自然な形で記述できることを理解する。
また、これまでに学習してきた Runnable、ExecutorService、排他制御といった内容とも関連付けながら、マルチスレッド処理を「部品として組み立てる」設計の考え方に触れる演習回として位置づける。

第50回テキスト
第5章「高度なプログラミング」 第1節「マルチスレッド」
項目7「非同期処理の連結と事後処理演習」
コマ主題細目 ① CompletableFutureによる後処理(成功時/失敗時)の分岐 ② 非同期処理の連結(直列実行・並列実行) ③ マルチスレッド処理の簡単な統合演習
細目レベル ① CompletableFutureによる後処理の記述方法の理解まで。
はじめに、第49コマで学習した Future/Callableを簡単に振り返り、「結果を受け取る」ことはできるが、「その後の処理を自然につなげて書く」ことが難しい場面があることを確認する。その上で、CompletableFutureを用いると、非同期処理の完了後に実行される処理を、whenCompleteAsync などのメソッドによって定義できることを説明する。
具体例を通して、ラムダ式の引数として「処理結果(result)」と「例外(ex)」が渡される点を確認し、exがnullの場合は成功時の処理、null でない場合は失敗時の処理として振り分けられることを理解させる。
ここでは、例外処理を「あとからまとめて書ける」ことの利点に着目し、非同期処理であっても、成功時・失敗時の処理を明確に分離して設計できる点を強調する。あわせて、非同期処理の完了を待たずに mainスレッド側の処理が進む様子を確認し、「プログラム全体は止まらずに動き続けている」ことを体験的に理解させる。はじめに、第49コマで学習した Future/Callableを簡単に振り返り、「結果を受け取る」ことはできるが、「その後の処理を自然につなげて書く」ことが難しい場面があることを確認する。例えば、外部サービスからデータを取得した後に、その結果を加工して画面表示用のデータを生成する、といった一連の処理を考えると、Future.get() を用いた場合は一度処理を待機してから次の処理を書く必要があり、処理の流れが分断されてしまうことをデモアプリケーションの動作を通して確認する。その上で、CompletableFutureを用いると、非同期処理の完了後に実行される処理を、whenCompleteAsync などのメソッドによって定義できることを説明する。
具体例を通して、ラムダ式の引数として「処理結果(result)」と「例外(ex)」が渡される点を確認し、exがnullの場合は成功時の処理、null でない場合は失敗時の処理として振り分けられることを理解させる。
ここでは、例外処理を「あとからまとめて書ける」ことの利点に着目し、非同期処理であっても、成功時・失敗時の処理を明確に分離して設計できる点を強調する。あわせて、非同期処理の完了を待たずに mainスレッド側の処理が進む様子を確認し、「プログラム全体は止まらずに動き続けている」ことを体験的に理解させる。


② 非同期処理の連結(直列・並列)の考え方の理解まで。
次に、CompletableFutureの本質的な利点として、「非同期処理を部品のようにつなげられる」点を扱う。thenApplyAsync、thenAcceptAsync などを用いて、ある非同期処理の結果を、次の処理へ順に引き渡していく直列連結の例を確認する。ここでは、「値を生成する処理(Supplier)」「値を加工・変換する処理(Function)」「結果を受け取って表示・記録する処理(Consumer)」
という役割分担に着目し、ラムダ式・関数型インターフェイスの知識が自然につながっていることを再確認する。
更に、allOf メソッドを用いて複数の非同期処理を並列に実行し、「すべてが完了したら後処理を行う」パターンを確認する。あわせて、anyOfメソッドを用いた「どれか1つが完了した時点で後処理を行う」パターンも紹介し、用途の違いを整理する。このとき、allOf の戻り値が CompletableFutureであり、個々の結果は元の CompletableFutureから取得する必要がある点、anyOfの場合は最初に完了した結果が Object型として得られる点に触れ、APIの設計意図を理解させる。
ここでは、「非同期処理はバラバラに動くもの」ではなく、「処理の流れとして組み立てられるもの」であるという視点を持たせることを重視する。

③ マルチスレッド処理の簡単な統合演習を通して、設計上の視点を整理できるようになることの理解まで。
最後に、これまでのマルチスレッド学習内容(Runnable、ExecutorService、排他制御、非同期処理)を踏まえた簡単な統合演習を行う。
演習例としては、「複数の非同期タスクを並列に実行し、すべて完了したら結果を集計・表示する」「直列に処理を連結し、「処理1 → 処理2 → 処理3」という流れを CompletableFuture で構成する」といった課題を設定し、処理の流れをコードとして組み立てさせる。
この過程で、「どの処理が並列で動いているか」「どの処理が順番に連結されているか」を意識的に整理させ、マルチスレッド処理の設計は**APIの使い方の問題だけでなく、処理構造の設計問題であることを確認する。
また、共有データを扱う場合には排他制御が必要になることにも触れ、「非同期・並列化」と「安全性」は常にセットで考えるべきであるという姿勢を改めて強調する。
本コマのまとめとして、CompletableFuture は「非同期処理を部品としてつなぐための道具」であり、今後のネットワーク通信や入出力処理など、実務的なプログラミングでも頻繁に用いられる考え方であることを整理する。

キーワード ① CompletableFuture whenCompleteAsync thenApplyAsync allOf / anyOf 非同期処理の連結
コマの展開方法 社会人講師 AL ICT PowerPoint・Keynote 教科書
コマ用オリジナル配布資料 コマ用プリント配布資料 その他 該当なし
小テスト 「小テスト」については、毎回の授業時間内に、LMS上において当該コマの小テスト(難易度表示付)
復習・予習課題 ◆今回授業の復習
CompletableFuture を用いて、直列に 2~3 個の非同期処理を連結するプログラムまたは、複数の非同期処理を並列に実行し、allOf で結果をまとめて表示するプログラムのいずれかを作成し、「どの処理が並列で動き、どの処理が連結されているか」を文章で説明する。
◆次回授業の予習
アノテーションとは何かを調べ、「プログラムの動作を直接変えない情報」が、なぜ用意されているのかを考えておく。次回は「アノテーションの基本と標準アノテーション」を扱う。

51 アノテーションの基本と標準アノテーション 科目の中での位置付け 本コマは、第5章「高度なプログラミング」第2節「アノテーション」における導入回として位置づけられる。
これまで、マルチスレッドや非同期処理など、「プログラムの振る舞い(処理の流れや実行の仕組み)」を中心に学習してきた。本コマからは視点を少し変え、「コードそのものに意味づけや付加情報を与える仕組み」としてのアノテーションを扱う。
アノテーションは、処理内容そのものを変えるものではなく、「このメソッドは何の役割か」「このクラスは推奨されているか」「この警告は意図したものか」といったメタ情報をコード上に明示するための仕組みである。フレームワークやライブラリ(テスト・Web・DIなど)では、アノテーションが事実上の「設定ファイル」の役割を担うことも多く、現代的なJava開発において必須の概念である。
本コマでは、アノテーションの基本構文・記述位置・読み方を整理したうえで、標準ライブラリで提供されている代表的なアノテーション(@Override、@Deprecated、@SuppressWarnings、@SafeVarargs、@FunctionalInterface)の意味と使いどころを理解することを主目的とする。

第51回テキスト
第5章「高度なプログラミング」 第2節「アノテーション」
項目1「アノテーションの基本と標準アノテーション」
コマ主題細目 ① アノテーションの役割と基本概念 ② アノテーションの記述位置と基本構文 ③ 標準アノテーションの意味と実践的な使いどころ
細目レベル ① アノテーションの役割と基本概念の理解まで。
はじめに、アノテーションとは「クラス・メソッド・フィールドなどに付与できる“注釈”であり、処理内容そのものではなく、付随的な情報(メタデータ)をコードに与える仕組み」であることを確認する。
あわせて、簡単なデモとして @Override を付与したメソッドを例に取り、記述ミスがコンパイル時に検出されることを確認し、アノテーションがコンパイラやツールに意味を伝える仕組みであることを理解させる。さらに、特定のメソッドに印を付けて処理対象を切り替える例を通して、コードの振る舞いを制御できる点を確認し、その利便性を理解させる。
public / static / abstract などの修飾子と見た目は似ているが、修飾子は言語仕様として固定された意味を持つのに対し、アノテーションは標準で用意されているものに加え、開発者自身が自由に定義できる点が大きな違いであることを整理する。
具体例として、テストフレームワークである JUnitの@Testアノテーションを取り上げ、「このメソッドはテスト用である」という“役割の宣言”が、メソッドの処理内容とは独立して付与されていることを確認する。
この例を通して、「アノテーションは人間やツール(フレームワーク・IDE・コンパイラ)がコードを解釈・処理するための手がかりである」という位置づけを理解させる。
また、アノテーションが利用される場面として、「テストコードの識別」「非推奨APIの明示」「コンパイラ警告の制御」「フレームワークによる自動処理の設定」などを挙げ、現代的なJava開発では“設定ファイルよりもアノテーションで設定する”設計が一般的であることを示す。
この段階では、アノテーションを「特別な高度機能」と捉えるのではなく、「コードに意味ラベルを貼るための自然な仕組み」として理解することを重視する。

② アノテーションの記述位置と基本構文についての理解まで。
次に、アノテーションを記述できる場所として、パッケージ宣言、型宣言(クラス・インターフェイス・enum・アノテーション)、コンストラクタ、メソッド、フィールド、引数、ローカル変数などを整理する。ただし、すべてのアノテーションがすべての場所に書けるわけではなく、個々のアノテーションごとに「適用可能な対象」が決まっている点に注意を向ける。
続いて、アノテーションの基本構文として、「@アノテーション名」「@アノテーション名(属性名 = 値)」という形式を確認し、属性に指定できる値の型が「基本型・String・Class・列挙型・アノテーション型・それらの配列」に限定されていることを整理する。
更に、以下の実用上の書き方のルールを確認する。ここでは、構文を丸暗記するのではなく、「アノテーションは“設定情報の塊”であり、読みやすく書くことが重要である」という観点を重視する。

③ 標準アノテーションの意味と活用場面の理解まで。
最後に、Javaの標準ライブラリで提供されている代表的なアノテーションを取り上げ、単なる文法知識ではなく、「どんな意図で使うのか」という実務的な意味づけを理解させる。
まず @Override について、「オーバーライドしているつもりのメソッドが、実はシグネチャの違いでオーバーライドになっていない」という初学者が陥りやすいミスを防ぐための安全装置であることを確認する。
続いて @Deprecated について、非推奨であることを明示することで「将来的に削除される可能性があるAPIである」「新規開発では使うべきでない」というメッセージを利用者に伝える役割があることを理解させる。since や forRemoval 属性によって、非推奨になった時期や将来的な廃止予定を示せる点にも触れる。
次に @SuppressWarnings を取り上げ、コンパイラ警告は本来は解消すべきものであるが、移行途中や意図した設計上の理由により、あえて警告を抑制したい場合があることを説明する。このとき、「警告を消すための魔法」ではなく、「意図的に警告対象のコードを使っているという意思表示」である点を強調する。
更に @SafeVarargs について、ジェネリクスと可変長引数を組み合わせた際の型安全性に関する警告を抑制するためのアノテーションであり、最終的な安全性の責任は開発者にあることを整理する。
最後に @FunctionalInterfaceについて、インターフェイスが関数型インターフェイスであることを明示し、ラムダ式と組み合わせて安全に利用するための宣言であることを振り返る。
  本コマのまとめとして、標準アノテーションは「コンパイラ・IDE・開発者間のコミュニケーションを助けるための仕組み」であり、コードの品質と保守性を高める重要な道具であることを確認する。

キーワード ① アノテーション メタデータ @Override @Deprecated @FunctionalInterface
コマの展開方法 社会人講師 AL ICT PowerPoint・Keynote 教科書
コマ用オリジナル配布資料 コマ用プリント配布資料 その他 該当なし
小テスト 「小テスト」については、毎回の授業時間内に、LMS上において当該コマの小テスト(難易度表示付)
復習・予習課題 ◆今回授業の復習
@Override を付けた場合と付けなかった場合で、メソッド名をわざと間違えたときの挙動の違いを確認し、「なぜ @Override を付けるべきか」を自分の言葉で説明する。
@Deprecated が付与されたAPIを1つ探し、ドキュメントコメントに書かれている「代替手段」を確認する。
◆次回授業の予習
「アノテーションの情報を、プログラムの実行中に読み取れると、どんなことができそうか」を考えておく。次回は、自作アノテーションとリフレクションの基礎を扱う。

52 アノテーションの自作 科目の中での位置付け 本コマは、「アノテーション」における発展内容として、「アノテーションを自分で定義し、実際に読み取って利用する」ことを体験する回である。
前コマでは、@Override や @Deprecated などの標準アノテーションを用いて、「コードに意味づけを行う仕組み」としてのアノテーションの基本を学習した。本コマではその一歩先として、開発者自身が独自のアノテーションを定義できる点に焦点を当てる。
アノテーションは、単体では「ただの注釈」に過ぎないが、リフレクションによって読み取り、処理と結びつけることで初めて意味を持つ。本コマでは、簡単なアノテーションを自作し、実行時に読み取って利用する一連の流れを体験することで、「アノテーションがフレームワークやライブラリの裏側でどのように使われているのか」を具体的にイメージできるようにする。

第52回テキスト
第5章「高度なプログラミング」 第2節「アノテーション」
項目2「アノテーションの自作」
コマ主題細目 ① アノテーション型の定義と属性設計の基本 ② メタアノテーション(@Target / @Retention など)の役割 ③ 自作アノテーションの利用と実行時取得
細目レベル ① アノテーション型を定義できるようになることの理解まで。
はじめに、アノテーションは @interface命令によって定義される「型の一種」であることを確認する。これはクラスやインターフェイス、列挙型と同様に、Javaの言語仕様として用意された正式な型であり、ソースコード上で開発者自身が独自に宣言できるものであることを学ぶ。
単なるコメントやメモとは異なり、コンパイラやフレームワーク、ツールなどから読み取られることを前提とした「構造化された情報」である点を強調し、アノテーションがプログラムの設計情報やメタデータを表現する仕組みであることを理解させる。
具体例として、クラスの情報(バージョン番号や説明文など)を表す簡単なアノテーションを実際に定義し、@interfaceを用いた基本構文を確認する。その際、アクセス修飾子(public など)を付けられることや、ファイル名とアノテーション名の対応関係など、クラスやインターフェイスを定義するときと同様のルールが適用される点にも触れる。これにより、「アノテーションも特別な存在ではなく、Javaの型の一種として定義されるもの」であるという認識を定着させる。
続いて、アノテーションの中では 「属性」を宣言できることを学ぶ。属性の宣言は、見た目は抽象メソッドに似た構文であるが、実際には「アノテーションに埋め込む設定値」を表すものであり、通常のメソッドとは役割が異なる点を整理する。具体的には、defaultを指定することで既定値を持てること、引数や throws 句を持てないこと、戻り値の型に指定できる型が限定されていることなど、アノテーション特有の制約を確認する。あわせて、これらの制約は「アノテーションをシンプルな設定情報の入れ物として扱う」ための設計上の意図であることを説明する。また、属性が1つだけの場合は慣習的にvalueという名前を用いることが多く、その場合には @MyAnno("v1") のように属性名を省略した記述が可能になる点を確認する。これにより、アノテーションの利用側の記述が簡潔になり、読みやすさが向上することを理解させる。

② メタアノテーションの役割についての理解まで。
次に、アノテーションの振る舞いを決めるための「メタアノテーション」の役割を学習する。@Targetによって「そのアノテーションをどこに付与できるか(クラス、メソッド、フィールドなど)」を制限できること、@Retentionによって「アノテーション情報をどこまで保持するか(SOURCE / CLASS / RUNTIME)」を指定できることを整理する。
ここでは特に、「実行時にリフレクションで読み取りたい場合は RUNTIME を指定する必要がある」点を強調する。あわせて、@Documented や @Repeatable など、実務でも目にする機会のあるメタアノテーションの存在を紹介し、アノテーション設計時には「どこで・いつ使われる情報なのか」を意識して構成情報を決める必要があることを理解させる。
単に書き方を覚えるのではなく、「アノテーションの性格を設計する」という観点を持たせることを重視する。

③ 自作アノテーションを利用し、実行時に取得できるようになることの理解まで。
最後に、自作したアノテーションをクラスに付与し、実行時に読み取る一連の流れを体験する。
まず、定義したアノテーションをクラスに付与し、属性に値を設定する例を確認する。省略記法(value 属性の省略)も実際に試し、記述の違いを理解させる。次に、Class オブジェクトを取得し、getAnnotation メソッドを用いてアノテーション情報を取得する流れを確認する。ここでは、「アノテーションは付けただけでは意味を持たず、それを読み取って処理するコードがあって初めて意味を持つ」という点を強調する。また、属性値を使って表示内容を変えるなど、簡単な分岐処理を行い、「設定情報としてのアノテーション」を活用する感覚をつかませる。
補足として、同一の要素に複数付与できる @Repeatableアノテーションの仕組みに触れ、コンテナーアノテーションの存在と、getAnnotationsByType メソッドによる取得方法を紹介する。
本コマのまとめとして、「アノテーション+リフレクション」によって、プログラムの振る舞いを外から制御できる設計につながることを整理し、次回のリフレクション演習への導入とする。

キーワード ① @interface 属性(value/default) @Target/@Retention getAnnotation @Repeatable
コマの展開方法 社会人講師 AL ICT PowerPoint・Keynote 教科書
コマ用オリジナル配布資料 コマ用プリント配布資料 その他 該当なし
小テスト 「小テスト」については、毎回の授業時間内に、LMS上において当該コマの小テスト(難易度表示付)
復習・予習課題 ◆今回授業の復習
簡単な自作アノテーション(例:@Author、@Version など)を定義し、クラスに付与したうえで実行時にリフレクションで読み取り、内容を表示するプログラムを作成する。
◆次回授業の予習
Class オブジェクトから、クラス名やメソッド一覧などの情報を取得できることを調べておく。次回は「リフレクション」を用いて、型情報やメンバーを動的に扱う演習を行う。

53 リフレクション入門実践演習 科目の中での位置付け 本コマは、アノテーションを実際に読み取り、活用するための基盤技術である「リフレクション」を学ぶ導入実践回として位置づけられる。
前回までに、標準アノテーションおよび自作アノテーションの定義方法を学習してきたが、アノテーションは「付ける」だけでは意味を持たず、実行時に読み取って処理に反映させてこそ価値を持つ。本コマでは、Class クラスや java.lang.reflectパッケージを用いた基本的な操作(インスタンス生成、メソッド呼び出し、フィールド操作、アノテーション取得)を、サンプルコードを通して体験的に理解する。
あわせて、リフレクションの利便性と同時に存在する欠点(可読性の低下、型安全性の低下、実行時エラー、性能面の問題)にも触れ、「なぜリフレクションは多用すべきでないのか」「それでも使うべき場面はどこか」という設計上の視点を持たせる回とする。

第53回テキスト
第5章「高度なプログラミング」 第2節「アノテーション」
項目3「リフレクション入門実践演習」
コマ主題細目 ① リフレクションの役割と基本的な考え方 ② リフレクションによるインスタンス生成・メソッド実行・フィールド操作 ③ アノテーション取得とリフレクション利用時の注意点
細目レベル ① リフレクションの役割と基本的な考え方の理解まで。
はじめに、通常のJavaプログラムでは「クラス名・メソッド名・フィールド名」はコンパイル時に確定し、ドット演算子を用いて静的にアクセスしていることを振り返る。
これに対して、リフレクションとは「クラスの構造やメンバー情報を、実行時に取得・操作する仕組み」であることを確認する。
Classクラスを入口として、コンストラクター・メソッド・フィールドといったメタ情報にアクセスできる点を押さえ、「実行時にクラスの中身を調べる」「実行時にメソッドを呼び出す」「実行時にフィールドを書き換える」といった柔軟な操作が可能になることを理解させる。
ここで、簡単なデモとして、通常はアクセスできない private フィールドに対して、リフレクションを用いることで実行時に値を取得できる例を提示し、「本来アクセスできない情報にも動的にアクセスできる」という特徴を体験的に理解させる。
その上で、リフレクションは主にフレームワークやライブラリの内部で利用される技術であり、アプリケーション開発者が日常的に直接使用する場面は多くないことを説明する。一方で、「アノテーションの情報を実行時に読み取る」「クラス構造に応じて処理を自動的に切り替える」といった仕組みの基盤となっていることを示し、「前回までのアノテーションの学習が、ここで実際に動く仕組みとしてつながる」ことを意識づける。
また、例外的な利用場面として、ライブラリ側に適切なアクセス手段が提供されていない場合に、最終手段として内部データへアクセスする用途があることにも触れる。ただし、このような使い方は設計上望ましくないケースも多く、基本的には仕組みの理解に留めるべきであることを強調する。
この段階では、細かなAPIの暗記ではなく、「リフレクションは“実行時に構造を扱う仕組み”であり、主にフレームワークを支える基盤技術である」という全体像の理解を重視する。

② リフレクションによるインスタンス生成・メソッド実行・フィールド操作の理解まで。
  次に、サンプルコードを通して、リフレクションの代表的な利用方法を段階的に確認する。まず、Class オブジェクトから getConstructorを用いてコンストラクターを取得し、newInstance によってオブジェクトを生成する流れを確認する。ここで、「new File(...)」のような通常の生成方法と比較し、リフレクションではクラスやコンストラクターを“文字列や型情報として扱う”という点に注目させる。
続いて、getMethods / getDeclaredMethodsを用いてクラスに定義されているメソッド一覧を取得し、Method オブジェクトから getName によってメソッド名を列挙できることを確認する。
更に、getMethod と invoke を用いて、特定のメソッド(例:renameTo など)を実行できることを示し、「メソッド呼び出しも実行時に差し替えられる」柔軟性を体験させる。
最後に、getDeclaredFieldとsetAccessible(true)を用いたフィールドの取得・設定を扱い、private フィールドにもアクセス可能であることを確認する。ただし、これは**カプセル化を破る危険な操作である**ことを強調し、あくまで学習目的・仕組み理解として扱う。
これらの操作を通して、「コンストラクター」「メソッド」「フィールド」が、すべて「オブジェクトとして扱われる」点に気付かせ、リフレクションの統一的な考え方を整理する。

③ アノテーション取得とリフレクション利用時の注意点の理解まで。
次に、Class クラスを用いて、クラスやメンバーに付与されたアノテーションを取得できることを確認する。
ここでは、「アノテーションは単なるマークではなく、リフレクションによって取得され、プログラムの振る舞いを制御するための情報である」ことを改めて整理する。その上で、リフレクションの以下の欠点について整理する。
・メンバー名を文字列で指定するため、コンパイル時に誤りを検出できない。
・コードが冗長になり、可読性・保守性が低下しやすい。
・通常の呼び出しに比べて実行速度が遅い。
これらの点から、「リフレクションは便利だが、常用すべき技術ではない」という設計上の原則を確認する。
最後に、リフレクションはフレームワークやライブラリ内部で多用されることが多く、アプリケーション開発者は「使う側」として仕組みを理解しておくことが重要である、という実務的な位置づけを示す。

キーワード ① アノテーション取得とリフレクション利用時の注意点の理解まで。 次に、Class クラスを用いて、クラスやメンバーに付与されたアノテーションを取得できることを確認する。 ここでは、「アノテーションは単なるマークではなく、リフレクションによって取得され、プログラムの振る舞いを制御するための情報である」ことを改めて整理する。その上で、リフレクションの以下の欠点について整理する。 ・メンバー名を文字列で指定するため、コンパイル時に誤りを検出できない。 ・コードが冗長になり、可読性・保守性が低下しやすい。 ・通常の呼び出しに比べて実行速度が遅い。 これらの点から、「リフレクションは便利だが、常用すべき技術ではない」という設計上の原則を確認する。 最後に、リフレクションはフレームワークやライブラリ内部で多用されることが多く、アプリケーション開発者は「使う側」として仕組みを理解しておくことが重要である、という実務的な位置づけを示す。
コマの展開方法 社会人講師 AL ICT PowerPoint・Keynote 教科書
コマ用オリジナル配布資料 コマ用プリント配布資料 その他 該当なし
小テスト 「小テスト」については、毎回の授業時間内に、LMS上において当該コマの小テスト(難易度表示付)
復習・予習課題 ◆今回授業の復習
String クラスの substring メソッドを、リフレクション経由で呼び出す簡単なプログラムを完成させ、「通常の呼び出し」と「リフレクション経由の呼び出し」のコード量・読みやすさを比較して気付いた点をまとめる。
◆次回授業の予習
Java 9 以降で導入された「モジュール」という仕組みが、クラスの公開範囲やリフレクション利用にどのような影響を与えるのかを調べておく。次回は「Javaモジュールの基本構造と依存関係」を扱う。

54 Javaモジュールの基本構造と依存関係 科目の中での位置付け 本コマは、これまで学んだアノテーション/リフレクションの「動的に読み取って動かす」世界から、もう一段外側の「部品(ライブラリ)をどう安全に組み合わせるか」という視点へ移る回である。前コマではリフレクションの柔軟さと危うさを体験したが、本コマでは“見せてよい部品/隠したい部品”を整理し、更に“必要な部品が揃っているか”を明示するための仕組みとしてJavaモジュールを扱う。以降の「パッケージ公開」「非モジュールライブラリとの共存」へつながる入口となる。
第54回テキスト
第5章「高度なプログラミング」 第2節「アノテーション」
項目4「Javaモジュールの基本構造と依存関係」
コマ主題細目 ① モジュールとは何かと、module-info.javaの読み方 ② 「requires」による依存関係の書き方と、エラーから原因をたどる練習 ③ 推移的な依存の考え方
細目レベル ① モジュールの基本構造を、把握できるようになることの理解まで。
こちらで用意した小さなプログラムを実行し、「同じプロジェクトの中に、役割の違う部品(パッケージ)がいくつかあり、外に見せてよいものと、内部だけで使うものが分かれている」状態を確認する。例として、学校の制作物を想像するとよい。表紙(みんなに見せる説明)と、下書きノート(自分たちだけが見たいメモ)が混ざって提出されると困る。プログラムでも同じで、「利用者に使ってほしい入口」と「内部の都合で置いている部品」を分けたい場面が出てくる。
このように公開範囲を分けることにより、外部からの誤った利用を防ぎ、変更の影響範囲を限定できるため、プログラムの保守性や安全性が向上する。また、内部実装を自由に変更できるようになることで、開発効率の向上にもつながるといった、実務上のメリットがあることを理解させる。
ここで、モジュールは「部品の箱」だと捉える。箱の中には複数のパッケージ(部品の棚)が入っており、箱には「この箱は何という名前で」「どの箱を必要としていて」「どの棚を外に見せるか」を書いたラベルが貼られる。そのラベルが module-info.java だと説明する。専門用語を増やすより、まずは「箱のラベルを読む」ことを体験するのが目的だと伝える。
次に、問題を見せる。module-info.java が無い(または内容が空のまま)という想定で、外部の部品を使おうとしたときに「使えるはずなのにアクセスできない」状態をわざと作る。学生には、エラーが出ること自体が失敗ではなく、「箱のラベルが不足している」というサインだと理解してほしい。ここでは難しい言葉を避け、「必要な部品が書かれていないと、使いたい部品に手が届かない」と言い換える。
その上で解決策として、/src直下にある module-info.java を開き、module ~ { } の形が「箱の名前」を示していることを確認する。モジュール名はパッケージ名と完全一致しなくても動くが、後で迷子になりにくいように、似た名前に揃えると読みやすい、という程度に留める。ここでは「箱の名前」「ラベルファイル」というイメージで説明し、細かな命名規則の暗記は求めない。
演習では、「module-info.javaを見つける」「module宣言を読める」「どの範囲が“この箱の中身”なのかを説明できる」の3点を短いチェックで確認する。最後に、「今日は“箱のラベルがある”という事実と、そこに依存関係を書く準備があることを掴めば十分だ」とまとめる。

② requires を用いて依存関係を最小限の手順で宣言できるようになることの理解まで。
次に授業の中心として、「困る状況 → 直す」という流れで依存関係を体験する。完成形として、標準ライブラリのうち“いつもは意識せずに使えているもの”と、“明示が必要になるものがある”ことを、短いデモで見せる。ここで大切なのは「動かなかったら、module-info.java を疑う」という道筋を持つことだと強調する。
問題提示として、あるパッケージを importしただけでコンパイルが通らない(アクセスできない)状況を用意し、実際にエラーメッセージを見せる。「クラス名は合っているのに、なぜか使えない」という、初学者が混乱しやすい状況をあえて作る。日常の例で言えば、学校の図書館で「本は棚にあるのに、入館証がないので入れない」状態に近い。必要なのは本の場所を知ることではなく、入館の許可(宣言)だという感覚を持たせる。
解決策として、module-info.java に requires ~;を1行追加する作業を、コーディングで見せる。追加した瞬間にエラーが消える体験を、学生自身の手でも再現させる。ここでは「requires は“この箱はこの箱を使います”という宣言」だと説明し、深い仕組みには立ち入らない。宣言が無いと使えない、宣言があれば使える、という因果関係をつかむことが狙いである。
演習では、「いきなり全部を覚える」のではなく、「動かない→ラベルを見る→requiresを書く」という3手順を体に入れることを重視する。更に、標準ライブラリの中には“暗黙的に使える基本セット”があることを軽く触れ、「全部に requiresが必要なわけではないが、必要なときはここに書く」とだけ整理する。
 最後に、「import を足したのに使えないとき、まず何を見るか」「requires の役割を一言で言うと何か」を確認する。

③ 推移的な依存の違いを、簡単な例で説明できるようになることの理解まで。
最後のパートでは、「依存が連鎖する」という感覚だけを掴む。完成形として、Aという箱がBを必要とし、Bが更にCを必要としている状況を図で見せる。日常の例にするなら、料理で「カレーを作るにはルーが必要」「ルーを使うには鍋が必要」のように、目的の先に更に必要なものがぶら下がることがある。プログラムでも同様に、「自分が直接使っていない部品」でも、使っている部品の内部で必要になる場合がある。
問題提示として、「自分はBだけ宣言したのに、なぜCの話が出てくるのか」と混乱しやすい場面を短く示す。ここで細かな規則を増やさず、「依存は一本の線ではなく、時々“芋づる式”になる」と表現する。解決策として、requires transitive の考え方を“説明のための道具”として紹介する。これは「Bを使うなら、Bが必ず必要とするものも一緒に使えるようにしておく」という“親切設定”のようなものだと説明する。
演習は、サンプルの module-info.java を読み、「requires の行数を数える」「transitive が付く行と付かない行で“使う側の立場で何が楽になるか”を1~2文で書く」、「“芋づる式”という比喩で説明できるか」を確認する。

キーワード ① モジュール module-info.java 依存関係 requires コンパイルエラー
コマの展開方法 社会人講師 AL ICT PowerPoint・Keynote 教科書
コマ用オリジナル配布資料 コマ用プリント配布資料 その他 該当なし
小テスト 「小テスト」については、毎回の授業時間内に、LMS上において当該コマの小テスト(難易度表示付)
復習・予習課題 ◆今回授業の復習
配布サンプルの module-info.java を見直し、requires を1行わざと削除してエラーを出し、元に戻して解消するところまでを再現する。その上で「どんなエラーが出て、どこを直したら直ったか」をまとめる。
◆次回授業の予習
「外に公開したいパッケージ」と「内部だけで使いたいパッケージ」を、自分が作ったプログラムで1つ思い出してメモしておく。次回はパッケージ公開と、従来の.jar(非モジュール)と共存する方法を扱う。

55 パッケージ公開と非モジュールライブラリとの共存 科目の中での位置付け 本コマは、「アノテーション」の後半で扱う「Javaモジュール」学習の実践回として位置づける。前回では、module-info.java によって依存関係(requires)を宣言し、モジュール同士を安全に組み合わせる基本を学んだ。本コマではその続きとして、「自分が作ったモジュールのどのパッケージを外部に見せるか」を設定し、更に従来の.jar(モジュール定義を持たないライブラリ)を同じ環境で動かす方法を体験する。ライブラリを「使う」だけでなく、「配る側・組み込む側」の視点を持つことで、今後の開発で遭遇しやすいエラーや設定の考え方を整理する回とする。
第55回テキスト
第5章「高度なプログラミング」 第2節「アノテーション」
項目5「パッケージ公開と非モジュールライブラリとの共存」
コマ主題細目 ① exports によるパッケージ公開 ② exports to / opens の使い分け ③ 非モジュール.jarとの共存
細目レベル ① exports によって、モジュール内で「公開するパッケージ」と「公開しないパッケージ」を分けて設計できるようになることの理解まで。
小規模なライブラリ構成を用い、外部に提供する機能用パッケージと内部実装用パッケージが混在している例を確認する。public 修飾子のみでは制御できない「モジュール外への公開可否」を、module-info.javaによって明示的に設定できる点を理解する。
あわせて、開発現場ではライブラリや共通部品を複数人で利用する場面が多く、「利用してよい機能」と「内部実装として隠しておきたい部分」を明確に分離する必要があることを説明する。モジュールによる公開範囲の制御を行うことで、誤った利用や内部構造への依存を防ぎ、仕様変更時の影響を抑えられる点が実務上の大きな利点であることを理解させる。また、大規模開発においてシステム構造を整理しやすくなる点でも有効であることに触れる。
まず、内部パッケージを importした際にコンパイルエラーが発生する状況を確認し、「public であっても、exports されていなければ外部からは利用できない」ことを押さえる。その上で、exportsを追加した場合に利用可能となる様子を比較し、公開設定がアクセス制御の単位をパッケージレベルに拡張する仕組みであることを整理する。
演習では、自作モジュールにおいて公開パッケージと非公開パッケージを分離し、利用側からのimport可否を検証する。エラーの原因を「クラスの不存在」ではなく「公開設定」によるものであると説明できることを目標とする。モジュールは public の意味をより細かく制御する仕組みであることをまとめ、次の公開範囲限定やリフレクションとの関係へ接続する。

② exports to と opens の違いについての理解まで。
まず、exports toを用いて特定モジュールにのみパッケージを公開する例を扱い、公開対象を限定できることを確認する。通常のexportsとの違いを比較し、公開範囲を細かく制御できる利点を理解する。次に、リフレクションを用いたアクセスがモジュール設定によって制限される場面を確認する。privateメンバへのアクセスが実行時エラーとなる例を通して、モジュールが実行時のアクセスにも影響することを押さえる。その上で opensを導入し、opensは「実行時のリフレクションアクセスを許可する設定」であり、exportsは「型として利用可能にするコンパイル時公開」であることを整理する。
演習では、exportsのみの場合と opensを追加した場合を比較し、通常利用とリフレクション利用の挙動の違いを確認する。どの場面でどの指定が必要かを言葉で説明できることを目標とする。また、公開を必要最小限に抑える設計姿勢の重要性を確認する。

③ 非モジュール.jarをモジュール環境で利用する際の基本的な配置方法と実行時設定についての理解まで。
まず、非モジュール.jarをmodule-pathに配置すると「自動モジュール」として扱われることを確認する。module-info.java を持たない.jar でも、モジュール環境で一定の形で利用できる仕組みがあることを理解する。
次に、設定不足による実行時エラーを確認し、原因を分析する。標準ライブラリの不足によるエラーでは、追加指定によって解決できる場合があることを学ぶ。非モジュール.jar自身には requiresを記述できないため、実行時オプションで補う必要がある点を押さえる。
更に、リフレクションを利用するライブラリで発生するアクセス制限エラーを扱い、opensや add-opens指定によって解決できることを確認する。コンパイルは通るが実行時に停止する場合があることを理解し、エラーメッセージから不足している条件(依存モジュール不足か、アクセス許可不足か)を判断できることを目標とする。
最終的に、非モジュール.jar を利用する際には「依存モジュールの不足」または「リフレクション許可の不足」が主な停止要因となることを整理し、実行時条件を適切に調整する視点を身に付ける。

キーワード ① exports exports to opens module-info.java module-path 
コマの展開方法 社会人講師 AL ICT PowerPoint・Keynote 教科書
コマ用オリジナル配布資料 コマ用プリント配布資料 その他 該当なし
小テスト 「小テスト」については、毎回の授業時間内に、LMS上において当該コマの小テスト(難易度表示付)
復習・予習課題 ◆今回授業の復習
自作モジュールで「公開するパッケージ」と「公開しないパッケージ」を1つずつ用意し、利用側からimportしたときに片方だけ成功する状態を再現する。あわせて、非モジュール.jarを使う例について、(1)置き場所(module-path)(2)不足した依存(追加指定)(3)覗かせる許可、のどれで詰まったかを確認する。
◆次回授業の予習
異なる言語・地域で、日付や数値の表示がどう変わるかを身近な例(スマホの表示、通販サイトの表記など)で1つ探しておく。次回はロケールの概念と国際化対応を扱う。

56 ロケールの概念と国際化対応 科目の中での位置付け 本コマは、第6章「ローカライズ/フォーマット」の導入回であり、これまで学んできたAPI活用やモジュール構成とは視点を変え、「同じプログラムを異なる国・言語環境でどう使えるようにするか」を考える回である。前コマまでは機能の正しさや構造の安全性を中心に扱ってきたが、本章では「利用者の地域に合わせて表示を変える」という実用的な課題に取り組む。次回以降のリソースバンドルやフォーマット処理の土台となる概念を理解する。
第56回テキスト
第6章「ローカライズ/フォーマット」 第1節「ローカライズ」
項目1「ロケールの概念と国際化対応」
コマ主題細目 ① ロケールとは何か ② Localeクラスによる取得と確認 ③ 国際化対応の基本設計
細目レベル ① ロケールの意味と必要性を説明できるようになることの理解まで。
まず同じ日付を表示するだけの簡単なプログラムを実行する。PCでは「2021/02/01」と表示され、別の設定では「2/1/21」と表示される様子を見せる。更に通貨の例として、「¥50,000」と「$50,000.00」が切り替わる様子も確認する。そして「今日は、この違いの正体を理解し、自分でコントロールできるようになる」と目標を明確にする。
あわせて、このような表示の違いは「ロケール(地域や言語の設定)」によって決まっており、実際の開発現場では、多言語対応や海外向けサービスにおいて重要な役割を持つことを説明する。例えば、同じアプリケーションでも利用者の国や地域に応じて日付や通貨、数値の表記を自動的に切り替えることで、ユーザにとって自然で分かりやすい表示を実現できる。このように、ロケールを適切に扱うことがユーザビリティの向上や国際対応に直結する点を理解させる。
次に、日付や通貨表示をすべて「文字列」として直接コードに書いていたらどうなるかを考える。日本向けには問題なくても、海外向けに配布する場合、日付の順序、区切り文字、通貨記号などをすべて書き直さなければならない。しかも、将来別の国に対応するときにも同じ作業が発生する。これは手間がかかるだけでなく、修正漏れやバグの原因にもなる。
ここで「ロケール」という考え方を導入する。ロケールとは「言語や国などの地域情報」をまとめたものであると説明する。たとえば、スマートフォンの言語設定を英語に変えると、アプリのメニュー表示や日付形式が自動的に変わる。その裏側で参照されているのがロケールである。
この段階では、ISO規格などの専門的な用語は確認しない。「地域の設定を表す情報があり、それに応じて表示を変えられる」という理解を目標とする。演習では、身近なWebサイトやアプリで、地域設定を変えたときに表示がどう変わるかを例として挙げさせ、「なぜ国際化が必要か」「誰のための機能か」を自分の言葉で説明させる。単に仕組みを覚えるのではなく、「利用者の立場で考える視点」を持つことを重視する。

② Localeクラスを使ってロケール情報を取得し、内容を確認できるようになることの理解まで。
Locale.getDefault()やLocale.USを使ったサンプルコードを実行し、languageやcountryが表示される様子を確認する。実行結果として「ja_JP」や「en_US」といった表示が出ることを見せ、「これは言語と国を組み合わせた情報である」と説明する。
次に「単なる文字列“ja”や“US”だけでは、それが何を表しているか直感的に分かりにくい」という問題を提示する。コードの中に意味の分からない文字列が並ぶと、保守性が下がる。解決策としてLocaleクラスを紹介する。new Locale("ja","JP")やLocale.JAPANなどを実行し、getLanguage()やgetCountry()で中身を確認する演習を行う。また、Locale.JAPANESEのように言語のみを表す定数があることも確認し、国情報がない場合は空文字になることを体験させる。
更にgetDisplayLanguage()やgetDisplayCountry()を使い、表示名がロケールに応じて変わることを確認する。たとえば、日本語環境では「アメリカ合衆国:英語」と表示され、Locale.USを基準にすると「United States : English」と表示される違いを見せる。
学生には、「ロケールは言語コード+国コードで構成される」「表示名は現在のロケールに依存する」「getDefault()は実行環境の設定を反映する」と説明できることを目標とする。

③ 国際化対応の基本設計を説明できるようになることの理解まで。
最後に、ロケールを理解したうえで「では、どう設計するべきか」という問いを立てる。ここで強調するのは、「表示文字列や表示形式を直接コードに書かない」ことが国際化対応の第一歩であるという点である。ロジック(計算や処理)と表示(ユーザーに見せる内容)を分けるという考え方を丁寧に説明する。
演習では、ハードコーディングされた文字列を使った例と、ロケールを利用して表示を切り替える例を比較する。将来、英語・フランス語・イタリア語と対応言語が増えた場合、どちらの設計が変更に強いかを考察させる。まとめとして、「ロケールは地域の設定情報である」「国際化対応とは、その設定に応じて表示を変えられるように設計することである」と説明できることを確認する。そして次回のリソースバンドルにつなげ、「表示内容そのものを切り替える仕組み」を学ぶ予告を行う。

キーワード ① ロケール Locale 言語コード 国コード 国際化
コマの展開方法 社会人講師 AL ICT PowerPoint・Keynote 教科書
コマ用オリジナル配布資料 コマ用プリント配布資料 その他 該当なし
小テスト 「小テスト」については、毎回の授業時間内に、LMS上において当該コマの小テスト(難易度表示付)
復習・予習課題 ◆今回授業の復習
Locale.getDefault()とLocale.USを使って、 同じ日付や数値を表示する簡単なプログラムを作成する。実行結果を見て、違っているところを確認する(例:日付の順番、区切り文字、通貨記号など)
◆次回授業の予習
表示文字列をコードの外に分けると何が便利か、言語を増やすとき、どこを直せばよいかなど、表示文字列を外に分ける意味を考える。 
また、英語と日本語で表示が切り替わる例を考えてみる。

57 リソースバンドルによる多言語対応 科目の中での位置付け 本コマは、前回学んだ「ロケール(地域設定)」を、実際の画面表示の切り替えに結びつける回である。前コマでは「同じプログラムでも地域設定で日付や通貨の見え方が変わる」ことを確認したが、今回は更に一歩進めて、ボタン名やメニューなどの「表示文字列そのもの」を、ロケールに応じて自動的に切り替える方法を学ぶ。コードに日本語や英語を直接書くのではなく、表示用の言葉を外に分離して管理することで、後から言語追加や文言修正がしやすくなることを体験する。次回(58コマ目)の「ローカライズされたフォーマット処理」に向けて、「表示を切り替える設計」の土台を固める回とする。
第57回テキスト
第6章「ローカライズ/フォーマット」 第1節「ローカライズ」
項目2「リソースバンドルによる多言語対応」
コマ主題細目 ① 表示文字列を切り替える必要性とリソースバンドルの考え方 ② ResourceBundleで文字列を取得する基本 ③ 多言語対応の基本設計(ハードコーディングから分離へ)
細目レベル ① 表示文字列を“地域に合わせて切り替える必要性”を、自分の言葉で説明できることの理解まで。
日付や通貨の表示が変わるのは「地域設定(ロケール)」を見ているからだったことを復習し、。ここで今日は「数字の見え方」ではなく、「言葉そのもの(ボタン名・メニュー名)」が変わる話だと予告する。
まず同じプログラムなのに、ロケールが日本ならボタンが「送信」「取消」と出て、ロケールが米国なら「send」「cancel」と出るデモを見せる。「これを今日、自分の手で作る」と宣言し、ゴールをはっきりさせる。学生には「英語版アプリ」「日本語版アプリ」を別々に作るのではなく、「同じプログラムが自動で切り替わる」点に注目してもらう。
次にボタン名をコードに直書きした例(例:`"送信"` をそのまま書く、`"send"` をそのまま書く)を見せる。ここで問いかける。「もし“送信”という言葉を“送る”に変えたくなったら?」「英語を“Send”に直したくなったら?」「フランス語も追加と言われたら?」。直書きだと、画面のあちこちに散らばった文字列を探して全部直すことになる。しかも、修正漏れが起きやすい。更に困るのは、プログラムの処理(ロジック)と表示(言葉)が混ざって、コードが読みにくくなる点である。
ここで、身近な例に結びつける。スマホアプリやWebサービスでは、設定で言語を変えるとメニューが丸ごと変わる。ゲームでも、言語設定で「Start/Options」が「スタート/設定」になる。利用者にとっては当たり前の便利さだが、作る側は「言葉を切り替える仕組み」を用意しないと実現できない。今日学ぶのは、そのための「言葉の引き出し」の作り方だと説明する。
この段階では、「表示に使う言葉を、プログラムの外にまとめて置き、必要なときに取り出す」発想が大事だと伝える。リソースバンドルは、その「言葉のセット」であり、ロケールに応じて適切なセットが選ばれる仕組みだと紹介する。学生には、直書きの問題点(直す場所が増える/漏れやすい/読みにくい)と、分離のメリット(直す場所が1か所/追加が楽)を、短い文章で説明できる状態を目指させる。

② ResourceBundleを使って、ロケールに応じた文字列を取得できることの理解まで。
次に、今日の「型」を見せる。完成形のコードとして、ResourceBundle.getBundle(...) でバンドルを取り出し、`getString("send")` のようにキーを指定して文字列を取得する流れをデモする。学生には「表示したい言葉を直接書く」のではなく、「キー(合図の名前)を指定して取り出す」ことを体験させたい。ここでのキーは、sendやcancelのような短い識別子でよい。
次に問題を見せるパートとして、「バンドルが見つからない」状況を作る。例えば、英語用のファイルを用意せずにUロケールで読み込もうとして例外が出る、あるいはキーを間違えて 「cencel」 のように打ってしまい取得できない、といった「ありがちな失敗」を体験させる。目的は、「うまくいかないときは、言葉の置き場所(バンドル)とキーを確認する」というチェック手順を身に付けることである。その上で解決策を示す。まず、言葉のセットを2種類用意する。日本語用と英語用を用意し、同じキーに対して値だけを変える。ここで、「キーは共通にする(send はどの言語でも sendのキーで取り出す)」「値だけを言語ごとに変える(日本語なら「送信」、英語なら「send」)」ことにする。次に、ロケールの切り替えを行う。Locale.getDefault()と Locale.USを用意し、順番に読み込んで表示する。実行して、出力が日本語→英語に切り替わるのを確認する。実装方法は、最初は理解しやすい形として、クラスで定義する方法(ListResourceBundle)を採用し、後半で「実務ではファイルで管理することが多い」としてプロパティファイル(PropertyResourceBundle)を紹介する。
演習では、「Locale.USで実行すると英語になる」「デフォルトロケールで実行すると日本語になる(環境により違う場合は、明示的に日本ロケールを指定して確認してもよい)」「キーを1つ追加して、両言語に反映できる(例:hello、titleなど)」について扱う。「getBundleで取り出す」「getStringでキーから文字列を取る」「キーは共通で値が変わる」を説明できることを目標とする。

③ 表示文字列を分離する設計の基本を説明できることの理解まで。
最後に、今日やったことを設計として整理する時間を取る。ここで強調したいのは、「英語対応のテクニック」ではなく、「変更に強い作り方」だという点である。
まず、直書きのコードと、リソースバンドルを使ったコードを並べて比較する。直書きは短く見えるが、増えるほど管理が壊れる。例えば、ボタンが10個、画面が5つになったら、直書きの修正箇所は簡単に50か所を超える。更にに言語が増えたら、修正箇所は倍々に増える。一方、リソースバンドル方式では、言葉の変更は「言葉の一覧」だけ直せばよい。プログラムの処理はそのままで、表示だけを差し替えられる。
次に、「キーまで日本語にしてよいか?」という疑問について確認する。キーは人間が管理しやすい名前なら何でもよいが、途中で変えると取得側のコードも直す必要が出るため、キーは「固定の合図」として扱い、値だけを表示用として変えることが基本だと伝える。ここは専門用語ではなく、「合図の名前は変えない、表示する言葉だけ変える」と言い換える。
更に、バンドルが見つからない、キーが無いといったトラブルの扱いも、必要最小限に確認する。深い仕様の暗記は不要だが、学生が困らないように、次の「現場の手順」を覚えてもらう。
・表示が出ない/例外が出る → まず「ファイル名(またはクラス名)」と「キーのスペル」を確認する
・言語の切り替えが起きない → どのロケールを指定しているかを確認する(Locale.USなど)
・直したのに反映されない → 実行している対象(コンパイル結果や配置場所)が合っているか確認する
 次回は、日付や数値など、形式が変わるものをローカライズする回に進む。つまり、国際化対応は「言葉」と「形式」の両方があり、今日は前者を扱ったと位置づける。

キーワード ① ResourceBundle getBundle getString 多言語対応 表示文字列の分離
コマの展開方法 社会人講師 AL ICT PowerPoint・Keynote 教科書
コマ用オリジナル配布資料 コマ用プリント配布資料 その他 該当なし
小テスト 「小テスト」については、毎回の授業時間内に、LMS上において当該コマの小テスト(難易度表示付)
復習・予習課題 ◆今回授業の復習
日本語用・英語用の2種類のリソースを用意し、send/cancelに加えてキーを1つ以上追加して表示が切り替わることを確認する。実行結果(日本語/英語)をそれぞれ1行ずつ確認する。
◆次回授業の予習
日付や金額が「国によって並び順や区切りが変わる」例を探し、どこが変わっているかを見つけてくる。次回は表示文言ではなく、数値や日付の「形式」をローカライズする方法を扱う。

58 ローカライズされたフォーマット処理 科目の中での位置付け 本コマは、前回までの「ロケール」「リソースバンドル(言葉の切り替え)」に続き、数値・通貨・日付などの見せ方を地域に合わせて整える回である。前コマではボタン名などの表示文字列を外に分離し、ロケールで切り替える体験をした。本コマでは、同じ値(例:50000、2021-02-01)でも、国によって区切りや通貨記号、日付の並びが自然に変わることを確認し、Javaのフォーマット機能を使って「利用者にとって読みやすい表示」を作れるようにする。
次回(59コマ目)ではセキュリティとして入力値検査を扱うため、今回は「表示」と「入力(文字列から値へ)」の両方に触れ、文字列を扱うときの注意意識につなげる。

第58回テキスト
第6章「ローカライズ/フォーマット」 第2節「フォーマット」
項目1「ローカライズされたフォーマット処理」
コマ主題細目 ① フォーマットの考え方 ② ロケールに合わせた数値・通貨・日付のフォーマット ③ 文字列から値へ戻す処理と表示設計の整理
細目レベル ① 「値の保存」と「画面に見せる形」が違う理由を説明できることの理解まで。
授業冒頭は前回の復習を10分ほど行い、「表示文字列はリソースバンドルで切り替えられる」ことを短く思い出す。ここで今日は、言葉だけでなく、数字や日付の見え方も同じように切り替わる回だと告げる。
最初に完成形を見せる。例えば同じ「50000」を表示しているのに、日本だと「50,000」「¥50,000」、米国だと「50,000」「$50,000.00」と変わるデモ、同じ「2021-02-01」が日本だと「2021/02/01」、米国だと「2/1/21」と変わるデモを実行して見せる。そして「今日はこの表示を、自分で安全に・楽に作る」と目標を明確にする。
次に「文字列で作ってしまう」例を出す。たとえば “¥”を足して “,” を入れて「¥50,000」と手で組み立てる、日付も”2021/02/01” のように直書きする、といった方法である。ここで、「もし米国向けにしたら、通貨記号は?小数点は?区切りは?」「日付の順番は?」など問いかける。手作業で作ると、国が増えるたびに直す場所が増え、ミスも増える。更に「0の扱い」や「桁区切り」など、細かいルールを自分で全部覚える必要が出てしまう。
ここで「フォーマット」という言葉を導入する。ただし難しい定義ではなく、「同じ値でも、見せるときの形を整えること」だと説明する。レジのレシートやネット通販の金額表示が見やすいのは、裏でフォーマットしているからだと日常例を挙げる。学生には、保存する値は 「50000」のように計算しやすい形で持ち、表示するときだけ「¥50,000」のように整えるのが自然だと理解させる。

② ロケールに応じて、数値・通貨・日付をフォーマットして表示できることの理解まで。
次に、フォーマット用の仕組みを使うと何が解決するのかを、コードを書きながら体験する。授業の流れは「完成形→困る例→解決策」の順で進める。
まず、数値と通貨の表示をロケールで切り替えるプログラムを実行する。日本ロケールでは「¥50,000」、米国ロケールでは「$50,000.00」になり、通貨記号や小数点以下の表示が自動で整うことを確認する。
次に、「$50,000.00」を 「"$" + "50,000" + ".00"」のように組み立てる例を示し、「別の国ならどう直すか」と問いかける。桁区切りや小数点の位置は国ごとに異なる可能性があるため、手作業は危険だと理解させる。
解決策として、ロケール付きのフォーマットに任せる。ここで確認することを「数値は数値用フォーマッタ」「通貨は通貨用フォーマッタ」という2点に絞る。実習では、日本(デフォルト)と米国(Locale.US)で同じ値を表示し、通貨記号・小数点以下・区切りの違いを観察する。続いて日付のフォーマットに進む。完成形として、LocalDateで作った日付が日本では「2021/02/01」、米国では「2/1/21」と表示されるデモを行い、「文字列を直書きしていないのに形が変わる」ことを確かめる。問題提示として "2021/02/01"を直書きした例を示し、米国向けにしたときの並びや区切りを決め打ちすると不安が増えることを体験させる。解決策として、ロケールに合わせた日付フォーマッタを使い、授業では「短い形式(SHORT)」のような定型で十分だと伝える。
演習を通して、「 同じ数値を日本と米国で数値表示・通貨表示し、違いを確認できる」「 同じ日付を日本と米国で表示し、並びや区切りの違いを説明できる」「表示は手作業で組み立てず、フォーマッタに任せる判断ができる」など学ぶ。

③ 文字列から値へ戻す処理(parse)の注意点と表示・入力のつながりの理解まで。
最後の項目では、「表示する」だけで終わらず、「文字列を読み取って値に戻す」場面も扱う。次回(59コマ目)の入力値検査につなげるため、「文字列は形式に依存する」「形式が違えば失敗する」という感覚を持つことを目標とする。
まず、米国形式の数値文字列「500.12」や通貨文字列「$20,456.99」を読み取り、数値に戻すデモを行う。ここで「表示と同じく、読み取りにもルールがある」ことを確認させる。次に、ロケールを変えて読み取りに失敗する例を見せる。たとえば、日本向けのルールで「$20,456.99」を読もうとすると失敗するなど、「見た目が同じでも形式が違えば読めない」ことを体験させる。重要なのは例外名ではなく、「読み取りはどの形式かに依存する」という理解である。表示は利用者に合わせるが、読み取りは形式を決めて行う必要があると整理する。
ここで、「日本の画面で “1,000”と入力されたら?」「米国の画面で”1,000.50”と入力されたら?」と問いかけ、入力形式が曖昧だと誤解や失敗が起きることに気付かせる。だからこそ、入力のルールを明確にする設計が重要だと確認し、次回の内容につなげる。
最後に、メッセージのフォーマットにも簡単に触れる。”Hello {0}” のようなテンプレートに値を埋め込む仕組みを紹介し、リソースバンドルと組み合わせれば「言葉の切り替え+値の埋め込み」ができることを示す。
「通貨表示の違い」「日付表示が変わる理由」「parseが失敗する理由」などを確認し、表示と入力にはルールが必要だという理解を定着させる。

キーワード ① フォーマット 通貨表示 日付表示 NumberFormat DateTimeFormatter parse
コマの展開方法 社会人講師 AL ICT PowerPoint・Keynote 教科書
コマ用オリジナル配布資料 コマ用プリント配布資料 その他 該当なし
小テスト 「小テスト」については、毎回の授業時間内に、LMS上において当該コマの小テスト(難易度表示付)
復習・予習課題 ◆今回授業の復習
同じ数値(例:50000)と同じ日付(例:2021-02-01)を、日本と米国の2種類のロケールで表示するプログラムを考える。数値表示・通貨表示・日付表示の3つを並べ、どこがどう違うかを見つける。
◆次回授業の予習
「入力欄に入ってくる値は信用できない」と言われる理由を、身近な例(会員登録、検索フォーム、アンケートなど)で考えてくる。次回は入力値検査とデータの無害化(IDS)を扱う。

59 入力値検査とデータの無害化(IDS) 科目の中での位置付け 本コマは、「セキュアコーディング」の基礎回である。これまでデータベースアクセス(JDBC)、文字列処理、ファイル操作など、実務でも使用される具体的なAPIの使い方を学んできた。しかし、それらの機能は「正しく動く」だけでは十分ではない。外部から与えられる入力値をどのように受け取り、どのように扱うかによって、プログラムの安全性は大きく左右される。
本コマでは、これまでに学んだ技術を「安全に扱う」という観点から見直す。難しい攻撃手法を詳細に理解することが目的ではなく、「外から入ってくる値はそのまま使わない」という基本原則を体験的に理解することを目標とする。SQL文の組み立て、文字列の検査、ファイルパスの扱いといった具体例を通して、入力値検査とデータの無害化の考え方を身に付ける。

第59回テキスト
第7章「セキュリティ概念」 第1節「セキュリティ」
項目1「入力値検査とデータの無害化(IDS)」
コマ主題細目 ① SQLインジェクションを防ぐための入力値検査とプレースホルダの活用 ② 文字列処理における正規化→検査→無害化の基本手順 ③ パス名の正規化と安全なディレクトリ確認の方法
細目レベル ① SQL文にユーザ入力を直接つなげない書き方を再現できることの理解まで。
前回は「表示形式は環境によって変わる」ことを扱ったが、今日はその逆で「入力される値は信用できない」という話に入る。
まず、完成形として、ユーザIDと新しいパスワードを入力すると、指定した1件だけが更新される簡単なプログラムを実行する。普通の値(例:T100)を入れると問題なく更新される様子を確認する。次に、SQL文を文字列として組み立てるコードを実行し、ユーザIDを普通に入力した場合は一見問題なく動くことを確認する。ここで「動いたから正しい」と思ってしまいやすい点を強調する。続いて、ユーザIDに少し変わった文字列を入れてみる。すると、本来1件だけ更新されるはずが、複数件更新されてしまうことを確認する。
ここでは「文字列をそのまま命令文にくっつけると、命令の一部として解釈されてしまうことがある」という事実を理解することを重視する。また、「SQL文の中に値を直接記述しない」「プレースホルダ(?)を用いる」「値は setString などで後から設定する」という3点の解決策を示す。コードを書きながら、「命令部分」と「値の部分」を分けるだけで安全性が大きく上がることを確認する。
SQL文字列に入力値を埋め込まない、必ずプレースホルダを使うなどの型を確認する。更に簡単な入力チェック、たとえば、「IDは10文字以内」「英数字のみ」など、現実的なルールを1つ追加する。ここでの狙いは、「DBに渡す前に、そもそもおかしい値を弾く」という流れを体験することである。
「文字列連結版では、想定外の入力で挙動が変わること」「プレースホルダ版では、同じ入力でも挙動が安定すること」「簡単な長さチェックを入れるだけでも安全性が上がること」など再確認する。

② 文字列は「正規化してから検査する」という順序を説明できることの理解まで。
ここでは、名前入力欄を例にする。普通に「田中太郎」と入力すれば問題ない。しかし、画面にそのまま表示される場合、特殊な文字列が入ると困ることがある。
まず、入力された文字列を、危険な形で実行させないように処理した上で表示するプログラムを実行する。普通の入力はそのまま表示される。
次に、危険な文字列をそのまま表示してしまうコードを動かす。ここで、「入力された文字はただの文字列ではなく、意味を持ってしまう場合がある」という点を押さえる。
重要なのは順番であることを確認し、間違った順番は「① 検査する、② 正規化する」であり、正しい順番は「① 正規化する、② 検査する」であることを徹底する。「見た目が似ているが中身が少し違う文字」が存在するため、先にそろえてから調べる必要がある、という考え方を押さえる。
  実習では、「Normalizerで文字列をそろえる→その後で禁止文字をチェックする」という流れだけを確認する。ここで覚えてほしいのは、「先にそろえる → その後に調べる」という順序である。ここでは、「入力値をそのまま信用しない」「表示するときも注意が必要」という意識を持つことを目的とする。

③ ファイル名やパスも入力値として扱い、正規化してから安全性を確認できることの理解まで。
最後にファイル操作を扱う。たとえば、「ユーザのホームディレクトリの中だけにファイルを保存する」というプログラムを考える。普通のファイル名を指定すれば問題ない。しかし、入力は自由である。
まず、安全なディレクトリ配下のみを許可するコードを実行し、通常のファイル名では問題なく動くことを確認する。次に問題を見せる。「..」を含むパスを入力すると、想定外の場所にアクセスできる可能性があることを確認する。細かいOSの仕組みには深入りせず、押さえるのは、「見た目のパスと実際にたどり着くパスが違うことがある」という事実である。
  解決策として、「getAbsolutePathではなくgetCanonicalPath を使う」という修正を行う。canonical を使うと、「.」や「..」が整理され、実際の行き先に変換されることを確認する。その上で、安全なディレクトリ配下かどうかを判定するという流れを実装する。ここで覚えるのは、「判定の前に正規化する」という考え方である。SQL文に入力値を直接つなげない、文字列は正規化してから検査する、パスは正規化してから安全性を確認するなどをまとめとし、「入力は信用しない」「そのまま使わない」「一度整えてから使う」という基本姿勢を身に付けることを強調する。

キーワード ① 入力値検査 プレースホルダ PreparedStatement 正規化 Normalizer getCanonicalPath
コマの展開方法 社会人講師 AL ICT PowerPoint・Keynote 教科書
コマ用オリジナル配布資料 コマ用プリント配布資料 その他 該当なし
小テスト 「小テスト」については、毎回の授業時間内に、LMS上において当該コマの小テスト(難易度表示付)
復習・予習課題 ◆今回授業の復習
SQL文を文字列連結で書いた場合と、プレースホルダを使った場合の違いを説明する。また、「正規化してから検査する理由」を簡単にまとめる。
◆次回授業の予習
スマートフォンの「アプリ権限設定」を例に、「OSが守ってくれる部分」と「アプリ側で守るべき部分」を考えてくる。次回はプラットフォームセキュリティを扱う。

60 プラットフォームセキュリティと雑則(SEC/MSC) 科目の中での位置付け 本コマは、環境プログラミングⅢの最終回として、これまで学んだ「正しく動くプログラム」を「安全に動くプログラム」へ一段引き上げる回である。前コマでは入力値検査(IDS)として「外から入ってくる値は信用しない」姿勢を学んだ。本コマでは、同じアプリの中でも「権限が違う部品」が混在するときに何が起こるか、そして安全に動かすためにどんな書き方が必要かを体験する。加えて、反復処理中にコレクションを壊してしまう典型例も扱い、「安全性は攻撃対策だけでなく、壊れにくい書き方の積み重ねで作られる」ことをまとめとして理解する回とする。
第60回テキスト
第7章「セキュリティ概念」 第1節「セキュリティ」
項目2「プラットフォームセキュリティと雑則(SEC/MSC)」 
コマ主題細目 ① 権限の違う部品を呼び出したときに起きる失敗(SECの導入) ② doPrivilegedの考え方と「特権処理の入口を狭くする」設計 ③ 反復処理で壊さないコレクション操作(MSC06-J)と総まとめ
細目レベル ① 権限の違いによって「同じコードでもできる/できない」が変わることを説明できることの理解まで。
まず、前コマ(IDS)の復習として、「入力は信用しない」「安全にするには、まず“危ない入力を入れても壊れないこと”を確認する」という姿勢を振り返る。続いて今日の学習内容について、「学生証だけで入れる部屋」と「職員しか入れない部屋」があるように、プログラムの世界でもできることの範囲(権限)が部品ごとに違うことがあるという例示で説明する。ここで大切なのは「同じアプリの中でも、全部が全部なんでもできるわけではない」という感覚を持つことである。次に、こちらで用意したサンプルを実行し、「あるメソッドはシステム設定を書き換えようとしているが、呼び出し元の権限が弱いと失敗する」デモを行う。
「これを“わざと失敗させて”、そのあと“安全に動かす直し方”を作る」とゴールを明確にする。その後、libA(権限が弱い)からlibB(権限が強い想定)のメソッドを呼び出す例を示し、「libBの中に“書き込み”処理があるのに、呼び出し元が弱いと書き込みができずエラーになる」状況を確認する。ここでは、「権限が違う部品が混ざると、実行時は“弱い方”に引っ張られることがある」「その結果、「コードは正しいつもりでも、環境(権限)によって失敗する」という因果関係について確認する。
演習では、最小の手順で「失敗を再現」する。まずは実行して例外が出ることを確認し、次に「どの行で止まったか」を読み取る練習をする。「原因は“書き込み処理そのもの”ではなく、“誰の権限で実行されたか”にある」と説明できる状態を目指す。最後に、これらの内容がが実務でどういう点につながるかを例示する。たとえば、ライブラリがファイルを読む/設定を変える/環境変数を見る、といった強い操作を持っているとき、呼び出し側の都合で簡単に動かなくなる、あるいは逆に、強い操作を外に漏らすと危険になる。つまり、「便利な処理ほど、入口の作り方が大切である」ということを認識させる。

② doPrivilegedの役割を「強い処理を安全に実行するための枠」として説明できることの理解まで。
次に、本コマの学習の中心となる解決策へ入る。最初に、先ほど失敗した例を、doPrivileged を使ったプログラムに差し替えて実行し、「呼び出し元が弱くても、libBの中で必要な範囲だけ強い権限で動かせる」ことを確認する。「これで直るなら、全部 doPrivileged にすればいいのでは?」と思わせてから、そうすると危険になる、という流れで理解を作る。
ここでの説明は、APIの暗記ではなく「考え方」に絞る。doPrivileged は、言い換えると「職員室でしかできない作業を、職員が立ち会って、その場でだけ実施する」ようなものだと伝える。つまり、強い権限で動くのは便利だが、むやみに広げると事故が起きる。だからこそ、特権で実行する範囲はできるだけ小さくし、入口もできるだけ狭くする必要がある。
演習では、「特権処理の入口が広すぎる不適切コード」を確認する。例として、機密ファイルを開く処理を doPrivileged に入れているのに、その openFile() が public だと「外のクラスからも呼べてしまう」ことを示す。ここでは、「doPrivileged は強い道具なので、公開範囲(public)と相性が悪い」「“強い操作の入口”を外に見せると、想定外の使われ方をされる」という二点について理解させる。また、publicのopenFile()を外から呼べることを確認し、それが「機密ファイルを開く権限を、外に貸しているのと同じ」だと気付かせる。ここで大切なのは「攻撃者」など難しい話ではなく、「自分のコードでも、別の人が使ったときに事故が起きる」という現実的な危険であるということである。
解決策として、openFile()をprivate にして「changeData()の中からしか使えない」形に直す。コードを書きながら、「外に見せてよい入口(公開API)」「内部だけで使う入口(private)」を分ける設計の基本を整理する。doPrivileged を使う目的や特権処理の入口は public にしない理由について、再確認する。

③ 繰り返し処理中にコレクションを安全に操作し、例外を再現して直せることの理解まで。
最後の内容として、雑則(MSC)として「ありがちな壊れ方」を扱い、授業全体のまとめにつなげる。最初に完成形として、リストから条件に合う要素(例:orange)を削除して、最後に(apple) だけ残るプログラムを見せる。ここでは、「今日の最後は、見た目は簡単なのに、よく例外で落ちる罠を体験する」と伝える。
次に、Iteratorで回している途中に list.remove(...) で消す不適切コードを動かし、ConcurrentModificationException が出るところまでを確認する。ここは攻撃ではなく「壊れやすさ」の話であり、「読んでいる最中に、名簿(リスト)を書き換えると、読み手(Iterator)が混乱するから、「消すなら、Iteratorに消してもらう」が基本になるということについて理解させる。解決策としてiter.remove()を使う版に直し、同じデータでも例外が出ずに削除できることを確認する。
演習では、「例外が出る版を実行して止まる→ 直した版を実行して最後まで動く→なぜ直ったのか」を一文で書く。更に、時間が許す範囲で「マルチスレッドだと別の危険が出る」ことを紹介する。「複数人が同じ共有ノートを同時に書き換えると、順番が崩れて壊れることがある」という例で、同期やスレッドセーフなコレクションの存在だけを紹介する。「単一スレッドでも壊れる例外があるし、複数スレッドならなおさら注意が必要」という意識を残すことが目的である。
最後に本コマのまとめとして、SECとMSCを一本の線でつなぐ。SECは「権限の強い処理は、入口と範囲を絞って安全に扱う」。MSCは「よくある壊れ方を知り、安全な書き方に直す」。両方に共通するのは、便利な操作ほど、扱い方を間違えると事故になるという点だと整理する。

キーワード ① doPrivileged private ConcurrentModificationException Iterator.remove
コマの展開方法 社会人講師 AL ICT PowerPoint・Keynote 教科書
コマ用オリジナル配布資料 コマ用プリント配布資料 その他 該当なし
小テスト 「小テスト」については、毎回の授業時間内に、LMS上において当該コマの小テスト(難易度表示付)
復習・予習課題 ◆今回授業の復習
doPrivileged を使う理由を、自分の言葉でにまとめる(例:強い処理を必要な範囲だけ安全に行うため)。また、Iteratorで回しながらlist.remove をすると例外になる理由と、iter.remove で直る理由をまとめる。
◆次回授業の予習
本授業は最終回のため予習は不要である。これまでの授業で扱った「例外が出たコード」を1つ選び、どの行が原因で、どう直したかなど思い出す。

履修判定指標
履修指標履修指標の水準キーワード配点関連回
Java標準APIと文字列操作の基礎 Java標準APIを「最初から利用できる基本的な道具箱」として捉え、Stringがオブジェクトであること、length・equals・compareToなどの基本メソッドの役割を理解できる。さらに、空文字や空白の扱い、文字列を比較するときの基本的な見方を判断できる。
【難易度★★普通】
isEmpty・isBlank・trim・strip・contains・indexOf・lastIndexOf・substringなどについて、どのような場面で用いるかを理解し、簡単なコード例から適切なメソッドを選択できる。
【難易度★★★難しい】
split・join・String.format・StringBuilderなどを用いた文字列の整形や組立てについて、読みやすい出力を行うための基本的な考え方を理解し、簡単な処理手順を判断できる。
8問
Java標準API / String / length / equals / compareTo / isEmpty / isBlank / trim / strip / contains / indexOf / lastIndexOf / substring / split / join / String.format / StringBuilder 16 1-7
正規表現によるマッチ・検索・置換 【【難易度★やさしい】
正規表現を「文字列の形を調べるための書き方」として理解し、数字・英字・記号などの簡単なパターンを見分けることができる。
【難易度★★普通】
matches と Pattern / Matcher の違い、find による検索の流れ、group の基本的な見方を理解し、簡単な例からどの方法を使うべきか判断できる。
【難易度★★★難しい】
replaceAll などを用いた簡単な置換や分割処理について、用途に応じた選択ができ、文字列処理の一部として利用する考え方を理解できる。
5問
正規表現 / matches / Pattern / Matcher / find / group / replaceAll 10 8-12
Date-Time APIの生成・比較・整形・計算 【難易度★やさしい】
LocalDate・LocalDateTime などの日付・時刻クラスの基本を理解し、日付の生成、現在日時の取得、表示結果の基本的な見方を理解できる。
【難易度★★普通】
equals・isBefore・isAfter を用いた前後比較や、plus・minus による簡単な加減算の考え方を理解し、簡単な設問で正しいメソッドを選択できる。
【難易度★★★難しい】
Period・Duration の基本、DateTimeFormatter の役割、LocalDate・LocalDateTime・ZonedDateTime など複数クラスの基本的な使い分けを理解できる。
6問
java.time / LocalDate / LocalDateTime / ZonedDateTime / DateTimeFormatter / equals / isBefore / isAfter / Period / Duration / plus / minus 12 13-18
配列・コピー・Unicode 正規化 【難易度★やさしい】
Arrays.sort・Arrays.toString などを用いた配列の基本操作を理解し、並べ替え結果や表示結果の見方を判断できる。
【難易度★★普通】
binarySearch の前提条件や copyOf / copyOfRange の基本的な用途を理解し、どの場面で使うかを選択できる。
【難易度★★★難しい】
シャローコピーとディープコピーの違い、Normalizer による Unicode 正規化の基本目的を理解し、データ前処理の必要性を説明できる。
3問
Arrays / sort / binarySearch / toString / copyOf / copyOfRange / シャローコピー / ディープコピー / Normalizer / Unicode正規化 6 19-20
ファイル操作とコレクション基礎 【難易度★やさしい】
Path / Paths / Files による基本的なファイル操作の流れと、List・Set・Map・Deque の基本的な違い(順序・重複・キー)を理解できる。
【難易度★★普通】
exists・copy・move・delete・deleteIfExists などの基本操作の違い、ならびに ArrayList・LinkedList・HashSet・TreeSet・HashMap・TreeMap・ArrayDeque など代表的な実装の特徴を理解できる。
【難易度★★★難しい】
状態確認をしてから操作する手順や、Iterator を用いた安全な走査・削除の基本的な考え方を理解し、簡単な場面で適切な方法を選択できる。
4問
Files / Path / Paths / exists / copy / move / delete / deleteIfExists / List / Set / Map / Deque / ArrayList / LinkedList / HashSet / TreeSet / HashMap / TreeMap / ArrayDeque / Iterator 8 21-24
列挙型・レコード・入れ子クラス 【難易度★やさしい】
enum と record の基本的な役割を理解し、それぞれがどのようなデータ表現に向いているかを判断できる。
【難易度★★普通】
EnumSet の基本的な利用場面や、入れ子クラスの種類が複数あることを理解し、授業で扱った例から基本的な意味を説明できる。
【難易度★★★難しい】
static メンバークラス、非 static メンバークラス、匿名クラス、ローカルクラスの違いを、基礎的な範囲で説明できる。
5問
ラムダ式 / 関数型インターフェイス / java.util.function / Consumer / Function / Predicate / Supplier / メソッド参照 / 型推論 / removeIf / Map.compute / computeIfPresent / computeIfAbsent / merge / BiFunction / Collection / HashMap 10 25‐31
ラムダ式・関数型インターフェイス・コレクション操作 【難易度★やさしい】
匿名クラスからラムダ式への簡単な読み替えができ、ラムダ式の基本的な書き方、メソッド参照の初歩、removeIf が「条件に合う要素を削除する処理」であることを理解できる。
【難易度★★普通】
型推論、引数の括弧の省略、波括弧と return の省略などの基本的な省略規則を判断でき、Predicate・Function などの基本的な役割を理解できる。さらに、compute・computeIfPresent・computeIfAbsent の違いを、キーの有無と処理の流れから理解できる。
【難易度★★★難しい】
Consumer・Function・Predicate・Supplier の使い分け、merge による値のまとめ方、簡単な BiFunction の役割を理解し、簡単なコード読解で適切な選択ができる。
5問
コレクションフレームワーク/
List/Set/Map/Deque/ArrayList/LinkedList/HashSet/TreeSet/HashMap/TreeMap/ArrayDeque/Iterator
10 32-37
Stream API の基礎 【難易度★やさしい】
Stream の処理が「生成→中間処理→終端処理」という流れで構成されることを理解し、遅延評価の基本的な考え方をつかむことができる。
【難易度★★普通】
filter・map・flatMap・sorted・limit・skip・distinct などの基本的な中間処理の役割を理解し、簡単な用途を判断できる。
【難易度★★★難しい】
forEach・findFirst・collect・toList・toMap・reduce・Optional などの終端処理の基本を理解し、処理結果のまとめ方を判断できる。
4問
enum/EnumSet/record/パターンマッチング/Nested Class/staticメンバークラス/非staticメンバークラス/匿名クラス/ローカルクラス/Outer.this 8 38-43
ラムダ式と関数型インターフェイス(読み替えと省略規則)並行処理・アノテーション・モジュール 【難易度★やさしい】
並行処理、アノテーション、モジュールについて、授業で扱う基本用語の意味を理解し、それぞれがどの分野の技術であるかを区別できる。
【難易度★★普通】
synchronized・ReentrantLock・AtomicInteger・volatile・ExecutorService・Executors・Future など、代表的な仕組みや API の基本的な役割を理解し、簡単な説明問題で正しく選択できる。
【難易度★★★難しい】
CompletableFuture、@Override・@Deprecated・@Target・@Retention などの標準アノテーション、module-info.java、requires / exports の基本的な用途や位置づけを理解できる。
6問
synchronized / ReentrantLock / AtomicInteger / volatile / ExecutorService / Executors / shutdown / Future / CompletableFuture / @Override / @Deprecated / @Target / @Retention / getAnnotation / module-info.java / requires / exports 12 44-55
ローカライズ・セキュリティ 【難易度★やさしい】
ロケールによって表示や書式が変わること、セキュリティ対策が安全なプログラム作成に必要であることを理解し、基本用語の意味を判断できる。
【難易度★★普通】
Locale・ResourceBundle・NumberFormat などを用いた表示切替や数値整形の基本的な考え方を理解し、PreparedStatement が SQL インジェクション対策に有効であることを理解できる。
【難易度★★★難しい】
doPrivileged の位置づけや Unicode 正規化との関係を含め、ローカライズとセキュリティを学ぶ意義を基礎的な範囲で説明できる。
4問
Locale / ResourceBundle / NumberFormat / PreparedStatement / Normalizer / doPrivileged 8 56-60
評価方法
評価基準 評語
    学習目標をほぼ完全に達成している・・・・・・・・・・・・・ S (100~90点)
    学習目標を相応に達成している・・・・・・・・・・・・・・・ A (89~80点)
    学習目標を相応に達成しているが不十分な点がある・・・・・・ B (79~70点)
    学習目標の最低限は満たしている・・・・・・・・・・・・・・ C (69~60点)
    学習目標の最低限を満たしていない・・・・・・・・・・・・・ D (60点未満)
教科書
参考文献
実験・実習・教材費