Kotlin

Bridge to Kotlin Part 1

Kotlin Language ဆိုတာ High Level Programming Language ထဲမှာ နောက်ဆုံးပေါ်  Programming Language ဆိုရင် မမှားပါဘူး။ နောက်မှပေါက်တဲ့ ရွှေကြာပင်ဆိုတဲ့ အတိုင်း တစ်ခြား Language တွေက အကောင်းဆုံးတွေပဲ ပေါင်းထည့်ထားပါတယ်။ ကျွန်တော်ကတော့ ဒီနေရာမှာ Android Developer တွေအနေနဲ့ သိသင့်တဲ့ Kotlin Language ဆိုင်ရာ Feature တွေကိုပဲ ရွေးထုတ်ပြီး ပြောသွားမှာ ဖြစ်ပါတယ်။ Programming Language တွေ လေ့လာတော့မယ်ဆိုတိုင်း ပထမဦးဆုံး ကြည့်ရမှာ Variable တွေ ဖြစ်ပါတယ်။

Variables in Kotlin

Programming Language တွေက Support ပေးတဲ့ Variable တွေကို လေ့လာမယ်ဆိုရင်

  1. Stastically Typed (or) Dynamically Typed
  2. Primative Data Type (or) Object Data Type
  3. Mutable (or) Immutable

Kotlin ဟာ Stastically Typed Language ဖြစ်ပါတယ်။ Variable Type တွေကို ကြေငြာပေးဖို့ လိုအပ်ပါတယ်။ ဒါပေမယ့် နောက်က Assign လုပ်မယ့် Value က Type သေချာတယ်ဆိုရင် Variable Type ကို ကြော်ငြာပေးစရာ မလိုပါဘူး။

(ဒီနေရာမှာ Dynamically Typed Language ဆိုတာ ကျွန်တော်တို့ Coder တွေအနေန့ Variable Type ကို ကြော်ငြာပေးစရာမလိုပါဘူး။ နောက်က Assign လုပ်လာမယ့် value အပေါ် မူတည်ပြီး အလိုအလျှောက် Type ကို သတ်မှတ်ပေးသွားတာပါ။ Scripting Language တွေမှာ အတွေ့ရများပါတယ်)

နမူနာအနေနဲ့ လေ့လာကြည့်ရအောင်

val oneMillion = 1_000_000
val creditCardNumber = 1234_5678_9012_3456L
val socialSecurityNumber = 999_99_9999L
val hexBytes = 0xFF_EC_DE_5E
val bytes = 0b11010010_01101001_10010100_10010010

Kotlin မှာ ထူးခြားတာ တစ်ခုက Variable တွေ အနေနဲ့ Java လို Primative Data Type ပုံစံ အလုပ်မလုပ်ပဲ Object Data Type ပုံစံ အလုပ်လုပ်ပါ။ အဲဒီအတွက် Integet ကနေ String ပြောင်းချင်ရင် အရင်က Java မှာ ရေးသလို String.valueOf(<int value>) ဆိုတာမျိုး ရေးစရာမလိုတော့ပဲ အောက်မှာ ပြထားတဲ့အတိုင်း ရေးလို့ရပါတယ်။

oneMillion.toString()
oneMillion.toByte()
oneMillion.toBigDecimal()
oneMillion.toBigInteger()

ဒါပေမယ့် Android မှာတော့ ရေးရင် Object ပုံစံနဲ့ ရေးရပြီး တကယ်တန်း သုံးရင်တော့ Primative Data Type ပုံစံ သုံးပါတယ်။ Primative Data ပုံစံဆိုတာ Memory ပေါ်မှာ နေရာ အသေမှတ်တဲ့ပုံစံပါ။ ဒါကလဲ Java နဲ့ Interoperability အတွက်ပါ။ ဆိုလိုတာက Kotlin နဲ့ ရေးရး Java နဲ့ ရေးရး Android ကို အဆင်ပြေစေဖို့ပါ။

