Last active
October 23, 2018 20:00
-
-
Save bgigle/9aae7645067128f303fea1bf396a83db to your computer and use it in GitHub Desktop.
Kotlin: Al Fresco reference code
This file contains 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 java.time.LocalDate | |
import java.time.Period | |
import java.util.stream.Collectors | |
/** | |
* Reference code for Kotlin: Al Fresco | |
*/ | |
object Main { | |
@JvmStatic | |
fun main(args: Array<String>) { | |
/* Classes in Kotlin */ | |
val elizabethHostess = Hostess() | |
val hyacinthHostess = Hostess("Hyacinth") | |
hyacinthHostess.sendInvites(listOf("Daisy", "Onslow")) | |
/* Data classes */ | |
val delectableSalad = Salad(true, setOf("Lettuce", "Tomato")) | |
val scrumptiousSalad = Salad(ingredients = setOf("Kale", "Spam")) | |
val horrificSalad = scrumptiousSalad.copy(isFresh = false) | |
// menu = "Salad(isFresh=false, ingredients=[Kale, Spam])" | |
val menu = horrificSalad.toString() | |
val (delectableFreshness, delectableIngredients) = delectableSalad | |
/* Objects */ | |
val finestSalad = Salad(true, setOf("Cheese", "Bun", "Hamburger")) | |
ChefUtil.makeSalad(finestSalad) | |
/* Companion objects */ | |
val bestColor = Blanket.DEFAULT_COLOR | |
val blanket = Blanket.getInstance() | |
/* Mutability */ | |
// flyingBlanket is read-only variable, i.e. final | |
val flyingBlanket = Blanket("flying through the stratosphere") | |
flyingBlanket = Blanket("in outer space") // does not compile | |
// securityBlanket is read-write variable | |
var securityBlanket = Blanket("in a baby crib") | |
securityBlanket = Blanket("in Fort Knox") // compiles | |
/* Type system */ | |
// ambrosiaSalad is non-nullable | |
var ambrosiaSalad: Salad | |
ambrosiaSalad = null // does not compile | |
// glasswortSalad is nullable | |
var glasswortSalad: Salad? | |
glasswortSalad = null | |
/* Safe calls */ | |
val guest: Guest? = null | |
val isLate = guest?.wienermobile?.isRunning()?.not() | |
/* Elvis operator */ | |
val reason: String? = null | |
val excuse = reason ?: "I'm allergic to spam" | |
val rationalization = reason ?: throw IllegalArgumentException() | |
/* Smart casting */ | |
val mysteryObj: Any? = guessAnObject() | |
if (mysteryObj is LocalDate) { | |
println("${LocalDate.now().datesUntil(mysteryObj).count()} days") | |
} | |
var mysteryGuest = mysteryObj as Guest | |
var mysterySalad = mysteryObj as? Salad | |
/* when function */ | |
val enigmaObj: Any? = guessAnObject() | |
val result = when (enigmaObj) { | |
is Hostess -> { | |
enigmaObj.name | |
} | |
in 41..43 -> { | |
"The answer to life, the universe, and everything" | |
} | |
true, 1, "spam" -> { | |
"It's an $enigmaObj" | |
} | |
guessAnObject() -> { | |
"Great guess!" | |
} | |
else -> { | |
"The mystery continues..." | |
} | |
} | |
/* Extension functions */ | |
val dinnerDate = LocalDate.parse("2018-10-24") | |
val betterDate = dinnerDate.reschedule(7) | |
// invite = "2018-10-31" | |
val invite = betterDate.toString() | |
/* Higher-order functions */ | |
var firstRsvp = obtainRsvp(::callSheridan) | |
var secondRsvp = obtainRsvp { count: Int -> | |
println("Emailing $count times") | |
Salad() | |
} | |
/* Collections & lambdas */ | |
val rsvpOrders: List<Salad> = emptyList() | |
val shoppingList = rsvpOrders.filterNotNull() | |
.parallelStream() | |
.flatMap { it.ingredients.stream() } | |
.filter { it != "bacon bits" } | |
.distinct() | |
.sorted { i1, i2 -> i1.compareTo(i2) } | |
.collect(Collectors.toList()) | |
val lastIngredient = shoppingList.lastOrNull() | |
val hasNoAvocado = shoppingList.none { it == "avocado" } | |
/* Fin */ | |
} | |
} | |
/* Classes in Kotlin */ | |
class Hostess(val name: String = "Elizabeth") { | |
fun sendInvites(guestList: List<String>): Boolean { | |
println("Sent!") | |
return true | |
} | |
} | |
/* Data classes */ | |
data class Salad(val isFresh: Boolean = true, val ingredients: Set<String> = emptySet()) | |
/* Objects */ | |
object ChefUtil { | |
fun makeSalad(salad: Salad) { | |
for (ingredient in salad.ingredients) { | |
println("Adding some $ingredient") | |
} | |
println("Bon Appetit!") | |
} | |
} | |
/* Companion objects */ | |
typealias Size = Pair<Int, Int> | |
class Blanket(val location: String) { | |
companion object { | |
const val DEFAULT_COLOR = "vanilla" | |
val DEFAULT_SIZE = Size(4, 6) | |
fun getInstance(): Blanket = Blanket("down by the river") | |
} | |
} | |
/* Safe calls */ | |
class Engine { | |
fun isRunning() = false | |
} | |
class Wienermobile(val engine: Engine?) { | |
fun isRunning() = false | |
} | |
class Guest(val wienermobile: Wienermobile?) | |
/* Smart casting */ | |
fun guessAnObject(): Any = false | |
/* Extension functions */ | |
fun LocalDate.reschedule(days: Long): LocalDate { | |
return this.plusDays(days) | |
} | |
/* Higher-order functions */ | |
fun obtainRsvp(contact: (Int) -> Salad): Salad { | |
println("Looking for an RSVP") | |
return contact.invoke(5) | |
} | |
fun callSheridan(count: Int): Salad { | |
for (i in 0..count) { | |
println("Phone call #$i") | |
} | |
return Salad() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment