【Java】ラムダ式とStream APIメモ

## はじめに
Javaの案件の面談でよくラムダ式、Stream APIについて知見があるか質問されるのでまとめました。

## ラムダ式、StreamAPIのメリット
ラムダ式のメリット:
1. 可読性の向上
2. 簡潔な構文
3. 無名の関数を作成


Stream APIのメリット:
1. 可読性の向上
2. 並列処理によるパフォーマンスの改善

## ラムダ式
Java 8以降で導入された機能です。
主に関数型インターフェースの実装を簡潔に書くために使用されます。
関数型インターフェースとは、抽象メソッドが1つだけ定義されているインターフェースのことを指します。
抽象メソッドとは、詳細未定（中身が無い）のメソッドのことを指します。

構文
```
 (引数) -> {処理内容};
```
* 引数の型を記述する必要はありません
* 引数は複数可能です
* 引数が1つの場合は()を省略できます

<details open><summary>サンプルコード</summary>

```java
// 関数型インターフェース
public interface SampleInterface {
    // 抽象メソッド
    public String method(String name, int age);
}

public class Main {
 
    public static void main(String[] args) {
 
        // ラムダ式の場合
        SampleInterface lambda = (name, age) -> {
            return "ラムダ式：" + "名前は" + name + " " + "年齢は" + age + "歳";
        };
        System.out.println(lambda.method("太郎", 20));
        
        // ラムダ式を使用しない場合（匿名クラス）
        SampleInterface anonymousClasses = new SampleInterface() {
            // オーバーライド
            public String method(String name, int n) {
                return "匿名クラス：" + "名前は" + name + " " + "年齢は" + age + "歳";
            }
        };
        System.out.println(anonymousClasses.method("太郎", 20));
    }
  
}
```
</details>

## Stream API
Java 8以降で導入された機能です。
コレクション（例: List, Map, Set）のデータ処理を効率的かつ簡潔に書くために使用されます。
for文、if文を使わず絞り込み、並び替えを行うことができます。

構文
```
 オブジェクト名.stream().中間操作(引数) -> 処理内容).終端操作(処理内容);
```
* メソッドの引数にはラムダ式の記述様式を使用します
### 基本的な構文と代表的な機能
1.Streamの生成:
    コレクションからStreamオブジェクトを作成できます。例えば、List<Integer> の要素から stream() メソッドを呼び出すことで、整数のストリームを取得できます。
    
2.中間操作 (Intermediate Operations)
中間操作は、Streamを変換する操作です。主な中間操作には以下があります：
* filter: 条件に一致する要素を抽出
* map: 要素を別の型に変換
* flatMap: 要素を別のStreamに変換し、それらのStreamを結合
* 
3.終端操作 (Terminal Operations):
終端操作は、Streamから結果を生成する操作です。主な終端操作には以下があります：
* forEach: 各要素に対してアクションを実行
* collect: 要素をコレクションに収集
* reduce: 要素を結合して単一の結果を生成
* sum(): 数値要素の合計を求める
* count(): 要素の数をカウント

4.遅延評価 (Lazy Evaluation):
Streamは遅延評価され、中間操作は終端操作が実行されるまで適用されません。これにより、効率的なデータ処理が可能です。

5.並列処理のサポート:
Stream APIは内部的に並列処理をサポートしており、マルチコアプロセッサーの恩恵を受けることができます。

<details open><summary>サンプルコード</summary>

```java
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class StreamExample {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);

        // 中間操作と終端操作を組み合わせて処理
        List<Integer> evenNumbers = numbers.stream()
            .filter(n -> n % 2 == 0)
            .collect(Collectors.toList());

        System.out.println(evenNumbers); // 出力: [2, 4]

        // 数値要素の合計を求める
        int sum = numbers.stream()
            .filter(n -> n % 2 == 0)
            .mapToInt(n -> n * 2)
            .sum();

        System.out.println("合計: " + sum); // 出力: 12
    }
}
```
</details>

## まとめ
ラムダ式は関数型インターフェースの実装を簡潔に書く記述方法です。
Stream APIはコレクション（例: List, Map, Set）のデータをfor文、if文を使わず絞り込んだり、並び替えることができるAPIです。

## 参考記事

https://www.sejuku.net/blog/22337

https://qiita.com/nabekou29/items/360506a8c4ced0bfdba0

https://bing.com/search?q=StreamAPI%e3%81%ae%e3%83%a1%e3%83%aa%e3%83%83%e3%83%88

https://qiita.com/haraitai00/items/034d11bb1298603f0450

https://www.sejuku.net/blog/22337

https://and-engineer.com/articles/ZD0TfhEAACgAWgnN

https://bing.com/search?q=%e3%83%a9%e3%83%a0%e3%83%80%e5%bc%8f%e3%81%ae%e3%83%a1%e3%83%aa%e3%83%83%e3%83%88

https://the-simple.jp/using-lambda-expressions-and-improving-program-efficiency-a-guide-for-programmers