ぱんくずリスト

気になる話をちらほらと。

Kotlinの小技集

気がついたら、追記していきます。

static field , method(っぽいもの)の定義

class Hoge {
  companion object {
    @JvmField
    val hoge: String = "HOGE"

    @JvmStatic
    fun HogeHoge() { ... }
  }
}

companion object の中で変数や関数を定義すれば、Kotlin上でstaticなメンバとして扱える。
Javaでもstaticなメンバとして扱えるが、Companionオブジェクトを介したアクセスになるらしい。
@JvmField@JvmStaticと言ったアノテーションをつけることで、Companionオブジェクトを介さなくなるみたい。

Kotlinのコレクション

kotlinのコレクション(List, Set, Map)には、読み取り専用のものと、書き込み可能なものがある。
List, Set, Mapは読み取り専用、要素の追加等をする場合には、各インターフェースの頭に'Mutable'とついたクラスを使用する。
また、各インターフェースのインスタンスを作る際には、~Of()と言うファクトリ関数を使用する。

  // 読み取り専用
  val list: List<Int> = listOf(1, 2, 3)
  // 書き込みも可能
  val mutableList: MutableList<Int> = mutableListOf(1, 2 ,3)

  // OK
  mutableList.add(4)
  // NG
  // list.add(4)

読み取り専用 ≠ immutable

Kotlinのmutableではないコレクションは、読み取り専用ではあるが、完全なImmutable(作成後に、状態を変更できないオブジェクト)と言う訳ではないらしい。

val mutableList = mutableListOf(1, 2, 3)
val list: List<Int> = mutableList // mutableを読み込み専用に代入
mutableList.add(4)

println(list) // 出力 >> [1, 2, 3, 4]

Mutable ~系インターフェースは読み込み専用インターフェースも継承しているので、そのインスタンスList等に代入できてしまう。
結果、後からMutableインターフェース経由で、書き換えられる可能性があるためImmutableではないとのこと。

Mutable(List, Map, Set) <=> (List, Map, Set)

to ~ ()メソッドを使用する

// MutableList => List
val mutableList: MutableList<Int> = mutableListOf(1, 2, 3)
val list: List<Int> = mutableList.toList()

// List => MutableList
val list: List<Int> = listOf(1, 2, 3)
val mutableList: MutableList<Int> = list.toMutableList()

複数メソッドをもつインターフェースの実装の仕方

OnClickListenerのように、メソッドを1つしか持たないインターフェースであれば、SAM変換を使うことで簡潔に書くことができるが、 AdapterViewのOnItemSelectedListenerのような、メソッドを2つ以上持つインターフェースではSAM変換は使えない。 複数メソッドを持つインターフェースは、object式を用いて実装を行う。

// setOnClickListener
button.setOnClickListener {
    // 何らかの処理
}

// OnItemSelectedListener
val listener = object: AdapterView.OnItemSelectedListener {
    override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
        // 何らかの処理
    }

    override fun onNothingSelected(parent: AdapterView<*>?) {
        // 何らかの処理
    }
}

// リスナーの登録
spinner.onItemSelectedListener = listener

これで実装はできるが、Javaっぽくて冗長なコードになるのが欠点。 何かいい設計はないものか…