Kotlin မှာ တစ်ကြိမ် Assign လုပ်တာနဲ့ ပြင်စရာမလိုတော့တဲ့ ပြင်လို့မရတော့တဲ့ Variable ဆိုရင် Inmutable (ပြင်လို့ မရအောင်) သတ်မှတ်လို့ရပါတယ်။ နောက်ထပ် value ကို ပြင်ချင်တယ်ဆိုရင်တော့ Mutable (ပြင်လို့ရအောင်) သတ်မှတ်ပေးလို့ရပါတယ်။ ဥပမာ –

val name = "Aung Aung"

var age = 34

name = "Change It"

age = 45

val ဆိုတာက Immutable ပါ။ အဲဒီအတွက် name = “Change It’ လို့ ထပ် Assign လုပ်ရင် Error တက်ပါလိမ့်မယ်။ IDE မှာ တင် Error တက်လာမှာပါ။ var လို့ ပေးထားတာတော့ Mutable ပါ။ အဲဒီအတွက် age = 45 ဆိုပြီး ထပ် assign လုပ်လို့ရပါတယ်။

Java မှာလို Variable တွေကို အရင်ကြော်ငြာပြီး နောက်မှ တန်ဖိုး assign လုပ်ချင်တယ်ဆိုရင်တော့ ဒီလို ပုံစံနဲ့ လုပ်လို့ရပါတယ်။

lateinit var test: String

အဲဒီလို သတ်မှတ်လိုက်ရင်တော့ test ရဲ့ value ကို နောက်မှ သတ်မှတ်လို့ရသွားပါလိမ့်မယ်။

ကျန်တာတွေကတော့ တစ်ခြား Language တွေနဲ့ အတူတူပါပဲ။ Android အတွက် Bridge အနေနဲ့ သိစရာကတော့ Variable နဲ့ ပတ်သက်ရင် ဒီလောက်ပါပဲ။

Array in Kotlin

Kotlin မှာ Array နဲ့ ပတ်သက်ရင် ထူးခြားတာတွေ ရှိပါတယ်။ ထူးခြားတယ်ဆိုတာ ကျွန်တော်တို့ တစ်ခြား Programming Language တွေမှာ အသုံးပြုတဲ့ ပုံစံတွေနဲ့ မတူတာပါ။ Kotlin Array ကို List တွေနဲ့ တွဲပြီး နားလည်ဖို့ လိုပါတယ်။ ကျွန်တော်တို့ Android မှာ မဖြစ်မနေ သုံးဖို့ လိုအပ်တာ Kotlin က Array နဲ့ List တွေပါ။

Array တစ်ခု ကြော်ငြာလိုက်တာနဲ့ Getter နဲ့ Setter တွေပါတဲ့ Array Class တစ်ခု ကြော်ငြာလိုက်ပါတယ်။ Array Class တစ်ခုမှာ

  1. size – property  တစ်ခု
  2. get, set, iterator ဆိုတဲ့ function သုံးခု (3)
  3. Inherited Functions တွေ ဖြစ်တဲ့ equals, hashCode, toString ဆိုတဲ့ function သုံးခု
  4. Extension Properties တွေ ဖြစ်တဲ့ indices, lastindex
  5. Extension Functions တွေ အများကြီး ပါဝင်ပါတယ်။

အဲဒီ အပိုင်း (၄) ပိုင်းမှာ အပေါ် သုံးချက်က ဘာမှ မထူးခြားပါဘူး။ အောက်က နမူနာလေးအတိုင်း ရေးကြည့်မယ်ဆိုရင် နားလည်သွားပါလိမ့်မယ်။

val days = arrayOf("Sun","Mon", "Tue", "Wed", "Thu", "Fri", "Sat")
val anotherDays = arrayOf("Sun","Mon", "Tue", "Wed", "Thu", "Fri", "Sat")
println(days.size)
println(days[2])
for (day in days) {
    println(day)
}
if (days.equals(days)) {
    println("They are equal")
} else {
    println("They are not equal")
}

if(days.equals(anotherDays)) {
    println("They are equal")
} else {
    println("They are not equal")
}
println(days.indices)
println(days.lastIndex)

