Java8の新機能

# Who?

## @carimatics
- Webアプリケーションエンジニア
    - 業務ではPerlに弄ばれてる
    - Emacs Lispゴニョるの疲れてきて泣く泣くVim使ってる
- ガルパンおじさん
    - 今は12月公開の劇場版を見るためだけに生きてる

---

# さて、みなさん

---

# Java8以降使ってる人 :raised_hand:

---

# Java8の新機能を使ってる人 :raised_hand:

---

# Java8以降の新機能
## ラムダ式
- 無名関数を簡単に書くための構文
    - 可読性向上
- 内部的には関数型インタフェース
    - 実装すべきメソッドが唯一のインタフェース

## Stream API
- コレクションに対するラムダ式の適用
    - filter
    - map
    - reduce
- 並列処理

etc...

---

# 書いてみる

---

# ラムダ式

---

# 文字列の長さを返す
## 匿名クラス版
### 実装

```java
Function<String, Integer> countLen = new Function<>() {
    @Override
    public Integer apply(String s) {
        return s.length();
    }
};
int len = countLen.apply("Function class sample!!!");
System.out.println(len); // => 24
```

### 問題点
- ただひたすらに長い

---

# 冗長なものをガリガリ削る

---

```java
Function<String, Integer> countLen = new Function<>() {
    @Override
    public Integer apply(String s) {
        return s.length();
    }
};
```

---


```java
Function<String, Integer> countLen =
    @Override
    public Integer apply(String s) {
        return s.length();
    }
 ;
```

- 実装するインタフェース名は自明
    - 左辺にFuntionって書いてある

---

```java
Function<String, Integer> countLen =

                        (String s) {
        return s.length();
    }
 ;
```

- 返り値は自明
    - 左辺にIntegerって書いてある
- メソッド名は自明
    - 実装すべきメソッドは一つしかないので

---

```java
Function<String, Integer> countLen = (String s)    { return s.length(); };
```

整理

---

```java
Function<String, Integer> countLen = (String s) -> { return s.length(); };
```

- ラムダ式は引数と本体の間に `->` (arrow token)が必要

---

```java
Function<String, Integer> countLen = (String s) ->          s.length()   ;
```

- 本体が一文なら `return` と波括弧を省略できる

---

```java
Function<String, Integer> countLen =         s  ->          s.length()   ;
```

- 引数の型が判明しているなら省略できる
    - 左辺にStringって書いてある

---

```java
Function<String, Integer> countLen = s -> s.length();
```

整理
（メソッド参照の形式にも変更できるけど時間の都合で割愛）

---

# 文字列の長さを返す
## 匿名クラス版

```java
Function<String, Integer> countLen = new Function<>() {
    @Override
    public Integer apply(String s) {
        return s.length();
    }
};
```

## ラムダ式版

```java
Function<String, Integer> countLen = s -> s.length();
```

---

# Stream API

---

# [1..100]の数値の平均値

## for文

```java
double sum = 0.0;
for (int i = 1; i <= 100; i++) {
    sum += i;
}
double ave = sum / 100;
```

# Stream API

```java
double ave = IntStream.rangeClosed(1, 100)
        .average()
        .orElse(0.0);
```

---

## 従業員における30代男性の平均給与

## for文

```java
double sumSalary = 0.0;
for (Employee employee : employees) {
    if (30 <= employee.getAge() && employee.getAge() < 40
            && employee.getGender() == Gender.MALE) {
        sumSalary += employee.getSalary();
    }
}
double a = employees.isEmpty() ? 0.0 : sumSalary / employees.size();
```


## Stream API
```java
double averageSalary =
        employees.stream()
                .filter(e -> 30 <= e.getAge() && e.getAge() < 40) // 30代
                .filter(e -> e.getGender() == Gender.MALE)        // 男性
                .mapToInt(e -> e.getSalary())                     // 給与
                .average()                                        // 平均
                .orElse(0.0);                                     // 該当者がいなければ0.0
```

---

# ラムダ式やStream APIを使うと何が良いか

- 簡潔に書ける
- 可読性が上がる
- 保守しやすい

Java9でもStream APIの機能が追加されてて地味に便利です！

---

# みんなもKotlin書こう！！

---

# Kotlin最高！！