プログラミングノート for Kotlin

# 目的
Kotlin言語の基本文法をおさえるためのまとめノートを作成する
# 前提
Javaと比較する想定のため、Java言語を理解している前提

## 変数の宣言
| 言語 | 意味 | 実装 |
|:-:|:-:|:-:|
|Kotlin | 変数  |  var |
|     |  定数 | val  |
|Java | 変数  | 何もつけない |
|     |  定数 | final |
  
## 条件分岐
※if文はjavaと同様に書けたので省略。
### if式
・関数で if式のパターンを実装
```kotlin
class If {
    fun ifExpression(s: String): Unit {
        var msg = if (s == "kotlin") {
            "kotlin"
        } else if (s == "java") {
            "java"
        } else {
            "other"
        }
        println(msg)
    }
}
```
・エントリーポイントで関数を実行
```kotlin
fun main(args: Array<String>) {
    val ifKotlin = If()
    ifKotlin.ifExpression("kotlin")
    ifKotlin.ifExpression("java")
    ifKotlin.ifExpression("aaa")
}
```
・実行結果
```java
kotlin
java
other
```
### when式
・関数で when式のパターンを実装
```kotlin
class When {
    fun whenExpression(a: String): Unit {
        when (a) {
            "kotlin" -> println("kotlinが渡されました")
            "java" -> println("javaが渡されました")
            else -> {
                //ブロックにすると、複数行処理がかける
                println("kotlinでもjavaでもありません")
            }
        }

    }
}
```
・エントリーポイントで関数を実行
```kotlin
fun main(args: Array<String>) {
    val whenKotlin = When()
    whenKotlin.whenExpression("kotlin")
    whenKotlin.whenExpression("java")
    whenKotlin.whenExpression("php")
}
```
・実行結果
```java
kotlinが渡されました
javaが渡されました
kotlinでもjavaでもありません
```
## ループ
### forループ

・関数でループパターンを実装
```kotlin
class ForLoop {
    fun indexLoop(): Unit {
        //通常for文
        for (i in 1..3) {
            println("通常for文:${i}")
        }
    }

    fun exLoop(): Unit {
        //拡張for文
        val list = listOf(1, 2, 3)
        for (i in list) {
            println("拡張for文:${i}")
        }
    }

    fun eachLoop(): Unit {
        //forEach関数
        val list = listOf(1, 2, 3)
        list.forEach { index -> println("forEach:${index}") }
    }

    fun eachIndexLoop(): Unit {
        //index+要素で取得できる方法
        val list = listOf("shelly", "bourbon", "jin")
        list.forEachIndexed { index, data -> println("forEach:${index}:${data}") }
    }
}
```

・エントリーポイントで関数を実行
```kotlin
fun main(args: Array<String>) {
    val forLoop = ForLoop()
    forLoop.indexLoop()
    forLoop.exLoop()
    forLoop.eachLoop()
    forLoop.eachIndexLoop()
}
```

・実行結果
```java
通常for文:1
通常for文:2
通常for文:3
拡張for文:1
拡張for文:2
拡張for文:3
forEach:1
forEach:2
forEach:3
forEach:0:shelly
forEach:1:bourbon
forEach:2:jin
```


### ループ範囲指定方法