အဲဒီ Program ထဲမှာပါတဲ့ ပထမ if မှာတော့ They are equal လို့ ထွက်ပြီး နောက် if မှာတော့ They are not equal လို့ ထွက်ပါလိမ့်မယ်။ .equals ဆိုတာက object လိုက် တိုက်စစ်တာဖြစ်ပြီး တန်ဖိုးကို စစ်တာ မဟုတ်တဲ့အတွက် ဖြစ်ပါတယ်။

Kotlin Array မှာ ပါတဲ့ Extension Function တွေက အရမ်း အသုံးဝင်ပါတယ်။ အဲဒီအထဲက တစ်ချို့ကို လေ့လာကြည့်ရအောင်

.all

Kotlin Array ရဲ့  Extension Function တစ်ခုဖြစ်တဲ့ all ဟာ Array ထဲမှာ ရှိတဲ့ Element တွေ အားလုံးကို တစ်ပြိုင်တည်း စစ်ချင်တဲ့အခါ အများကြီး အသုံးဝင်ပါတယ်။ ဥပမာ –

val numbers = arrayOf(2,4,6,8,10)
val isEven: (Int) ->Boolean = { it % 2 == 0}
val iterator = numbers.iterator()

while (iterator.hasNext()) {
    if (isEven(iterator.next())) {
        println(true)
    }
}

println(numbers.all(isEven)) // isEvent(it)

အပေါ်မှာ ပြထားတဲ့ Program ကို လေ့လာကြည့်မယ်ဆိုရင် numbers array ထဲမှာ ပါတဲ့ values တွေ အားလုံး စုံဂဏ္ဍန်း (Even Number) တွေလားဆိုပြီး စစ်ချင်တယ် ဆိုပါစို့။ ပုံမှန်အတိုင်းဆိုရင် loop ပတ်ပြီး စစ်နေရပါလိမ့်မယ်။ အဲဒီအစား numbers.all(isEven) ဆိုရင် တစ်ခါတည်း ကိစ္စ ပြတ်ပါတယ်။

ဒီနေရာမှာ တစ်ခုမှတ်ထားဖို့ လိုတာက အထဲမှာ ရှိတဲ့ Value တစ်ခုခြင်းစီကို ကိုယ်စားပြုတဲ့အခါ Kotlin မှာ it နဲ့ ကိုယ်စားပြုပါတယ်။ numbers.all(isEven(it)) ဆိုပြီးလဲ စစ်လို့ရပါတယ်။

.any

.any ကတော့ .all နဲ့ ဆင်ပါတယ်။ .all က အားလုံး ဖြစ်မှ true ဖြစ်မှာ ဖြစ်ပြီး .any ကတော့ တစ်ခုခု ကိုက်တာနဲ့ true ဖြစ်ပါမယ်။ ဥ့ပမာ –

val numbers = arrayOf(1, 4, 5, 7, 10)
val isEven: (Int) -> Boolean = { it % 2 == 0}
println(numbers.any { isEven(it) })

အပေါ်မှာ ပြထားတဲ့ Program ကို run ကြည့်မယ်ဆိုရင် Array Value တွေထဲမှာ 4 ဆိုတဲ့ even value တစ်ခုပါနေတဲ့အတွက် တစ်ခုခု ကိုက်တဲ့အတွက် true ဆိုပြီး ပြပါလိမ့်မယ်။

ဒီနေရာမှာတော့ it ရဲ့ အသုံးပြုတဲ့ ပုံစံကို ရှင်းပြထားပါတယ်။

.contains

.contains ကလဲ အရမ်းအသုံးဝင်တဲ့ function တစ်ခု ဖြစ်ပါတယ်။ ဥပမာ –

val numbers = arrayOf(2, 4, 6, 8, 10)
println(numbers.contains(6))

Array Value တွေထဲမှာ 6 ပါလားဆိုပြီး ရှာလို့ရပါတယ်။ ရှိတယ်ဆိုရင် true ဆိုပြီး ပြပါလိမ့်မယ်။

