Created
March 4, 2021 08:22
-
-
Save ky28059/09feab45f70c6a83677458de7e27f2c5 to your computer and use it in GitHub Desktop.
The epic presentation from UC, compiled into a file
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import kotlin.collections.HashMap | |
fun main() { | |
// Like with Java's public static void main(String[] args), | |
// kotlin programs are accessed through the main function | |
// Types | |
// Kotlin is a strongly typed language, but type declarations are optional when they can be inferred. | |
// Kotlin also has implicit type casting. | |
val x: String = "hello" // valid | |
val y = "hello" // also valid; the compiler can infer that y is a String without the explicit statement | |
val n: Int = 5 | |
val m = n / 2.5 // though n is an int, it is implicitly cast to a double for this operation | |
// Ranges | |
// Like Python, Kotlin replaces the C-style for loop with ranges | |
// Kotlin's ranges have several operators that make them very handy to use | |
for (i in 0..16) println(i) // prints 0 through 16, inclusive | |
for (i in 0 until 16) println(i) // prints 0 through 15 | |
for (i in 0..16 step 2) println(i) // prints 0, 2, 4, 6, etc | |
for (i in 16 downTo 0) println(i) // prints 16, 15, 14, 13, etc | |
for (i in 'a'..'z') println(i) // prints a, b, c, d, etc | |
// The in statement can also be used to check whether a value is within a range | |
println(5 in 0..6) // true | |
println(0.05 in 1.1..3.6) // false | |
// Destructuring | |
// It can often be handy to have named variables instead of writing list[0] and list[1] everywhere | |
// Like js, Kotlin's destructuring is very handy for this purpose | |
val (left, right) = "112 or 231".split(" or ") | |
println(left) // 112 | |
println(right) // 231 | |
val searchQuery: List<List<String>> = "a=b&c=d&e=f" | |
.split("&") | |
.map { it.split("=") } | |
for ((name, value) in searchQuery) { | |
println("$name $value") // "a b", "c d", "e f" | |
} | |
// The when statement | |
// when () is a switch statement but epic, with less nesting, break;, and more capability | |
fun coolWhenStatement(x: Any): Int { | |
return when (x) { | |
5 -> 1 // the when statement can match specific values like a switch, but can also... | |
is Boolean -> 2 // check types | |
in 6..26 -> 3 // check within ranges | |
"hello", "hey", "hi" -> 4 // match multiple values | |
is Int, is Double, is Long -> 5 | |
in 'a'..'c', in 'e'..'g' -> 6 | |
else -> 7 // have an else case | |
} | |
} | |
println(coolWhenStatement(5)) // 1 | |
println(coolWhenStatement(false)) // 2 | |
println(coolWhenStatement(8000000000000000)) // 5 | |
println(coolWhenStatement('b')) // 6 | |
println(coolWhenStatement('e')) // 6 | |
// Null safety | |
// Unlike java where all non-primitive types are nullable, Kotlin types cannot be nullable unless they are marked with a ? | |
// To prevent null pointer exceptions, all properties or methods of a nullable type must be accessed safely | |
// The safe ?. operator does the operation only if value to the left of it is not null | |
// The ?: operator uses the left value if it is not null, or the right if the left is null | |
// The only way an NPE can be thrown in Kotlin is if you use the null assertion operator !! which throws an NPE if the left element is null | |
val map: HashMap<Int, String> = hashMapOf(1 to "hi", 2 to "hey") | |
val value1: String? = map[1] // because value1 could be null if the key does not exist in the map, the element's type is a String? | |
val value2: String? = map[3] | |
println(value1?.length ?: "This element is null!") // 2 | |
println(value2?.length ?: "This element is null!") // "This element is null!" | |
// Evaluating expressions | |
// In Kotlin, expressions can be evaluated anywhere | |
// This is very powerful. | |
fun weirdExample(x: Any): String { | |
return listOf("wow", "woah", "uau", "wowzers")[when (x) { | |
is String -> 0 | |
is Int -> 1 | |
is MutableList<*> -> 2 | |
else -> 3 | |
}] | |
} | |
println(weirdExample("hi")) // prints "wow" | |
println(weirdExample(mutableListOf<Int>())) // prints "uau" | |
val weirdVariable = if (weirdExample(5) == "woah") "Intriguing" else "Inspiring" | |
println(weirdVariable) // "Intriguing" | |
for (i in 1..100) println( // the famous fizzbuzz problem, prints fizzbuzz if i is divisible by 15, fizz if by 3, buzz if by 5, i otherwise | |
if (i % 15 == 0) "Fizzbuzz" | |
else if (i % 3 == 0) "Fizz" | |
else if (i % 5 == 0) "Buzz" | |
else i | |
) | |
// Primary constructors | |
// In Java, there is a lot of repeated logic in classes where you have fields assigned by constructors | |
// In Kotlin, this is simplified by the primary constructor | |
data class BankAccount(val balance: Int, val owner: String) | |
// equivalent to | |
class WordierBankAccount { | |
val balance: Int | |
val owner: String | |
constructor(balance: Int, owner: String) { | |
this.balance = balance | |
this.owner = owner | |
} | |
} | |
// Equality | |
// In Java, == compares memory location, which becomes especially annoying as Strings and other objects require the use of .equals | |
// In Kotlin, == uses .equals and does not compare memory | |
val j = BankAccount(1500, "Serena") | |
val k = BankAccount(1500, "Serena") | |
println(j == k) // true | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment