Kotlin is a new language which at least most of Android developers heard about it or are using it instead of Java.
Out of my curiosity start learning it to know what’s attractive inside that makes some developer crazy about it! so during my learning process, I have made some notes which might look too minified but contains keywords for beginners and your later searches.
This is the notes which I prefer to have at the beginning of my learning process:
val immutableName: String = "Mohsen"
var mutableName: String = "Mohsen"var mutableName = "Mohsen"
var nullableName: String? = null
val numbers = arrayListOf(1, 2, 3, 4, 5)print("Even Numbers are ${numbers.filter { i -> i % 2 == 0 }}")
val countries = listOf(Pair("Iran", "Tehran"), Pair("France", "Paris"), Pair("Germany", "Berlin"))
for ((country, city) in countries) {print("Country: $country - City: $city")}
// fun stands for function!
fun addNumbers(first: Int, second: Int): Int {return first + second}addNumbers(10, 20)addNumbers(first = 10, second = 20)addNumbers(second = 1, first = 2) // !!!
// you can have multiple paramsfun addNumbers(vararg numbers: Int): Int {return numbers.sum()}addNumbers(1, 2, 3, 4, 5, 6)
// default valuefun addTwoNumbers(first: Int, secound: Int = 0): Int {return first + secound}addTwoNumbers(2)
// no fields in classes! only properties and functionsclass Customer(val id: Int = 0, var name: String) {
// secondary constructor
constructor(id: Int) : this(id, "")
// initialize method
init() {
}
// public by default property
val test = 0
// visible inside Customer.kt
private fun foo() {}
// property is visible everywhere
// setter is visible only in Customer.kt
public var bar: Int = 5
private set
// visible inside the same module
internal val baz = 6
}
// mutable data classes similar to AutoValue library which provide equals, toString, copy, etc.data class Customer(val id: Int = 0, var name: String)
fun String.convertSpacesToUnderscores(): String {return this.replace(" ", "_")}
print("This is my sample String.".convertSpacesToUnderscores())
val x: String = null //error!val x: String? = null
// if x is not null range to 10x?.rangeTo(10)
var customer: Customer? = nullcustomer?.let {// it = user and not null and only read once!println(it.name)}
someMethod().let { result ->//method only run once!}
fun getStringLen(obj: Any): Int? = if (obj is String) obj.length else null
// the same as Static methods and you have to access the// method like this: Customer.Companion.what()
class Customer {companion object {fun what(customer: Customer): String {return customer.id.toString() + customer.name}}}
// If you want the function looks like java static methods// like this: Customer.what() have to add JvmStatic// It is useful for calling static methods from NDK librariesclass Customer {companion object {@JvmStaticfun what(customer: Customer): String {return customer.id.toString() + customer.name}}}
// functions with no classes, just the same as java import staticpackage com.google.test
fun packageFunction() {println("I am a package function!!")}
val list = listOf("a", "b")val mutableList = mutableListOf("a", "b")
for (s in list) {// ...}
val map = mapOf("key" to "value")val mutableMap = mutableMapOf("key" to "value")
for ((key, value) in map) {// ...}
interface TestInterface {fun run(t:Int): String
fun test(){
// default body!
}
}
class Box<T>(t: T) {// ...}Val box: Box(1) // box: Box<Int>
enum class Direction(val degree: Int) {NORTH(0), EAST(90), SOUTH(180), WEST(270)}
val y = x as Intval y = x as? Int // nullable
// smart castIf (x is String)x.toUpperCase()
operator fun plus(other: Point): Point = Point(x + other.x, y + other.y)
// all classes are final by default and for inheritance should be openopen class Shape {}
class Circle: Shape() {}
infix fun String.hello(name:String): String{return "Hello, $name. $this"}
"Test" hello "test" // == "Test".hello("test")
interface Repository<T : Record> {fun getById(id: Int): Tfun getAll(): List<T>}
class Controller(repository: Repository<Customer>) : Repository<Customer> by repository {fun customerList(): List<Customer> {return getAll()}
fun customerById(id: Int): Customer {
return getById(id)
}
}
var test: String by Delegates.observable("") {prop, old, new ->println("$old -> $new")}
// sealed means there is no PageResult child more than ones that are here in this filesealed class PageResult
class Success(val url: String) : PageResult()class Error(val code: Int, val message: String) : PageResult()
fun getPage(url: String): PageResult {val someOperationIsSuccessfull = false
if (someOperationIsSuccessfull)
return Success(url)
else
return Error(404, "Not found")
}
fun callingPage() {val result = getPage("http://google.com")when (result) {is Success -> println(result.url)is Error -> println(result.message)}}
class User(firstName: String, lastName: String) {val fullName: String by lazy { "$firstName $lastName" }
fun printFullName() {
println("User full name is: $fullName")
}
}
fun myFunction() {val numbers = 1..100numbers.forEach {if(it%5==0)return@forEach} println("Hello!!") //Hello will be printed!}
//tailrec convert a recursive function call to a goto looptailrec fun factorial(number: Int, accumulator: Int = 1): Int {when (number) {0 -> return accumulatorelse -> return factorial(number - 1, accumulator * number)}}
// multiline string literalsprint("""1. test2. unit test3. what a test""")
print("""1. test2. unit test3. what a test""".trimIndent())
print("""|1. test|2. unit test|3. what a test""".trimMargin())
fun max(a: Int, b: Int) = if (a > b) a else b
// no for (int i=0;i<10;I++) loop!!!val myArray = arrayOf("A","B","C","D")for (index in 0 until myArray.size){println(myArray.get(index))}
for ( i in 1..10 )println(myArray.get(index))}
for ( i in 100 downTo 1 step 5)println(myArray.get(index))}
var i = 0while (i < 10)println (i++)
// no switch case defaultwhen (i) {0 -> println("zero")1..5 -> println("number")is String -> println("$i is string")!is String -> println("is not string")else -> println("unknown!!!")}
val isString = when ("Hello") {is String -> trueelse -> false}
val isInRange = i in 5..9val isMember = "hello" in array
// set alias while importing!Import com.google.Test as MyTest
// loop operatorswhile (true){if(false) breakif(false) continueif(false) return}
// labelsouter@ for (l in list) {for (m in map) {if (l == m.key) break@outer}}
// Pair and Triple data typesval myPair = Pair(1, "Mohse")val myTriple = Triple(1, "A", "Mohsen")val (id, name) = myPair
// measure runtime in ms!!val took = measureTimeMillis {// ...}
// deprecate a method@Deprecated ("Use another method!", level = WARNING/ERROR/HIDDEN, replaceWith = ReplaceWith("newPrintFullName()", imports = "com.google.test"))fun printFullName() {// …}
// rename method for Java@JvmName("methodNameInJava")fun printFullName() {// …}
// inject using qualifier annotation@field:[Inject ApplicationContext]lateinit var context: Context
// exclude field from serialization and gson@Transientvar id: String? = null
// add plugin to build.gradleapply plugin: 'kotlin-android-extensions'
import kotlinx.android.synthetic.main.<layout>.*
// access views without findViewById!!myText.text = "Hello world!"
I look forward for your comments, experiences with Kotlin, and any unusual syntaxes which I might miss as a beginner. Share this article if you think it is useful by tapping 💚 button, and follow me for more articles Mohsen Mirhoseini.