.copyOf

copyOf ကတော့ Array တစ်ခုကနေ နောက်တစ်ခုကို တစ်ပုံစံတည်း ကူးယူချင်တဲ့အခါ သုံးပါတယ်။

val days = arrayOf("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat")
val anotherDays = days.copyOf()
for (anotherDay in anotherDays) {
    println(anotherDay)
}
if (days.equals(anotherDays)) {
    println("They are exactly the same")
} else {
    println("They are not exactly the same")
}

anotherDays က days ရဲ့ တစ်ပုံစံတည်း Copy အဖြစ် ကူးလိုက်ပါတယ်။ ဒါပေမယ့် သူတို့နှစ်ခုကို equals နဲ့ စစ်ကြည့်မယ်ဆိုရင်တော့ တူမှာ မဟုတ်ပါဘူး။ Object နှစ်ခု ဖြစ်သွားပြီး တစ်ခုနဲ့ တစ်ခု Memory ပေါ်မှာ မှတ်တဲ့အခါ မတူတဲ့အတွက် ဖြစ်ပါတယ်။

.filter

Kotlin Array မှာ filter ကလဲ အတော် အသုံးဝင်တဲ့ function တစ်ခု ဖြစ်ပါတယ်။ ဥပမာ –

val numbers = arrayOf(1, 3, 4, 5, 6, 7, 8, 9, 10)
val isEven: (Int) -> Boolean = { it % 2 == 0 }
val filteredNumbers = numbers.filter(isEven)
println(filteredNumbers)
if(filteredNumbers is List) {
    println("It is a List!")
}
if (numbers is Array<*>) {
    println("It is an Array!")
}

အပေါ်က Program ကို လေ့လာကြည့်မယ်ဆိုရင် filteredNumbers တွေ အကုန်လုံးဟာ numbers.filter(isEven) နဲ့ စစ်လိုက်တဲ့အတွက် List တစ်ခုအနေနဲ့ ထွက်လာပါလိမ့်မယ်။

ဒီနေရာမှာ Array အနေနဲ့ ထုတ်ပေးတာ မဟုတ်ပဲ List အနေနဲ့ ထုတ်ပေးတယ်ဆိုတာ သတိထားဖို့ လိုပါတယ်။ List အကြောင်းကို နောက်ပိုင်းမှာ ဆက်ပြောပါမယ်။

.forEach

forEach ကလဲ ကျွန်တော်တို့အတွက် အင်မတန် အသုံးဝင်တဲ့ function တစ်ခု ဖြစ်ပါတယ်။ ဥပမာ –

val numbers = arrayOf(1, 3, 4, 5, 6, 7, 8, 9, 10)
numbers.forEach {
   
println(it)
}

forEach သုံးမယ်ဆိုရင် ကျွန်တော် တို့ အပေါ်မှာ ရေးသလို ရေးနေစရာ မလိုတော့ပါဘူး။ ရေးရတာ အရမ်းသက်သာသွားပါတယ်။

ဒီနေရာမှာ သတိထားဖို့လိုတာက it ဆိုတာပါ။ it ဆိုတာ item တစ်ခုခြင်းစီကို ကိုယ်စားပြုပါတယ်။

Kotlin Array ရဲ့ Extension Function တွေ အများကြီးပါ။ အောက်မှာ ပေးထားတဲ့ Link က တစ်ဆင့် သွားကြည့်လို့ရပါတယ်။

Kotlin Array

Array Extension Function တွေကို ဘယ်လို လေ့လာမလဲဆိုရင် ကိုယ်တကယ် အသုံးလိုတဲ့ Tradition Way အတိုင်း Loop ပတ်ဖို့ စဉ်းစားနေပြီဆိုရင် Kotlin ဟာ နောက်ဆုံးပေါ် Programming Language တစ်ခု ဖြစ်တယ်။ အဲဒီအတွက် ကိုယ် သမာရိုးကျသုံးနေတာတွေအတွက် သူ့မှာ အထောက်အပံ့တွေ ရှိနိုင်တယ်လို့ မြင်ပြီး API Reference မှာ ရှာကြည့်ဖို့ လိုပါတယ်။

