Last active
January 21, 2023 13:58
-
-
Save dschinkel/ecdc8c368202a04ab9bac12b27a05b72 to your computer and use it in GitHub Desktop.
Kotlin Recipes / Example Snippets
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
/* | |
MUTABLE MAPS | |
------------ | |
Note: Its type is inferred by underlying values within | |
*/ | |
val toRoman = mutableMapOf( | |
"IIIII" to "V", | |
"VV" to "X" | |
) | |
// get a value: "VV" returns "X" | |
toRoman["VV"] | |
/* | |
MUTABLE LISTS | |
------------- | |
*/ | |
private val defaultSkunkWorks : MutableList<SkunkWork> = listOf( | |
"Coffee Machine", | |
"XBox", | |
"Ping Pong Table", | |
) | |
/* | |
MAPS | |
Map over each item in the list and create a new SkunkWork model with title populated, | |
then convert it back to a mutable list so we can modify it later | |
*/ | |
val skunkwork = defaultSkunkWorks.map{ SkunkWork(it) }.toMutableList() | |
// define a function that returns one | |
fun findAllSkunkWork(): MutableList<SkunkWork> { | |
return skunkworkRepository.findAllSkunkWorks() | |
} | |
// set a variable to a mutable list returned by a function | |
val skunkWorks: MutableList<SkunkWork> = findAllSkunkWorks() | |
// Filtering | |
val originalMap = mapOf("key1" to 1, "key2" to 2, "something_else" to 3) | |
val filteredMap = originalMap.filterKeys { it.contains("key") } | |
// Iterating | |
items.forEach { | |
k, v -> | |
println("$k = $v") | |
} | |
for ((k, v) in items) { | |
println("$k = $v") | |
} |
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 kotlinx.coroutines.CompletableDeferred | |
class BluetoothDiscotech(private val bluetoothInterface: BluetoothInterface) { | |
suspend fun discoverize() = beginDiscovery() | |
.run { collectDevices() } | |
private fun beginDiscovery() = if (bluetoothInterface.isEnabled) { | |
bluetoothInterface.startDiscovery() | |
} else { | |
bluetoothInterface.enable() | |
bluetoothInterface.bluetoothEnabled + ::onBluetoothEnabled | |
} | |
private suspend fun collectDevices() = mutableListOf<BloothDevice>() | |
.also { devices -> | |
bluetoothInterface.deviceDiscovered + { devices += it } | |
waitForDiscoveryToFinish() | |
} | |
private suspend fun waitForDiscoveryToFinish() = CompletableDeferred<Unit>() | |
.apply { bluetoothInterface.discoveryEnded + { complete(Unit) } } | |
.await() | |
private fun onBluetoothEnabled(unit: Unit) { | |
bluetoothInterface.startDiscovery() | |
bluetoothInterface.bluetoothEnabled - ::onBluetoothEnabled | |
} | |
} |
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
/* | |
DATA CLASSES (Data Models) | |
------------ | |
Kotlin's way of creating a custom data type | |
(Data Model / DTO / Class with just Data, POKO, no Behavior / Dumb Data Object, whatever the fuck you wanna call it) | |
So, when you create one, note that public props can be defined right in the initialization. | |
- In the example below, title and note become public properties of a SkunkWork Model | |
*/ | |
/* | |
Note: The compiler automatically derives the following members from all properties declared in the primary constructor: | |
equals()/hashCode() pair; | |
toString() of the form "User(name=John, age=42)"; | |
componentN() functions corresponding to the properties in their order of declaration; | |
copy() function | |
*/ | |
data class SkunkWork(val title: String, val note: String? = null) |
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
/* | |
NULL | |
---- | |
In Kotlin, the type system distinguishes between references that can hold null (nullable references) | |
and those that can not (non-null references) | |
/* | |
/* | |
SAFE CALLS | |
---------- | |
Safe calls is one way in Kotlin to check for null for mutable properties, variables, etc. | |
If you have declared a variable with val, it's immutable so no need for a safe call like this | |
Instead of checking with an if statement if a prop or variable is null before trying to use it, you can | |
instead use the safe call shorthand which is nicer. | |
Safe calls are also useful in chains. | |
*/ | |
// Such a chain returns null if any of the properties in it is null | |
val departmentHead = bob?.department?.head?.name | |
// STRING TEMPLATES - mix strings with code | |
val inputOne = "Dave" | |
val inputTwo = "Schinkel" | |
val fullName = "$inputOne $inputTwo" // Dave Schinkel | |
// ELVIS OPERATOR | |
return toRoman["$inputOne$inputTwo"] ?: "$inputOne$inputTwo" | |
// NOT NULL ASSERTION OPERATOR | |
val companyLength = companyName!!.length |
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
/* | |
FUNCTIONS are first class citizens; | |
That means they are actual types in Kotli, | |
which means you can pass them into functions as params, | |
assign them to variables, etc. | |
*/ | |
// BASIC FUNCTION, with nullable string return type | |
fun add(inputOne: String, inputTwo: String): String? { | |
} | |
fun comparePermission(selfPermission: Int) = | |
selfPermission == PackageManager.PERMISSION_GRANTED | |
// function that takes no arguments and returns a SkunkWork | |
()->SkunkWork | |
// function that takes a name and returns a SkunkWork | |
(name)->SkunkWork | |
// function that returns another function that returns a SkunkWork | |
()->()->SkunkWork | |
// assigning a function to a variable | |
val getSkunkWork: ()->SkunkWork | |
// assigning a named function to a variable | |
fun printSkunkWork(skunkWork: SkunkWork) { | |
println(skunkwork.name) | |
} | |
val skunkWorkName = ::printSkunkWork | |
/* | |
FUNCTION LITERALS | |
There are two kinds in Kotlin: | |
- Lambda expression | |
- Anonymous function | |
- an alternative way to define a function, similar to a lambda; | |
the big difference is that anonymous functions are more explicit | |
- It is more clear when we are using them, and return value needs to be specified explicitly | |
*/ | |
/* | |
LAMBDAS | |
- a short way to define a function | |
- very similar to Java lambdas | |
- everything is optional except the code body | |
- the type of the last command within a lambda block is the returned type | |
*/ | |
val lambdaName : Type = { argumentList -> codeBody } | |
val square = { number: Int -> number * number } | |
// lambda that takes an int argument and returns a string | |
val magnitude100String = { input : Int -> | |
val magnitude = input * 100 | |
magnitude.toString() | |
} | |
// lambda, where argument type is inferred to be type SkunkWork. | |
// ()->String is just describes the type of variable which is | |
// describing the lamba function type itself (note: this is optional) | |
// { println(skunkwork.name) } is the actual lambda | |
val skunkWorkName: ()->String = { println(skunkwork.name) } | |
// lambda, where lack of argument type is inferred to be type SkunkWork by what the function returns | |
// (Int)->String is just describes the type of variable, which is | |
// just describing the lamba function type itself (not required) | |
val skunkWorkName: (Int)->String = { id -> println(skunkwork.name) } |
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
KOTLIN | |
---------------------------------------------------------------------------------------------- | |
http://bit.ly/30nOl2y - Coding Conventions | |
FUNCTIONS | |
http://bit.ly/2VAUcCH - Function Type vs Function literal vs Lambda expression vs Anonymous function | |
http://bit.ly/2JftGrZ - Lambda Expressions in Kotlin | |
NULL | |
http://bit.ly/2Jxek1m - Null Safety |
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
/* | |
SWAP | |
---- | |
swapping between two variables | |
*/ | |
// easy way | |
val inputOne = "AB" | |
val inputTwo = "CD" | |
inputOne = inputTwo.also { inputTwo = inputOne } | |
// manual way, not thread safe | |
fun swap(pair: MutablePair) { | |
val temp = pair.one | |
pair.one = pair.two | |
pair.two = temp | |
} | |
// get last char | |
inputOne.takeLast(1) // B | |
/* | |
EQUALITY | |
.equals checks not only for structural equality but ALSO reference equality | |
== or != | |
- only checks for structural equality | |
- an expression like a == b is translated to: a?.equals(b) ?: (b === null) | |
- if a is not null, it calls the equals(Any?) function, | |
otherwise (i.e. a is null) it checks that b is referentially equal to null. | |
*/ | |
!skunkWorksTitle.equals("") | |
// Find a String | |
inputOne.contains(inputTwo); | |
inputOne in inputTwo |
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
/* | |
kotlin.test framework | |
Using the kotlin.test which wraps JUnit5 under the hood, | |
but has some nicer syntax in its test framework | |
*/ | |
// basic build.gradle.kt to get you up and running | |
plugins { | |
id("org.jetbrains.kotlin.jvm").version("1.3.21") | |
} | |
repositories { | |
jcenter() | |
} | |
dependencies { | |
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8") | |
testImplementation("org.jetbrains.kotlin:kotlin-test-junit") | |
} | |
// RomanNumeralCalculatorTest.kt | |
import kotlin.test.Test | |
import kotlin.test.* | |
class RomanNumeralCalculatorTest { | |
// using backticks (a Kotlin feature, preferred) | |
@Test | |
internal fun `one plus one is two`() { | |
val total = Calculator.add("I", "I") | |
assertEquals("II", total) | |
} | |
// using traditional Java camelcase (harder to read especially as test names get long) | |
@Test | |
internal fun onePlusOneIsTwo() { | |
val total = Calculator.add("I", "I") | |
assertEquals("II", total) | |
} | |
} |
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
// Kotlin classes can be declared either as mutable using the var keyword, or as read-only using the val keyword | |
// Example Class with data hiding (size) | |
class SkunkWork(val skunkworkRepo: SkunkWorkRepository) { | |
fun add(title: String) { | |
skunkworkRepo.addSkunkWork(SkunkWork(title)) | |
} | |
fun size(): Int { | |
return skunkworkRepo.findAllSkunkWork().size | |
} | |
} | |
// INTERFACE | |
interface BluetoothInterface { | |
} | |
// ENUM | |
enum class CameraState { | |
Ready, | |
MustRequest, | |
NoCamera | |
} | |
enum class DeviceType(override val value: Int, val displayName: String) : IntEnum { | |
Unknown(0, "Unknown"), | |
Classic(1, "Classic"), | |
LE(2, "Low Energy"), | |
Dual(3, "Dual"); | |
companion object { | |
fun fromInt(value: Int): DeviceType = | |
IntEnum.fromInt(value) ?: DeviceType.Unknown | |
} | |
} | |
// CASTING - unsafe cast - will blow up if cast is not possible | |
val skunkWork = skunkworkRepository.findById(skunkwork.id) as SkunkWork | |
// CASTING - safe cast | |
val skunkWork: String? = skunkworkRepository.findById(skunkwork.id) as? SkunkWork |
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
// mutable | |
var | |
/* | |
val | |
--- | |
- declares final, read only, reference | |
- cannot be reassigned (you can't change its reference) | |
- method parameters are implicitly declared as final val, so you cannot reassign them just like you could in Java | |
*/ | |
val |
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
// SERIALIZABLE CLASS | |
// https://proandroiddev.com/kotlinx-serialization-83815cc1c57b - more here on it | |
data class BloothDevice( | |
val name: String?, | |
val macAddress: String, | |
val type: DeviceType, | |
val majorClass: BluetoothMajorClass?, | |
val minorClass: BluetoothMinorClass?, | |
val services: List<BluetoothServiceClass> | |
) : Serializable |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment