メモ

気になったことつらつら

kotlin

1. 基本構文

パッケージ宣言

package com.example.kotlinguide

メイン関数

fun main() {
    // プログラムのエントリーポイント
}

変数宣言

val applicationName = "Kotlin"  // 読み取り専用変数(immutable)
var counter = 0                 // 変更可能変数(mutable)

型指定

val firstNumber: Int = 1
val secondNumber: Int = 2
val welcomeMessage: String = "Hello"

2. 制御構文

if式

val maximumValue: Int = if (firstNumber > secondNumber) firstNumber else secondNumber
val comparisonMessage: String = if (firstNumber < secondNumber) {
    "secondNumberの方が大きい"
} else {
    "firstNumberの方が大きい"
}

when式

val inputValue: Int = 2
when (inputValue) {
    1 -> println("inputValue=1")
    2 -> println("inputValue=2")
    else -> {
        println("inputValue is not 1 or 2")
    }
}

// 条件式を使用したwhen
val scoreValue: Int = 10
when {
    scoreValue < 0 -> println("scoreValue is minus number")
    scoreValue in 1..10 -> println("scoreValue is in the range")
    else -> {
        println("scoreValue is over 11")
    }
}

3. ループ処理

for文

// リストの反復処理
val numberList: List<Int> = listOf(1, 2, 3, 4, 5)
for (currentNumber: Int in numberList) {
    println(currentNumber)
}

// 範囲を使った反復処理
for (index: Int in 1..5) {
    println(index)
}

// 逆順
for (index: Int in 5 downTo 1) {
    println(index)
}

// ステップ指定
for (index: Int in 1..10 step 2) {
    println(index)
}

while文

var loopCounter: Int = 0
while (loopCounter < 5) {
    println(loopCounter)
    loopCounter++
}

// do-while文
var doWhileCounter = 0
do {
    println(doWhileCounter)
    doWhileCounter++
} while (doWhileCounter < 5)

ラベル付きbreak/continue

outerLoop@ for (outerIndex: Int in 1..3) {
    innerLoop@ for (innerIndex: Int in 1..3) {
        if (outerIndex == 2 && innerIndex == 2) {
            break@outerLoop  // 外側のループを抜ける
        }
        println("break 例 -: outerIndex$outerIndex innerIndex$innerIndex")
    }
}

outerLoop@ for (outerIndex: Int in 1..3) {
    innerLoop@ for (innerIndex: Int in 1..3) {
        if (outerIndex == 2 && innerIndex == 2) {
            continue@outerLoop  // 外側のループの次の反復へ
        }
        println("continue 例 -: outerIndex$outerIndex innerIndex$innerIndex")
    }
}

4. 関数

基本的な関数定義

fun calculateSum(firstValue: Int, secondValue: Int): Int {
    return firstValue + secondValue
}

// Unit型(戻り値なし)
fun displayWelcomeMessage(): Unit {
    println("Hello World")
}

// デフォルト引数
fun greetUser(userName: String = "Guest"): Unit {
    println("Hello $userName")
}

// 名前付き引数
fun introduceUser(userName: String, userAge: Int): Unit {
    println("My name is $userName, and I am $userAge years old")
}

// 呼び出し例
introduceUser(userName = "Alice", userAge = 5)
introduceUser(userAge = 25, userName = "Bob")

拡張関数

fun String.reverseString(): String {
    return this.reversed()
}

// 使用例
val sampleText: String = "Hello World"
println(sampleText.reverseString())

5. クラス

基本的なクラス

class User {
    var userName: String = ""
    var userAge: Int = 0

    fun introduceUser() {
        println("My name is $userName , and I am $userAge years old")
    }
}

プライマリコンストラク

class UserWithPrimaryConstructor(var userName: String, var userAge: Int) {
    init {
        println("create a new user with primary constructor name: $userName, age: $userAge")
    }
    
    fun introduceUser() {
        println("My name is $userName, and I am $userAge years old")
    }
}

セカンダリコンストラク

class UserWithSecondaryConstructor(var userName: String, var userAge: Int) {
    constructor(userName: String): this(userName, 0)
    constructor(): this("DefaultUser")

    fun introduceUser() {
        println("My name is $userName, and I am $userAge years old")
    }
}

ゲッター・セッター

class UserWithCustomAccessors {
    var userName: String = ""
        get() = field.uppercase()
        set(value) {
            field = value.trim()
        }
    
    var userAge: Int = 0
        set(value) {
            field = value + 1
        }
}

データクラス

data class UserProfile(val userName: String, val userAge: Int)

// 使用例
val firstUser = UserProfile("alice", 10)
val secondUser = UserProfile("alice", 10)
val thirdUser = UserProfile("bob", 20)

println(firstUser == secondUser)  // true(構造的等価性)
println(firstUser == thirdUser)   // false

6. コレクション

配列

val numberArray: Array<Int> = arrayOf(1, 2, 3, 4, 5)
println(numberArray[0])
println(numberArray.size)

リスト