Collections in Kotlin (List, Set, Map)

Kotlin မှာ collections များအနေနဲ့ List, Set, Map ဆိုပြီး သုံးမျိုး ထောက်ပံ့ပါတယ်။ Java နဲ့ အတူတူပါပဲ။ ဒါပေမယ့် မတူတာလေးတွေ ရှိပါတယ်။ အဲဒါတော့ Mutable Collections နဲ့ Immutable Collections ပါ။

ဒီနေရာမှာ ​Array နဲ့ Collection ဘာကွာလဲဆိုတာ သိထားဖို့ လိုပါတယ်။

Array တွေက Fixed Size ဖြစ်ပြီး Collections မှာ ပါဝင်တဲ့ MutableList<T> ကတော့ Dynamic Size ဖြစ်ပါတယ်။

Array တွေက Mutable ဖြစ်ပြီး Collections မှာတော့ Mutable ဖြစ်ချင်တယ်ဆိုရင် MutableList ကို သုံးမှ ရပါမယ်။

Collections တွေဟာ အထဲမှာ ပါဝင်တဲ့ Element တွေကို ကိုင်တွယ်တဲ့နေရာမှာ Array ထက် ပိုပြီး လွယ်ကူပါတယ်။

List

Kotlin List မှာ MutableList နဲ့ ImmutableList ဆိုပြီးရှိပါတယ်။ ဥ့ပမာ –

val days = listOf( "Sun", "Mon", "Tue", "Wed", "Thu", "Fri" )
days.forEach { println(it) }
val anotherDays = mutableListOf( "Sun", "Mon")
val endDays = listOf("Wed", "Thu", "Fri")
anotherDays.add(2, "Tue")
println(anotherDays)
anotherDays.addAll(endDays)
println(anotherDays)

listOf မှာတော့ Array နဲ့ သိပ်မထူးပေမယ့် mutableListOf မှာတော့ add တို့ addAll စတာတွေ သုံးလို့ရပါတယ်။ ကျွန်တော်တို့ Java မှာ သုံးနေကြ ပုံစံတွေ ဖြစ်ပါတယ်။

Set

Set မှာလဲ ထုံးစံအတိုင်း Immutable နဲ့ Mutable ဆိုပြီး နှစ်ခု ကွဲပါတယ်။ List နဲ့ Set ဘာကွာလဲဆိုရင် Set မှာက ထပ်နေတဲ့ Element တွေ ပါလို့ မရပါဘူး။ List မှာတော့ ပါလို့ရပါတယ်။ ဥပမာ –

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

val firstSet = setOf(1,1,3,4,3,1)

println(firstList)

println(firstSet)

ပထမ listOf ကို သုံးတော့ ထပ်နေတာတွေကို ထပ်တဲ့အတိုင်း ထားပါတယ်။ ဒုတိယ setOf မှာတော့ အဲဒီလိုမဟုတ်တော့ပဲ ထပ်နေတာတွေကို ဘုံချပြီး ပေါင်းလိုက်ပါတယ်။ Run ကြည့်မယ်ဆိုရင် Result မှာ

[1, 1, 3, 5, 4, 3, 2]

[1, 3, 4]

ဆိုပြီး ပြပါလိမ့်မယ်။

Map

Map ကတော့ Key->Value Pair ပုံစံနဲ့ သွားပါတယ်။ Key တွေ အနေနဲ့ ဘယ်တော့မှ မထပ်ပဲ Value အနေနဲ့တော့ တူလို့ရပါတယ်။ ဥပမာ –

val mapValues = hashMapOf("Sun" to 1, "Mon" to 2, "Mon" to 3)
mapValues.forEach {
   
println(it.key)
    println(it.value)
}

အပေါ်က နမူနာကို ကြည့်မယ်ဆိုရင် Map ကို နားလည်မယ် ထင်ပါတယ်။

ဆက်ပါဦးမယ် …