【サクッと習得】Java学習教材

# はじめに
**情報処理安全確保支援士の学習にあたってJavaの知識が必要**なので、自己学習しました。
その際に学習した内容をまとめたので、**情報処理安全確保支援士の学習をする方**や**Javaを短時間で学習したい方**の参考になれば良いと思い教材を作成しました。
**専門書を買うほどでもなくサクッと言語を学習したい方**におすすめです。


# 目次

[1.概要](#1概要)
[2.基本的な構文](#2基本的な構文)
[2-1.コメント](#2-1コメント)
[2-2.変数とデータ型](#2-2変数とデータ型)
[2-3.演算子](#2-3演算子)
[2-4.制御文](#2-4制御文)
[2-5.配列](#2-5配列)
[2-6.メソッド](#2-6メソッド)
[2-7.クラスとオブジェクト](#2-7クラスとオブジェクト)
[2-8.継承](#2-8継承)
[2-9.インタフェース](#2-9インタフェース)
[2-10.例外処理](#2-10例外処理)
[2-11.組み込み関数](#2-11組み込み関数)
[3.高度なトピック](#3高度なトピック)
[3-1.パッケージ](#3-1パッケージ)
[3-2.アクセス修飾子](#3-2アクセス修飾子)
[3-3.コレクションフレームワーク](#3-3コレクションフレームワーク)
[3-4.ジェネリクス](#3-4ジェネリクス)
[3-5.スレッドと並行処理](#3-5スレッドと並行処理)
[3-6.ファイル操作](#3-6ファイル操作)
[3-7.ラムダ式とストリームAPI](#3-7ラムダ式とストリームAPI)
[4.練習問題](#4練習問題)
[4-1.基本文法の復習](#4-1基本文法の復習)
[4-2.高度なトピックの復習](#4-2高度なトピックの復習)
[5.まとめ](#5まとめ)

# 1.概要

Javaは、Webアプリケーションからデスクトップアプリケーション、モバイルアプリケーションまで幅広い用途で利用される強力なプログラミング言語です。本教材では、特に**Javaに初めて触れるエンジニアを対象**に、**基本的な文法**から**オブジェクト指向プログラミング**、そしてさらに高度な機能までをカバーします。

# 2.基本的な構文

## 2-1.コメント
Javaでは、コードにコメントを追加する方法として以下の3種類があります。
- シングルラインコメント (<font color="Red">//</font>)
- マルチラインコメント (<font color="Red">/* ... */</font>)
- ドキュメンテーションコメント (<font color="Red">/** ... */</font>)
```
// これはシングルラインコメントです

/*
  これはマルチラインコメントです
  複数行にわたるコメントを記述できます
*/

/**
 * これはドキュメンテーションコメントです
 * クラスやメソッドの説明を記述するのに使います
 */
public class Example {
    public static void main(String[] args) {
        System.out.println("Hello, World!"); // 行末のコメント
    }
}
```

## 2-2.変数とデータ型
Javaには主に8種類の基本データ型があります。

#### 基本データ型
- 整数型: <font color="Red">byte</font>, <font color="Red">short</font>, <font color="Red">int</font>, <font color="Red">long</font>
- 浮動小数点型: <font color="Red">float</font>, <font color="Red">double</font>
- 文字型: <font color="Red">char</font>
- 論理型: <font color="Red">boolean</font>

```
public class DataTypes {
    public static void main(String[] args) {
        // 整数型の変数を宣言
        byte a = 10;        // 8ビット整数
        short b = 20;       // 16ビット整数
        int c = 30;         // 32ビット整数
        long d = 40L;       // 64ビット整数（Lを付ける）

        // 浮動小数点型の変数を宣言
        float e = 3.14f;    // 32ビット浮動小数点数（fを付ける）
        double f = 2.71828; // 64ビット浮動小数点数

        // 文字型の変数を宣言
        char g = 'A';       // 16ビットUnicode文字

        // 論理型の変数を宣言
        boolean h = true;   // 真偽値

        // 変数の値を出力
        System.out.println("byte: " + a);
        System.out.println("short: " + b);
        System.out.println("int: " + c);
        System.out.println("long: " + d);
        System.out.println("float: " + e);
        System.out.println("double: " + f);
        System.out.println("char: " + g);
        System.out.println("boolean: " + h);
    }
}
```

## 2-3.演算子

演算子には以下の種類があります。

算術演算子: <font color="Red">+</font>, <font color="Red">-</font>, <font color="Red">*</font>, <font color="Red">/</font>, <font color="Red">%</font>
代入演算子: <font color="Red">=</font>, <font color="Red">+=</font>, <font color="Red">-=</font>, <font color="Red">*=</font>, <font color="Red">/=</font>, <font color="Red">%=</font>
比較演算子: <font color="Red">==</font>, <font color="Red">!=</font>, <font color="Red">></font>, <font color="Red"><</font>, <font color="Red">>=</font>, <font color="Red"><=</font>
論理演算子: <font color="Red">&&</font>, <font color="Red">||</font>, <font color="Red">!</font>
インクリメント・デクリメント演算子: <font color="Red">++</font>, <font color="Red">--</font>

```
public class Operators {
    public static void main(String[] args) {
        int a = 10;
        int b = 20;

        // 算術演算子を使用した例
        System.out.println("a + b = " + (a + b)); // 加算
        System.out.println("a - b = " + (a - b)); // 減算
        System.out.println("a * b = " + (a * b)); // 乗算
        System.out.println("a / b = " + (a / b)); // 除算
        System.out.println("a % b = " + (a % b)); // 剰余

        // 比較演算子を使用した例
        System.out.println("a == b: " + (a == b)); // 等価
        System.out.println("a != b: " + (a != b)); // 不等価
        System.out.println("a > b: " + (a > b));   // 大なり
        System.out.println("a < b: " + (a < b));   // 小なり
        System.out.println("a >= b: " + (a >= b)); // 大なりイコール
        System.out.println("a <= b: " + (a <= b)); // 小なりイコール

        // 論理演算子を使用した例
        System.out.println("(a > 5) && (b > 15): " + ((a > 5) && (b > 15))); // AND
        System.out.println("(a > 15) || (b > 15): " + ((a > 15) || (b > 15))); // OR
        System.out.println("!(a > 15): " + (!(a > 15))); // NOT

        // インクリメント・デクリメント演算子を使用した例
        a++;
        b--;
        System.out.println("a after increment: " + a); // インクリメント
        System.out.println("b after decrement: " + b); // デクリメント
    }
}
```

## 2-4.制御文

制御構文には以下の種類があります。

- 条件分岐: <font color="Red">if</font>, <font color="Red">else</font>, <font color="Red">switch</font>
- ループ: <font color="Red">for</font>, <font color="Red">while</font>, <font color="Red">do-while</font>
- ブレークとコンティニュー: <font color="Red">break</font>, <font color="Red">continue</font>

```
public class ControlStructures {
    public static void main(String[] args) {
        int number = 20;

        // if-else文を使用した条件分岐
        if (number < 10) {
            System.out.println("number is less than 10");
        } else {
            System.out.println("number is greater than or equal to 10");
        }

        // switch文を使用した条件分岐
        switch (number) {
            case 10:
                System.out.println("number is 10");
                break;
            case 20:
                System.out.println("number is 20");
                break;
            default:
                System.out.println("number is neither 10 nor 20");
                break;
        }

        // forループを使用した繰り返し処理
        for (int i = 0; i < 5; i++) {
            System.out.println("for loop iteration: " + i);
        }

        // whileループを使用した繰り返し処理
        int i = 0;
        while (i < 5) {
            System.out.println("while loop iteration: " + i);
            i++;
        }

        // do-whileループを使用した繰り返し処理
        i = 0;
        do {
            System.out.println("do-while loop iteration: " + i);
            i++;
        } while (i < 5);

        // break文とcontinue文を使用したループ制御
        for (i = 0; i < 10; i++) {
            if (i == 5) {
                break; // ループを終了
            }
            if (i % 2 == 0) {
                continue; // 次のイテレーションにスキップ
            }
            System.out.println("break and continue: " + i);
        }
    }
}
```

## 2-5.配列

配列は同じデータ型の複数の値を格納するためのデータ構造です。


```
public class Arrays {
    public static void main(String[] args) {
        // 一次元配列の宣言と初期化
        int[] numbers = {1, 2, 3, 4, 5};
        for (int i = 0; i < numbers.length; i++) {
            System.out.println("number: " + numbers[i]);
        }

        // 二次元配列の宣言と初期化
        int[][] matrix = {
            {1, 2, 3},
            {4, 5, 6},
            {7, 8, 9}
        };
        for (int i = 0; i < matrix.length; i++) {
            for (int j = 0; j < matrix[i].length; j++) {
                System.out.println("matrix[" + i + "][" + j + "]: " + matrix[i][j]);
            }
        }
    }
}
```
## 2-6.メソッド
メソッドは一連の命令をまとめたものです。メソッドには引数と戻り値を持つことができます。

```
public class Methods {
    public static void main(String[] args) {
        int result = add(10, 20); // メソッド呼び出しと戻り値の受け取り
        System.out.println("Result of add: " + result);

        greet("Alice"); // メソッド呼び出し
    }

    // 引数と戻り値を持つメソッド
    public static int add(int a, int b) {
        return a + b; // 呼び出し元に戻り値を返す
    }

    // 引数を持つが戻り値を持たないメソッド
    public static void greet(String name) {
        System.out.println("Hello, " + name); // メッセージを出力
    }
}
```

## 2-7.クラスとオブジェクト
Javaはオブジェクト指向言語であり、クラスとオブジェクトが基本概念です。

```
public class Person {
    // フィールド（インスタンス変数）
    String name;
    int age;

    // コンストラクタ
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // メソッド
    public void introduce() {
        System.out.println("Hello, my name is " + name + " and I am " + age + " years old.");
    }

    public static void main(String[] args) {
        // オブジェクトの生成
        Person person = new Person("Bob", 30);
        person.introduce(); // メソッド呼び出し
    }
}
```

## 2-8.継承
Javaでは、既存のクラスを継承して新しいクラスを作成することができます。継承には <font color="Red">extends</font> キーワードを使用します。

```
// 親クラス（基底クラス）
class Animal {
    void eat() {
        System.out.println("This animal eats food.");
    }
}

// 子クラス（派生クラス）
class Dog extends Animal {
    void bark() {
        System.out.println("The dog barks.");
    }
}

public class Inheritance {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.eat();  // 親クラスのメソッドを呼び出し
        dog.bark(); // 子クラスのメソッドを呼び出し
    }
}
```

## 2-9.インタフェース
インタフェースは、クラスが実装すべきメソッドのセットを定義します。インタフェースには <font color="Red">interface</font> キーワードを使用します。

```
// インタフェースの定義
interface Animal {
    void eat();
    void makeSound();
}

// インタフェースの実装
class Dog implements Animal {
    public void eat() {
        System.out.println("Dog eats bones.");
    }

    public void makeSound() {
        System.out.println("Dog barks.");
    }
}

public class Interfaces {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.eat();
        dog.makeSound();
    }
}
```

## 2-10.例外処理
Javaでは、例外処理のために <font color="Red">try</font>, <font color="Red">catch</font>, <font color="Red">finally</font> ブロックを使用します。

```
public class ExceptionHandling {
    public static void main(String[] args) {
        try {
            int result = divide(10, 0); // 例外が発生する可能性のあるコード
            System.out.println("Result: " + result);
        } catch (ArithmeticException e) {
            System.out.println("Error: " + e.getMessage()); // 例外が発生した場合の処理
        } finally {
            System.out.println("Finally block executed."); // 常に実行される処理
        }
    }

    public static int divide(int a, int b) {
        return a / b; // 数値を割り算する（0で割ると例外が発生する）
    }
}
```

## 2-11.組み込み関数
Javaには多くの組み込み関数（標準ライブラリ）があり、開発を効率化するために利用できます。ここでは、いくつかの重要なクラスとそのメソッドを紹介します。

### 文字列操作: <font color="Red">String クラス</font>

- <font color="Red">length()</font>：文字列の長さを返します。
- <font color="Red">charAt(int index)</font>：指定された位置にある文字を返します。
- <font color="Red">substring(int beginIndex, int endIndex)</font>：指定された開始位置と終了位置の間にある部分文字列を返します。
- <font color="Red">concat(String str)</font>：指定された文字列をこの文字列の末尾に連結します。
- <font color="Red">replace(CharSequence target, CharSequence - replacement)</font>：指定された対象文字列を新しい文字列に置き換えます。
- <font color="Red">split(String regex)</font>：正規表現に基づいて文字列を分割し、配列で返します。

```
public class StringExample {
    public static void main(String[] args) {
        String str = "Hello, World!";
        
        // 文字列の長さを取得
        int length = str.length();
        System.out.println("Length: " + length);

        // 特定の文字を取得
        char charAt = str.charAt(0);
        System.out.println("Character at index 0: " + charAt);

        // 部分文字列を取得
        String substring = str.substring(7, 12);
        System.out.println("Substring: " + substring);

        // 文字列の連結
        String concatenated = str.concat(" How are you?");
        System.out.println("Concatenated string: " + concatenated);

        // 文字列の置換
        String replaced = str.replace("World", "Java");
        System.out.println("Replaced string: " + replaced);

        // 文字列の分割
        String[] parts = str.split(", ");
        for (String part : parts) {
            System.out.println("Part: " + part);
        }
    }
}
```

### 数学計算: <font color="Red">Math クラス</font>

- <font color="Red">Math.abs(double a)</font>：絶対値を返します。
- <font color="Red">Math.max(double a, double b)</font>：2つの引数のうち大きい方の値を返します。
- <font color="Red">Math.min(double a, double b)</font>：2つの引数のうち小さい方の値を返します。
- <font color="Red">Math.pow(double a, double b)</font>：aをb乗した値を計算して返します。
- <font color="Red">Math.random()</font>：0.0以上1.0未満の乱数を返します。
- <font color="Red">Math.round(double a)</font>：最も近い整数に丸めた値を返します。

```
public class MathExample {
    public static void main(String[] args) {
        double num = -5.5;
        
        // 絶対値を取得
        double absValue = Math.abs(num);
        System.out.println("Absolute value: " + absValue);

        // 最大値と最小値を取得
        double max = Math.max(10, 20);
        double min = Math.min(10, 20);
        System.out.println("Max value: " + max);
        System.out.println("Min value: " + min);

        // 累乗を計算
        double powValue = Math.pow(2, 3);
        System.out.println("2^3: " + powValue);

        // 制限範囲内の乱数を生成
        double randomValue = Math.random() * 10; // 0.0から10.0の範囲の乱数を生成
        System.out.println("Random value: " + randomValue);

        // 四捨五入
        long roundValue = Math.round(3.14);
        System.out.println("Rounded value: " + roundValue);
    }
}
```

### 日付操作: <font color="Red">LocalDate, LocalTime, LocalDateTime クラス</font>

- <font color="Red">LocalDate.now()</font>：現在の日付を取得します。
- <font color="Red">LocalTime.now()</font>：現在の時刻を取得します。
- <font color="Red">LocalDateTime.now()</font>：現在の日付と時刻を取得します。
- <font color="Red">LocalDate.of(int year, Month month, int dayOfMonth)</font>：指定された年、月、日を持つ特定の日付を作成します。
- <font color="Red">LocalDate.plusDays(long daysToAdd)</font>：指定された日数をこの日付に加算します。
- <font color="Red">LocalDate.minusDays(long daysToSubtract)</font>：指定された日数をこの日付から引きます。

```
import java.time.*;

public class DateTimeExample {
    public static void main(String[] args) {
        // 現在の日付を取得
        LocalDate currentDate = LocalDate.now();
        System.out.println("Current date: " + currentDate);

        // 現在の時刻を取得
        LocalTime currentTime = LocalTime.now();
        System.out.println("Current time: " + currentTime);

        // 現在の日付と時刻を取得
        LocalDateTime currentDateTime = LocalDateTime.now();
        System.out.println("Current date and time: " + currentDateTime);

        // 特定の日付を作成
        LocalDate specificDate = LocalDate.of(2023, Month.JANUARY, 1);
        System.out.println("Specific date: " + specificDate);

        // 日付の加算と減算
        LocalDate tomorrow = currentDate.plusDays(1);
        LocalDate yesterday = currentDate.minusDays(1);
        System.out.println("Tomorrow: " + tomorrow);
        System.out.println("Yesterday: " + yesterday);
    }
}
```

### コレクション操作: <font color="Red">Collection クラス</font>

- <font color="Red">add(E e)</font>：コレクションに要素を追加します。
- <font color="Red">remove(Object o)</font>：コレクションから指定された要素を削除します。
- <font color="Red">contains(Object o)</font>：コレクションが指定された要素を含む場合に true を返します。
- <font color="Red">size()</font>：コレクションの要素数を返します。
- <font color="Red">Collections.sort(List<T> list)</font>：リストを昇順にソートします。

```
import java.util.*;

public class CollectionExample {
    public static void main(String[] args) {
        // リストの作成と操作
        List<String> list = new ArrayList<>();
        list.add("Apple");
        list.add("Banana");
        list.add("Cherry");

        // 要素を出力
        for (String item : list) {
            System.out.println("Item: " + item);
        }

        // 要素を削除
        list.remove("Banana");
        System.out.println("After removing Banana: " + list);

        // 要素の存在を確認
        boolean contains = list.contains("Apple");
        System.out.println("Contains Apple: " + contains);

        // コレクションのサイズを取得
        int size = list.size();
        System.out.println("List size: " + size);

        // コレクションのソート
        Collections.sort(list);
        System.out.println("Sorted list: " + list);
    }
}
```

### 正規表現操作: <font color="Red">Pattern クラスと Matcher クラス</font>

- <font color="Red">Pattern.compile(String regex)</font>：指定された正規表現を使用してパターンをコンパイルします。
- <font color="Red">matcher(CharSequence input)</font>：入力シーケンスに対してパターンを適用するマッチャーを作成します。
- <font color="Red">find()</font>：次の正規表現パターンに一致する部分を見つけます。
- <font color="Red">group()</font>：一致した部分文字列を返します。

```
import java.util.regex.*;

public class RegexExample {
    public static void main(String[] args) {
        String text = "Java is a programming language.";
        String patternString = "\\bprogramming\\b";

        // パターンのコンパイル
        Pattern pattern = Pattern.compile(patternString);
        Matcher matcher = pattern.matcher(text);

        // パターンに一致する部分を見つける
        if (matcher.find()) {
            System.out.println("Found: " + matcher.group());
        } else {
            System.out.println("Not found");
        }

        // すべてのパターンに一致する部分を見つける
        String text2 = "cat, cats, caterpillar";
        Pattern pattern2 = Pattern.compile("\\bcat\\b");
        Matcher matcher2 = pattern2.matcher(text2);

        while (matcher2.find()) {
            System.out.println("Found: " + matcher2.group());
        }
    }
}
```

# 3.高度なトピック

## 3-1.パッケージ
パッケージは関連するクラスをまとめるための仕組みです。パッケージを使用することで、クラスの名前空間を整理し、名前の衝突を避けることができます。

```
// パッケージの宣言
package com.example;

// インポート文
import java.util.Date;

public class PackageExample {
    public static void main(String[] args) {
        Date date = new Date(); // Dateクラスを使用
        System.out.println("Current date: " + date);
    }
}
```

## 3-2.アクセス修飾子
アクセス修飾子を使用して、クラス、メソッド、フィールドのアクセスレベルを制御できます。Javaには4種類のアクセス修飾子があります。

<font color="Red">public</font>: すべてのクラスからアクセス可能
<font color="Red">protected</font>: 同じパッケージ内とサブクラスからアクセス可能
<font color="Red">default </font>(アクセス修飾子を指定しない場合): 同じパッケージ内からアクセス可能
<font color="Red">private</font>: 同じクラス内からのみアクセス可能

```
public class AccessModifiers {
    public String publicField = "Public Field";      // パブリックフィールド
    protected String protectedField = "Protected Field"; // プロテクテッドフィールド
    String defaultField = "Default Field";           // デフォルトフィールド
    private String privateField = "Private Field";   // プライベートフィールド

    public static void main(String[] args) {
        AccessModifiers am = new AccessModifiers();
        System.out.println(am.publicField);      // アクセス可能
        System.out.println(am.protectedField);   // アクセス可能
        System.out.println(am.defaultField);     // アクセス可能
        System.out.println(am.privateField);     // アクセス可能
    }
}
```

## 3-3.コレクションフレームワーク
Javaのコレクションフレームワークは、データ構造とアルゴリズムを提供します。主要なインタフェースとクラスには以下があります。

- <font color="Red">List</font>: 順序を保持するコレクション (例: <font color="Red">ArrayList</font>, <font color="Red">LinkedList</font>)
- <font color="Red">Set</font>: 重複を許さないコレクション (例: <font color="Red">HashSet</font>, <font color="Red">TreeSet</font>)
- <font color="Red">Map</font>: キーと値のペアを保持するコレクション (例: <font color="Red">HashMap</font>, <font color="Red">TreeMap</font>)

```
import java.util.*;

public class CollectionsExample {
    public static void main(String[] args) {
        // Listインタフェースの実装クラスArrayListを使用
        List<String> list = new ArrayList<>();
        list.add("Apple");
        list.add("Banana");
        list.add("Cherry");
        System.out.println("List: " + list);

        // Setインタフェースの実装クラスHashSetを使用
        Set<String> set = new HashSet<>();
        set.add("Dog");
        set.add("Cat");
        set.add("Bird");
        System.out.println("Set: " + set);

        // Mapインタフェースの実装クラスHashMapを使用
        Map<String, Integer> map = new HashMap<>();
        map.put("One", 1);
        map.put("Two", 2);
        map.put("Three", 3);
        System.out.println("Map: " + map);
    }
}
```

## 3-4.ジェネリクス

ジェネリクスを使用すると、型安全なコレクションやクラスを作成できます。ジェネリクスは、コンパイル時に型のチェックを行うため、ランタイムエラーを減らすことができます。

```
import java.util.ArrayList;
import java.util.List;

public class GenericsExample {
    public static void main(String[] args) {
        // ジェネリクスを使用したリスト
        List<String> stringList = new ArrayList<>();
        stringList.add("Hello");
        stringList.add("World");

        for (String str : stringList) {
            System.out.println(str); // リストの要素を出力
        }

        // ジェネリッククラスの使用例
        Box<Integer> intBox = new Box<>();
        intBox.set(123);
        System.out.println("Box contains: " + intBox.get());
    }
}

// ジェネリッククラスの定義
class Box<T> {
    private T value;

    public void set(T value) {
        this.value = value; // 値をセット
    }

    public T get() {
        return value; // 値を返す
    }
}
```

## 3-5.スレッドと並行処理
Javaでは、<font color="Red">Thread</font> クラスや <font color="Red">Runnable</font> インタフェースを使用してスレッドを作成し、並行処理を行うことができます。また、<font color="Red">ExecutorService</font>を使用すると、スレッドプールを管理することができます。

```
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ThreadsExample {
    public static void main(String[] args) {
        // Threadクラスを拡張する方法
        MyThread thread1 = new MyThread();
        thread1.start(); // スレッドを開始

        // Runnableインタフェースを実装する方法
        Thread thread2 = new Thread(new MyRunnable());
        thread2.start(); // スレッドを開始

        // ExecutorServiceを使用する方法
        ExecutorService executorService = Executors.newFixedThreadPool(2);
        executorService.submit(new MyRunnable());
        executorService.submit(new MyRunnable());
        executorService.shutdown(); // スレッドプールを終了
    }
}

// Threadクラスを拡張したクラス
class MyThread extends Thread {
    public void run() {
        System.out.println("Thread is running.");
    }
}

// Runnableインタフェースを実装したクラス
class MyRunnable implements Runnable {
    public void run() {
        System.out.println("Runnable is running.");
    }
}
```

## 3-6.ファイル操作
Javaでは、<font color="Red">java.io</font> パッケージと <font color="Red">java.nio</font> パッケージを使用してファイル操作を行うことができます。以下は、ファイルの読み書きの例です。

```
import java.io.*;

public class FileExample {
    public static void main(String[] args) {
        String filePath = "example.txt";

        // ファイルへの書き込み
        try (BufferedWriter writer = new BufferedWriter(new FileWriter(filePath))) {
            writer.write("Hello, World!");
        } catch (IOException e) {
            System.out.println("Error writing to file: " + e.getMessage());
        }

        // ファイルの読み込み
        try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) {
            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println("Read from file: " + line);
            }
        } catch (IOException e) {
            System.out.println("Error reading from file: " + e.getMessage());
        }
    }
}
```

## 3-7.ラムダ式とストリームAPI
Java 8から導入されたラムダ式とストリームAPIは、関数型プログラミングをサポートし、コードを簡潔に記述するための強力なツールです。

```
import java.util.*;
import java.util.stream.*;

public class LambdaAndStreams {
    public static void main(String[] args) {
        // ラムダ式を使用した例
        List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
        names.forEach(name -> System.out.println("Hello, " + name));

        // ストリームAPIを使用した例
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        int sum = numbers.stream()
                         .filter(n -> n % 2 == 0) // 偶数フィルター
                         .mapToInt(Integer::intValue) // intに変換
                         .sum(); // 合計を計算
        System.out.println("Sum of even numbers: " + sum);
    }
}
```

# 4.練習問題

## 4-1.基本文法の復習
次の練習問題を通して、基本文法を復習しましょう。

### 問題1: コメント
以下のコードにコメントを追加してください。

```
public class CommentExample {
    public static void main(String[] args) {
        System.out.println("Hello, World!");
    }
}
```

#### 解説:
コメントを追加することで、コードの意図や動作を説明しやすくなります。シングルラインコメント (<font color="Red">//</font>) とマルチラインコメント (<font color="Red">/* ... */</font>) を適切に使いましょう。

#### 解答例:

```
// このクラスはコメントの例を示します
public class CommentExample {
    public static void main(String[] args) {
        // "Hello, World!"を出力します
        System.out.println("Hello, World!");
    }
}
```

### 問題2: 変数とデータ型
次のコードを完成させ、異なるデータ型の変数を宣言して値を出力してください。
```
public class DataTypeExample {
    public static void main(String[] args) {
        // ここにコードを追加
    }
}
```

#### 解説:
Javaには8種類の基本データ型があります。各データ型の変数を宣言し、適切な値を代入して出力してみましょう。

```
public class DataTypeExample {
    public static void main(String[] args) {
        byte b = 1;
        short s = 2;
        int i = 3;
        long l = 4L;
        float f = 5.0f;
        double d = 6.0;
        char c = 'A';
        boolean bool = true;

        System.out.println("byte: " + b);
        System.out.println("short: " + s);
        System.out.println("int: " + i);
        System.out.println("long: " + l);
        System.out.println("float: " + f);
        System.out.println("double: " + d);
        System.out.println("char: " + c);
        System.out.println("boolean: " + bool);
    }
}
```

### 問題3: 演算子
次のコードを完成させ、変数aとbの和を計算して出力してください。

```
public class OperatorExample {
    public static void main(String[] args) {
        int a = 5;
        int b = 10;
        // ここにコードを追加
        System.out.println("Sum: " + sum);
    }
}
```

#### 解説:
演算子を使って基本的な算術操作を行いましょう。ここでは、2つの整数を加算してその結果を出力します。

#### 解答例:
```
public class OperatorExample {
    public static void main(String[] args) {
        int a = 5;
        int b = 10;
        int sum = a + b; // 和を計算
        System.out.println("Sum: " + sum);
    }
}
```

### 問題4: 制御構文
次のコードを修正し、<font color="Red">number</font>が偶数の場合に「偶数です」、奇数の場合に「奇数です」と出力してください。

```
public class ControlStructureExample {
    public static void main(String[] args) {
        int number = 7;
        // ここにコードを追加
    }
}
```

#### 解説:
条件分岐 (<font color="Red">if-else</font>) を使用して、数値が偶数か奇数かを判定し、適切なメッセージを出力します。

#### 解答例:

```
public class ControlStructureExample {
    public static void main(String[] args) {
        int number = 7;
        if (number % 2 == 0) {
            System.out.println("偶数です");
        } else {
            System.out.println("奇数です");
        }
    }
}
```

### 問題5: 配列
次のコードを完成させ、配列の要素を逆順に出力してください。

```
public class ArrayExample {
    public static void main(String[] args) {
        int[] numbers = {1, 2, 3, 4, 5};
        // ここにコードを追加
    }
}
```

#### 解説:
配列の要素にアクセスし、逆順に出力します。配列の長さを取得してループを使いましょう。

#### 解答例:

```
public class ArrayExample {
    public static void main(String[] args) {
        int[] numbers = {1, 2, 3, 4, 5};
        for (int i = numbers.length - 1; i >= 0; i--) {
            System.out.println(numbers[i]);
        }
    }
}
```

### 問題6: メソッド
次のコードを完成させ、2つの整数の最大公約数 (GCD) を計算するメソッドを作成してください。

```
public class GCDExample {
    public static void main(String[] args) {
        int a = 56;
        int b = 98;
        // ここにコードを追加
        System.out.println("GCD: " + gcd(a, b));
    }

    // ここにメソッドを追加
}
```

#### 解説:
ユークリッドの互除法を使って、2つの整数の最大公約数を計算するメソッドを実装します。

#### 解答例:

```
public class GCDExample {
    public static void main(String[] args) {
        int a = 56;
        int b = 98;
        System.out.println("GCD: " + gcd(a, b));
    }

    public static int gcd(int a, int b) {
        while (b != 0) {
            int temp = b;
            b = a % b;
            a = temp;
        }
        return a;
    }
}
```

### 問題7: クラスとオブジェクト
次のコードを完成させ、<font color="Red">Book</font>クラスを作成し、<font color="Red">title</font>と<font color="Red">author</font>のフィールドを持たせてください。また、<font color="Red">display</font>メソッドを作成して、書籍情報を表示してください。

```
public class BookExample {
    public static void main(String[] args) {
        // ここにコードを追加
    }
}

// ここにクラスを追加
```

#### 解説:
クラスとオブジェクトの基本概念を理解するために、<font color="Red">Book</font>クラスを作成し、フィールドとメソッドを定義します。

#### 解答例:

```
public class BookExample {
    public static void main(String[] args) {
        Book book = new Book("Java Programming", "John Doe");
        book.display();
    }
}

// Bookクラスの定義
class Book {
    String title;  // タイトルフィールド
    String author; // 著者フィールド

    // コンストラクタ
    public Book(String title, String author) {
        this.title = title;
        this.author = author;
    }

    // 書籍情報を表示するメソッド
    public void display() {
        System.out.println("Title: " + title);
        System.out.println("Author: " + author);
    }
}
```

### 問題8: 継承
次のコードを完成させ、<font color="Red">Animal</font>クラスを継承する<font color="Red">Cat</font>クラスを作成し、<font color="Red">makeSound</font>メソッドをオーバーライドしてください。

```
public class InheritanceExample {
    public static void main(String[] args) {
        // ここにコードを追加
    }
}

class Animal {
    void makeSound() {
        System.out.println("Some generic animal sound");
    }
}

// ここにクラスを追加
```

#### 解説:
継承を使って、基本クラス (<font color="Red">Animal</font>) の機能を拡張する子クラス (<font color="Red">Cat</font>) を作成します。メソッドのオーバーライドも実装します。

#### 解答例:

```
public class InheritanceExample {
    public static void main(String[] args) {
        Cat cat = new Cat();
        cat.makeSound(); // Catクラスのメソッドが呼び出される
    }
}

class Animal {
    void makeSound() {
        System.out.println("Some generic animal sound");
    }
}

// Catクラスの定義
class Cat extends Animal {
    @Override
    void makeSound() {
        System.out.println("Meow");
    }
}
```

### 問題9: インタフェース
次のコードを完成させ、<font color="Red">Vehicle</font>インタフェースを実装する<font color="Red">Car</font>クラスを作成してください。

```
public class InterfaceExample {
    public static void main(String[] args) {
        // ここにコードを追加
    }
}

interface Vehicle {
    void start();
    void stop();
}

// ここにクラスを追加
```

#### 解説:
インタフェースを使って、クラスが実装すべきメソッドを定義します。インタフェースを実装するクラス (<font color="Red">Car</font>) を作成し、メソッドを具体化します。

#### 解答例:

```
public class InterfaceExample {
    public static void main(String[] args) {
        Car car = new Car();
        car.start(); // Carクラスのstartメソッドが呼び出される
        car.stop();  // Carクラスのstopメソッドが呼び出される
    }
}

interface Vehicle {
    void start();
    void stop();
}

// Carクラスの定義
class Car implements Vehicle {
    public void start() {
        System.out.println("Car started");
    }

    public void stop() {
        System.out.println("Car stopped");
    }
}
```

### 問題10: 例外処理
次のコードを完成させ、配列の要素にアクセスする際に発生する可能性のある<font color="Red">ArrayIndexOutOfBoundsException</font>をキャッチしてください。

```
public class ExceptionExample {
    public static void main(String[] args) {
        int[] numbers = {1, 2, 3, 4, 5};
        // ここにコードを追加
    }
}
```

#### 解説:
例外処理 (<font color="Red">try-catch</font>) を使って、配列の範囲外アクセスによる例外をキャッチし、適切なメッセージを表示します。

#### 解答例:

```
public class ExceptionExample {
    public static void main(String[] args) {
        int[] numbers = {1, 2, 3, 4, 5};
        try {
            System.out.println(numbers[10]); // 存在しないインデックスにアクセス
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("Error: Array index out of bounds");
        }
    }
}
```

### 問題11: 文字列操作

次のコードを完成させ、文字列の長さを取得し、「Java」を「Java Programming」に置換してください。

```
public class StringOperationExample {
    public static void main(String[] args) {
        String text = "Java is fun";
        // ここにコードを追加
        System.out.println("Length: " + length);
        System.out.println("Replaced text: " + replacedText);
    }
}
```

#### 解説:

length() メソッドを使用して文字列の長さを取得し、replace() メソッドを使用して文字列を置換します。

#### 解答例:

```
public class StringOperationExample {
    public static void main(String[] args) {
        String text = "Java is fun";
        int length = text.length(); // 文字列の長さを取得
        String replacedText = text.replace("Java", "Java Programming"); // 文字列を置換
        System.out.println("Length: " + length);
        System.out.println("Replaced text: " + replacedText);
    }
}
```

#### 問題12: 正規表現操作

次のコードを完成させ、文章中に「Java」が含まれているかどうかをチェックしてください。

```
import java.util.regex.*;

public class RegexOperationExample {
    public static void main(String[] args) {
        String text = "I love Java programming language.";
        String patternString = "Java";
        // ここにコードを追加
        if (matcher.find()) {
            System.out.println("Found: " + matcher.group());
        } else {
            System.out.println("Not found");
        }
    }
}
```
#### 解説:

Pattern.compile() メソッドを使用してパターンをコンパイルし、matcher() メソッドを使用して文字列にパターンを適用します。

#### 解答例:

```
import java.util.regex.*;

public class RegexOperationExample {
    public static void main(String[] args) {
        String text = "I love Java programming language.";
        String patternString = "Java";
        Pattern pattern = Pattern.compile(patternString);
        Matcher matcher = pattern.matcher(text);
        if (matcher.find()) {
            System.out.println("Found: " + matcher.group());
        } else {
            System.out.println("Not found");
        }
    }
}
```


## 4-2.高度なトピックの復習
次の練習問題を通して、高度なトピックを復習しましょう。

### 問題1: コレクションフレームワーク
次のコードを完成させ、リストに要素を追加し、すべての要素を出力してください。

```
import java.util.*;

public class CollectionExample {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        // ここにコードを追加
    }
}
```

#### 解説:
コレクションフレームワークを使用して、リストに要素を追加し、ループを使ってすべての要素を出力します。

#### 解答例:

```
import java.util.*;

public class CollectionExample {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("Apple");
        list.add("Banana");
        list.add("Cherry");

        for (String item : list) {
            System.out.println(item); // リストの要素を出力
        }
    }
}
```

### 問題2: ジェネリクス
次のコードを完成させ、ジェネリククラス<font color="Red">Box</font>を使用して<font color="Red">String</font>型の値を格納し、出力してください。

```
public class GenericsExample {
    public static void main(String[] args) {
        Box<String> stringBox = new Box<>();
        // ここにコードを追加
    }
}

class Box<T> {
    private T value;

    public void set(T value) {
        this.value = value;
    }

    public T get() {
        return value;
    }
}
```

#### 解説:
ジェネリクスを使って型安全なクラスを作成し、それを利用してString型の値を格納し、出力します。

#### 解答例:

```
public class GenericsExample {
    public static void main(String[] args) {
        Box<String> stringBox = new Box<>();
        stringBox.set("Hello, Generics!");
        System.out.println("Box contains: " + stringBox.get());
    }
}

class Box<T> {
    private T value;

    public void set(T value) {
        this.value = value;
    }

    public T get() {
        return value;
    }
}
```

#### 問題3: スレッドと並行処理
次のコードを完成させ、<font color="Red">Runnable</font>を使用してスレッドを作成し、メッセージを出力してください。

```
public class ThreadExample {
    public static void main(String[] args) {
        Runnable task = new Runnable() {
            public void run() {
                // ここにコードを追加
            }
        };

        Thread thread = new Thread(task);
        // ここにコードを追加
    }
}
```

#### 解説:
スレッドを作成し、<font color="Red">Runnable</font>インタフェースを実装して並行処理を行います。スレッドを開始 (<font color="Red">start()</font>) してメッセージを出力しましょう。

```
public class ThreadExample {
    public static void main(String[] args) {
        Runnable task = new Runnable() {
            public void run() {
                System.out.println("Thread is running.");
            }
        };

        Thread thread = new Thread(task);
        thread.start(); // スレッドを開始
    }
}
```

# 5.まとめ
本教材では、**Javaの基本文法**から**高度なトピック**まで詳細に説明しました。さらに、各章の内容を復習するための練習問題も提供しました。これらの問題を解くことで、Javaの理解を深めることができるでしょう。さらに高度な技術やフレームワークを学ぶ際の基盤となるでしょう。