// 読み取り専用リスト
val fruitList: List<String> = listOf("Apple", "Banana", "Orange")
println(fruitList[[1](https://developer.android.com/codelabs/basic-android-kotlin-compose-classes-and-objects?hl=ja)])

// 変更可能リスト
val mutableFruitList: MutableList<String> = mutableListOf("apple", "banana", "orange")
mutableFruitList.add("grape")
mutableFruitList[0] = "pineapple"

セット

val fruitSet: Set<String> = setOf("apple", "banana", "orange", "banana")
println(fruitSet)  // 重複は除去される

val mutableNumberSet: MutableSet<Int> = mutableSetOf(1, 2, 3, 4, 5)
mutableNumberSet.add(6)
mutableNumberSet.remove(1)

マップ

val userAgeMap = mapOf("alice" to 25, "bob" to 20, "carol" to 30)
println(userAgeMap)

val subjectScoreMap = mutableMapOf("math" to 90, "english" to 80)
subjectScoreMap["music"] = 77
subjectScoreMap.remove("math")

7. 高階関数ラムダ式

ラムダ式の基本

val calculateSum = { firstValue: Int, secondValue: Int -> firstValue + secondValue }
println(calculateSum(1, 2))

val calculateSquare: (Int) -> Int = { it * it }
println(calculateSquare(4))

高階関数

fun executeOperation(firstValue: Int, secondValue: Int, operation: (Int, Int) -> Int): Int {
    return operation(firstValue, secondValue)
}

val additionResult = executeOperation(3, 5) { a, b -> a + b }
val multiplicationResult = executeOperation(3, 5) { a, b -> a * b }

コレクション操作

val numberList = listOf(1, 2, 3, 4, 5)

// filter: 条件に合う要素を抽出
val evenNumberList = numberList.filter { it % 2 == 0 }

// map: 各要素を変換
val squaredNumberList = numberList.map { it * it }

// reduce: 要素を累積処理
val totalSum = numberList.reduce { accumulator, currentValue -> accumulator + currentValue }

// find: 条件に合う最初の要素を取得
val firstEvenNumber = numberList.find { it % 2 == 0 }

// sorted: ソート
val sortedNumberList = numberList.sorted()

// メソッドチェーン
val chainedResult = numberList
    .filter { it % 2 == 0 }
    .map { it * it }
    .reduce { a, b -> a + b }

8. スコープ関数

apply

val userProfile = UserProfile("", 0, "").apply {
    userName = "Alice"
    userAge = 25
    userAddress = "123 Main St"
}

let

val inputText: String? = "hello"
inputText?.let {
    println("length: ${it.length}")
    println("Uppercase: ${it.uppercase()}")
}

run

val textValue = "hello"
val textLength = textValue.run {
    println("length: ${this.length}")
    this.length
}

also

val userInstance = User("Alice", 25).also {
    println("Created user: ${it.userName}")
}

9. Null安全性

Nullable型

var nonNullableText: String = "hello"      // Non-null型
var nullableText: String? = null           // Nullable型

安全呼び出し演算子

val inputText: String? = "hello"
println(inputText?.length)  // inputTextがnullでなければlengthを取得

val nullText: String? = null
println(nullText?.length)   // nullが返される

エルビス演算子

val inputText: String? = null
val textLength = inputText?.length ?: -1  // nullの場合は-1を返す

10. 例外処理

try-catch-finally

fun performDivision(dividend: Int, divisor: Int): Int {
    if (divisor == 0) {
        throw IllegalArgumentException("Division by zero")
    }
    return dividend / divisor
}

try {
    val divisionResult = performDivision(10, 0)
    println(divisionResult)
} catch (exception: IllegalArgumentException) {
    println("Error: ${exception.message}")
} finally {
    println("exception finally")
}

11. ジェネリクス

ジェネリッククラス

class Container<T>(private var storedValue: T) {
    fun getValue(): T = storedValue
    fun setValue(newValue: T) {
        storedValue = newValue
    }
}

val integerContainer = Container<Int>(10)
val stringContainer = Container<String>("hello")

ジェネリック関数

fun <T> displayValue(value: T) {
    println(value)
}

displayValue<Int>(19)
displayValue<String>("hello")
displayValue<Boolean>(true)

ワイルドカード

fun displayListValues(itemList: List<*>) {
    for (item in itemList) {
        println(item)
    }
}

12. オブジェクト宣言

object宣言(シングルトン)

object ApplicationDataManager {
    private val dataStorage = mutableListOf<String>()
    
    fun addData(item: String) {
        dataStorage.add(item)
    }
    
    fun getAllData(): List<String> = dataStorage
}

// 使用例
ApplicationDataManager.addData("item 1")
println(ApplicationDataManager.getAllData())

13. 文字列テンプレート

基本的な文字列補間

val applicationName = "Kotlin"
println("Hello, $applicationName!")

val currentIndex = 5
println("currentIndex = $currentIndex")

式の埋め込み

val firstValue = 1
val secondValue = 2
println("Max of $firstValue and $secondValue is ${if (firstValue > secondValue) firstValue else secondValue}")