・関数でループ範囲指定パターンを実装
```kotlin
class ForLoopRange {
    fun untilLoop() {
        //until
        for (i in 1 until 3) {
            println("untilは最後を含めない:${i}")
        }
    }

    fun downToLoop() {
        //downTo
        for (i in 3 downTo 1) {
            println("1ずつ減らす:${i}")
        }
    }

    fun stepLoop() {
        //skip
        for (i in 1..20 step 3) {
            println("3飛びで進む:${i}")
        }
    }

    fun outerBreak() {
        //ラベル構文
        outer@
        for (i in 1..10) {
            for (j in 1..10) {
                if (j > 5) break@outer
                println("i:${i} j:${j}")
            }
        }
    }

    fun notOuterBreak() {
        //ラベル構文なしのbreak
        for (i in 1..5) {
            for (j in 1..5) {
                if (j > 2) break
                println("i:${i} j:${j}")
            }
        }
    }
}
```
・エントリーポイントで関数を実行
```kotlin
fun main(args: Array<String>) {
    val range = ForLoopRange()
    println("==untilLoop==")
    range.untilLoop()
    println("")
    println("==downToLoop==")
    range.downToLoop()
    println("")
    println("==stepLoop==")
    range.stepLoop()
    println("")
    println("==outerBreak==")
    range.outerBreak()
    println("")
    println("==notOuterBreak==")
    range.notOuterBreak()
}
```
・実行結果 ※ログ見にくいので関数毎にタイトル付ける
```java
==untilLoop==
untilは最後を含めない:1
untilは最後を含めない:2

==downToLoop==
1ずつ減らす:3
1ずつ減らす:2
1ずつ減らす:1

==stepLoop==
3飛びで進む:1
3飛びで進む:4
3飛びで進む:7
3飛びで進む:10
3飛びで進む:13
3飛びで進む:16
3飛びで進む:19

==outerBreak==
i:1 j:1
i:1 j:2
i:1 j:3
i:1 j:4
i:1 j:5

==notOuterBreak==
i:1 j:1
i:1 j:2
i:2 j:1
i:2 j:2
i:3 j:1
i:3 j:2
i:4 j:1
i:4 j:2
i:5 j:1
i:5 j:2
```

## 可変長引数・分解宣言
関数定義
```kotlin
class Vararg {
    fun sumReturn(vararg values: Int): Int {
        var result = 0
        for (value in values) {
            result += value
        }
        return result
    }

    fun sumPairReturn(vararg values: Int): Pair<Int, Double> {
        //Pairで2つ戻り値を戻す
        var result = 0
        for (value in values) {
            result += value
        }
        return Pair(result, result / 10.0)
    }

    fun sumTripleReturn(vararg values: Int): Triple<Int, Double, Int> {
        //Tripleで3つ戻り値を戻す
        var result = 0
        for (value in values) {
            result += value
        }
        return Triple(result, result / 10.0, result + 1)
    }

}
```

テストクラス
```kotlin
import org.junit.jupiter.api.Test

class VarargTest {

    @Test
    fun sumReturn() {
        val vararg = Vararg()
        val result = vararg.sumReturn(2,3)
        assert(result == 5)
    }

    @Test
    fun sumReturnSplet() {
        //スプレット演算子を用いた場合
        val vararg = Vararg()
        val list = intArrayOf(4,5)
        val result = vararg.sumReturn(2,*list,3)
        assert(result == 14)
    }

    @Test
    fun sumPairReturn() {
        val vararg = Vararg()
        val list = intArrayOf(4,5)
        val result = vararg.sumPairReturn(2,*list,3)
        assert(result == Pair(14,1.4))
    }

    @Test
    fun sumTripleReturn() {
        val vararg = Vararg()
        val list = intArrayOf(4,5)
        val result = vararg.sumTripleReturn(2,*list,3)
        assert(result == Triple(14,1.4,15))
    }

}
```

## コレクション
### Map
ストラテジーパターンを使って、mapから実装したクラスを取り出す処理
クラス分割が多いので気になる方はgitにあります。
```JavaFactory.kt
class JavaFactory {
    private val javaTypes: Map<JavaType, Java> = object : HashMap<JavaType, Java>() {
        init {
            put(JavaType.JAVA_BRONZE, JavaBronze())
            put(JavaType.JAVA_SILVER, JavaSilver())
            put(JavaType.JAVA_GOLD, JavaGold())
        }
    }

    @NotNull
    fun of(javaType: JavaType): Java {
        return javaTypes[javaType]!!
    }
}
```

```Map.kt
class Map {
    fun getJava(javaType: JavaType): Java {
        val factory = JavaFactory()
        return factory.of(javaType)
    }
}
```
・テストクラス
```kotlin
class MapTest {

    @Test
    fun getJava() {
        val map = Map()
        val result = map.getJava(JavaType.JAVA_BRONZE)
        assertEquals(result.show(),"JavaBronze")
    }
}
```

GitHub

https://github.com/Shinya-Takiyoshi/kotlin-sandbox