== operator
String sr2 = new String(str1); if(str1 == str2){ // str2 and str2 are two separate Strings references, will never print print("True, str1 and str2 point to the same reference") } else { print("False, str1 and str2 point to separate references") // Output }
val str2 = String(str1.toCharArray) if(str1 == str2) { // this will be the output, because == is equivalent to str1.equals(str2) print("str1 and str2 both have the value "Hello") } else { print("str1 and str2 have different values") } === operator - In Kotlin, the '===' operator is equivalent to Java's '==' operator and tests to see if the reference is equal Class constructor example:
// Class with no body class Car // Class with parameters class Car(var make: String, var model: String, var year: Int, var color: String) { fun drive() { } } Object instantiation: var car = Car("Tesla", "Model S", 2018, "silver") Accessing class properties(local variables) and functions: // property 'make' println(car.make) // prints "Tesla" // function drive() car.drive()
Creating an array of objects: var manyCars = arrayOf(Car("Toyota", "Camry", 2017, "red"), Car("Nissan", "Rogue", 2013, "gray"), Car("Ford", "F-150", 2012, "black")) Accessing an object array's element: manyCars[0].model // "Camry" manyCars[2].drive() // Ford F-150 calls drive() Class initializer blocks: class Car(var make: String, var model: String, var year: Int, var color: String) { fun drive() { } init { print("New car, $make $model pulling up") } init { // this runs after the above 'init'. 'init' blocks run in the order of appearance in code } } Custom getter and setter functions: class Car(var make: String, var model: String, var year: Int, var color: String) { var mpg: Int get() = // do something to calculate/derive the above 'mpg' // a future access of 'Car.mpg' would auto-call this get() var verifiedYear = year set(value) { if(value != 0) { // field identifier used Kotlin to avoid circular dependency issues field = value } } set() // often used to validate values/data // set() auto-called each time a value is assigned e.g. 'Car.verifiedYear = 1999' fun drive() { } } - If there is no explicit getter or setter declarations, the compiler creates them automatically. 'val' properties have just the getter method (due to value being immutable) created, while 'var' properties get both. Superclasses and Subclasses
// Superclass open class Car(var make: String, var model: String, var year: Int, var color: String) { var mpg open val country open fun drive() { } } // Subclass class SportsCar : Car() { // use override keyword to override superclass properties or functions override val country override fun drive() // for superclass properties defined with 'var', it doesn't need to be overridden init { mpg = 25 } } Abstract classes & interfaces Abstract classes and interfaces are still declared the same way in Kotlin using the 'abstract' and 'interface' keywords. // abstract class abstract class Animal { abstract val species: String fun classify() { ... } } // interface interface Hunt { fun chase() { println("Chase prey") } } Kotlin does not have the keywords 'inherits' or 'implements'. // The class MyAnimal implements the 'Hunt' interface and inherits from the 'Animal' class class MyAnimal: Hunt, Animal() { override val species: String get() = "Lion" } Abstract class constructor abstract class Animal(private val species: String) { fun classify() { println("The animal is part of the $species species") } } Kotlin function signature:
fun functionName(varName: varType): returnType { return varName } Example: fun isLegal(age: Int): Boolean { return if(age >= 18) } // or fun isLegal(age: Int): Boolean = age >= 18 // multiple parameters fun applicant(age: Int, name: String) { ... } // function with no return /** fun displayTotal(num1: Int, num2: Int): Unit {} -- using (: Unit) can also delineate the function does not return **/ fun displayTotal(num1: Int, num2: Int) { val total = num1 + num2 println(total) } // function with return fun larger(firstNum: Int, secondNum: Int): Int { val largerNum = if(firstNum > secondNum) firstNum else secondNum return largerNum } // above larger() function can be further simplified: fun larger(firstNum: Int, secondNum: Int): Int = if(firstNum>secondNum) firstNum else secondNum // you can remove return type of function and allow compiler to infer it from your 'if' statement fun larger(firstNum: Int, secondNum: Int) = if(firstNum>secondNum) firstNum else secondNum Calling the function: val legal = isLegal(21) // True val legal isLegal(10) // False Default function parameter values: fun displayMsg(message: String, name: String = "visitor") { println("Howdy $name, $message") } // function calls displayMsg("nice to meet you!", "Sarah") // Output: Howdy Sarah, nice to meet you displayMsg("pleasure to be of acquaintance") // Output: Howdy visitor, pleasure to be of acquaintance Variable number of function arguments // Allows non-fixed number of arguments of declared type (argType) fun funName(vararg argName: argType): returnType { } main() function
public class MainClass { public static void main(String[] args) { System.out.println("Hello world"); } } Kotlin: fun main(args: Array<String>) { println("Hello World") } Static functions class NumberPicker { // 1 companion object allowed per class companion object { // declare function inside a 'companion' object block to delineate 'static' fun spinWheel () { } } } /** call spinWheel(). Unlike Java, no need to call function using a class instance (e.g. NumberPicker c = new NumberPicker(); c.spinWheel(); **/ NumberPicker.spinWheel() Static factory function private class SecretClass private constructor() { companion object() : SecretClass { fun create() : SecretClass { return SecretClass() } } } // instantiate a new SecretClass instance val sc = SecretClass.create() kotlin.collections package - site for reference.
- Allows declarations of immutable or mutable collections List<Double> // immutable List of Double objects MutableList<Double> // mutable List of Double objects Arrays // array type inferred val numArray = arrayOf(1, 2, 3, 4, 5, 6, 7) // array type specified val intArray = intArrayOf(1, 3, 5, 7, 9) joinToString() println(numArray.joinToString() ) // show contents of 'numArray' (1, 2, 3 .. etc) /** Adding symbols/chars before and after the array contents In below example, parenthesis enclosing array contents (1, 2, 3, 4..) **/ println(numArray.joinToString(prefix = "(", postfix = ")")) // specifying separator between array contents other than default commas ',' println(numArray.joinToString(prefix = "(", postfix = ")", separator = "*")) // Output: (1*2*3*4... etc) Lists, Sets, Maps // immutable list val nameList = ListOf("Jen:", "Joe", "Jim") // mutable list val mutableNameList = mutableListOf("Jack", "James", "Joey") // Set: unique contents only, so the set would contain 2 and 4 only val numSet = setOf(2, 2, 4, 4) // mutable set val mutableNumSet = mutableSetOf(2, 2, 4, 4) // immutable map val alphabet = mapOf(1 to "a", 2 to "b", 3 to "c") println(map) // Output: {1=a, 2=b, 3=c} // mutable map val alphabet = mutableMapOf(1 to "a", 2 to "b", 3 to "c", 4 to "d") println(map) // Output: {1=a, 2=b, 3=c, 4=d} if statements:
val num = 21 if (num < 21) { println("Underage drinker") } else { println("Adult") } // Output: Adult Assigning variable with outcome of 'if' statement: // 'age' will be assigned the string after the println() val age = if(num < 21) { printlln("Underage drinker") "Do not allow drinking" // if 'num' is under 21, 'age' assigned "Do not allow drinking" } else { println("Legal drinker") // 'num' is over 21, 'age' assigned "Allow drinking" "Allow drinking" } Using 'if' statement as an expression // corresponding else clause is mandatory when using 'if' as an expression println(if (a > b) "a is greater than b" else "a is less than b") when statements:
val cost = 100 when(cost) { 0 -> println("Free admission") 50 -> println("Half-price admission") 51..99 -> println("Over 50% off admission") else -> println("Full-price admission") // default } // Output: Full-price admission Assigning variable with outcome of 'when' statement: // 'admission' will be assigned the appropriate string based on corresponding 'when' condition val admission = when(cost) { 0 --> "Free admission" 50 --> "Half-price admission" 51..99 --> "Over 50% off admission" else ---> "Full-price admission" } while & do-while loops: // while loops in Kotlin have similar syntax to Java val num = 0 while(i <10) { println("$num ") num++ } do { println(num) num++ } while(num < 20) for loops: for(i in 1..20) { print("$i ") } // or, the above simplified: // Output: Integer range of 1-20 (e.g. 1 2 3 4 5...etc, includes 100) for(i in 1..100) print("$i ") // Output: same as above, but excludes end number 100) for(i in 1 until 100) print("$i ") for(chars in "Kotlin language") { print("$chars ") } // Output: Each character of string w/ space between each character (e.g. K o t l i n l a n g .. etc) Using downTo operator in 'for' condition, reverses range of output for(i in 100 downTo 1) { print("$i ") } // Output: 100, counting down by 1 (e.g. 100 99 98 97 .. etc) Using downTo operator + step for(i in 100 downTo 1 step 5) { print("$i ") } // Output: 100, counting down by 5-step increments (e.g. 100 95 90 85 .. etc) Looping through an array for(item in numArray) { println("$item is an item in numArray") } Looping through an array using its index for((index, item) in numArray.withIndex()) { println("numArray[ $index ] has the element $item) } Looping through a string to print each of its characters val language = "Kotlin" for(c in language) { print(c) } Data types
Integer types
Some points regarding variables and data types in Kotlin:
Kotlin variable declaration
greeting = "Hi again" // not allowed, 'greeting' immutable due to 'val' declaration
greeting = "Hello World, v2" // allowed, 'var' declaration allows mutability var age = 21 // mutable variable (value and reference to object can change) var age: Int = 21 // no semi-colon required at end of declaration statement val name = "John" // 'val' for immutable variables (reference to object unchangable ) val name: String = "John" // equivalent to declaration above val isHuman: Boolean = true Kotlin and immutability or null safety val str: String = null // not allowed val str: String? = null // use '?' after the data type when wanting to assign 'null' val i: Int? = null - Kotlin will warn at compile time when a variable is null Unsafe and safe operators for null in Kotlin // 'str' is null str!!.length // using unsafe operator '!!', throws null pointer exception str?.length /** safe operator that returns null if 'str' is null, the value of 'str.length' if 'str' is not null **/ val length = str?.length ?: -1 /** ?: - Elvis operator. If 'str' is null, assign -1 to 'length', otherwise, length of 'str' assigned value of its 'length' **/ |
AuthorExploring Android and mobile web design, security, and development. Archives
March 2021
Categories |