SlideShare a Scribd company logo
Mastering
Kotlin Standard
Library
Nelson Glauber
@nglauber
• Provides the essential types, classes and functions for
everyday work with Kotlin.
• In version 1.3 it contains approximately 50 sub packages
organized in 4 categories: 

Common, JVM, JS and Native.
Kotlin Std Lib
• Provides the essential types, classes and functions for
everyday work with Kotlin.
• In version 1.3 it contains approximately 50 sub packages
organized in 4 categories: 

Common, JVM, JS and Native.
Kotlin Std Lib
Scope Functions
• T.let { }
• T.apply { }
• T.also { }
• T.run { }
• run { }
• with(T) { }
Scope Functions
• It’s an extension function.

• Caller is represented by it.

• Returns the block’s last line.
• It’s commonly used for nullability checking.
public inline fun <T, R> T.let(block: (T) -> R): R {
return block(this)
}
fun deleteTempPhoto() {
var tempImageFile: File? = // ...
tempImageFile?.let {
if (it.exists()) it.delete()
}
}
fun deleteTempPhoto() {
var tempImageFile: File? = // ...
if (tempImageFile != null) {
if (tempImageFile.exists()) // thanks smart cast!
tempImageFile.delete()
}
}
class SomeClass {
var tempImageFile: File? = null
fun deleteTempPhoto() {
if (tempImageFile != null && tempImageFile.exists())
tempImageFile.delete()
}
}
class SomeClass {
var tempImageFile: File? = null
fun deleteTempPhoto() {
if (tempImageFile != null && tempImageFile.exists())
tempImageFile.delete()
}
}
Smart	cast	to	'File'	is	impossible,		
	because	'tempImageFile'	is	a	mutable		
	property	that	could	have	been	changed		
	by	this	time	
class SomeClass {
var tempImageFile: File? = null
fun deleteTempPhoto() {
if (tempImageFile != null && tempImageFile.exists())
tempImageFile.delete()
}
}
class SomeClass {
var tempImageFile: File? = null
fun deleteTempPhoto() {
if (tempImageFile != null && tempImageFile?.exists() == true )
tempImageFile?.delete()
}
}
😒😱
class SomeClass {
var tempImageFile: File? = null
fun deleteTempPhoto() {
tempImageFile?.let {
if (it.exists()) it.delete()
}
}
}
class SomeClass {
var tempImageFile: File? = null
fun deleteTempPhoto() {
tempImageFile?.let { file ->
if (file.exists()) file.delete()
}
}
}
😎
• It’s an extension function.

• Caller is represented by this.

• Returns the caller itself (this).
• It’s commonly used for initializing and configuring an
object.
public inline fun <T> T.apply(block: T.() -> Unit): T {
block()
return this
}
val chip = Chip(this)
chip.text = weatherType.name.capitalize()
chip.setChipBackgroundColorResource(R.color.colorAccent)
chip.isClickable = false
chip.isCheckable = false
chip.isCloseIconVisible = true
chip.setOnCloseIconClickListener {
if (viewModel.unselectWeatherType(weatherType)) {
chipGroup.removeView(it)
}
}
chipGroup.addView(chip)
val chip = Chip(this)
chip.text = weatherType.name.capitalize()
chip.setChipBackgroundColorResource(R.color.colorAccent)
chip.isClickable = false
chip.isCheckable = false
chip.isCloseIconVisible = true
chip.setOnCloseIconClickListener {
if (viewModel.unselectWeatherType(weatherType)) {
chipGroup.removeView(it)
}
}
chipGroup.addView(chip)
val chip = Chip(this).apply {
text = weatherType.name.capitalize()
setChipBackgroundColorResource(R.color.colorAccent)
isClickable = false
isCheckable = false
isCloseIconVisible = true
setOnCloseIconClickListener {
if (viewModel.unselectWeatherType(weatherType)) {
chipGroup.removeView(it)
}
}
}
chipGroup.addView(chip)
• It’s an extension function.

• Caller is represented by it.

• Returns the caller itself (this).
• It’s commonly used for chaining object initialization or
simple to separate one action from another.
public inline fun <T> T.also(block: (T) -> Unit): T {
block(this)
return this
}
val chip = Chip(this).apply {
text = weatherType.name.capitalize()
setChipBackgroundColorResource(R.color.colorAccent)
isClickable = false
isCheckable = false
isCloseIconVisible = true
setOnCloseIconClickListener {
if (viewModel.unselectWeatherType(weatherType)) {
chipGroup.removeView(it)
}
}
}
chipGroup.addView(chip)
Chip(this).apply {
text = weatherType.name.capitalize()
setChipBackgroundColorResource(R.color.colorAccent)
isClickable = false
isCheckable = false
isCloseIconVisible = true
setOnCloseIconClickListener {
if (viewModel.unselectWeatherType(weatherType)) {
chipGroup.removeView(it)
}
}
}.also {
chipGroup.addView(it)
}
• It’s an extension function.

• Caller is represented by this.

• Returns the block’s last line.
• It’s commonly used to get the result of an operation
using an object.
public inline fun <T, R> T.run(block: T.() -> R): R {
return block()
}
public inline fun <R> run(block: () -> R): R {
return block()
}
• It’s not an extension function.

• There’s no reference to the caller (once it’s not an
extension function).

• Returns the block’s last line.
• It’s commonly used to get the result of an operation.
private fun getFavoriteCity(): String {
val prefs =
PreferenceManager.getDefaultSharedPreferences(this)
return prefs.getString("favCity", null) ?:
getString(R.string.pref_city_default)
}
private fun getFavoriteCity() =
PreferenceManager.getDefaultSharedPreferences(this).run {
getString("favCity", null)
} ?: run {
getString(R.string.pref_city_default)
}
• It’s not an extension function.

• The caller is passed as parameter and is referenced by
this.

• Returns the block’s last line.
• It’s commonly used when you want to remember Delphi.
public inline fun <T, R> with(receiver: T, block: T.() -> R): R {
return receiver.block()
}
val webView: WebView = loadWebView()
with(webView) {
settings.javaScriptEnabled = true
loadUrl("file:///android_asset/app_page.html")
}
val webView: WebView? = loadWebView()
with(webView) {
settings.javaScriptEnabled = true
loadUrl("file:///android_asset/app_page.html")
}
val webView: WebView? = loadWebView()
with(webView) {
settings.javaScriptEnabled = true
loadUrl("file:///android_asset/app_page.html")
}
	Only	safe	(?.)	or	non-null	asserted	(!!.)		
	calls	are	allowed	on	a	nullable	receiver		
	of	type	WebView?
val webView: WebView? = loadWebView()
with(webView) {
this?.settings?.javaScriptEnabled = true
this?.loadUrl("file:///android_asset/app_page.html")
}
😩
val webView: WebView? = loadWebView()
webView?.let {
it.settings.javaScriptEnabled = true
it.loadUrl("file:///android_asset/app_page.html")
}
%
• T.let { } for nullability check.
• T.apply { } for object initialization.
• T.also { } for initialization chaining or a simple change of
scope.
• T.run { } to get a result from an object sequence of calls.
• run { } to get a result from a sequence of calls.
• with(T) { } for some reason you don’t know how to
explain… :)
Scope Functions - Summary
Annotations
fun sayHello() {
println("Hello!")
}
fun sayHello() {
println("Hello!")
}
fun greetings(message: String = "Hello") {
println(message)
}
@Deprecated(
message = "This function is being replaced.",
replaceWith = ReplaceWith("greetings(message)"),
level = DeprecationLevel.WARNING)
fun sayHello() {
println("Hello!")
}
fun greetings(message: String = "Hello") {
println(message)
}
@Deprecated(
message = "This function is being replaced.",
replaceWith = ReplaceWith("greetings(message)"),
level = DeprecationLevel.WARNING)
fun sayHello() {
println("Hello!")
}
fun greetings(message: String = "Hello") {
println(message)
}
fun main() {
sayHello()
}
fun login(userName: String, password: String) {
// Do login
}
fun login(userName: String, password: String) {
// Do login
}
data class AuthUser(val name: String, val password: String)
fun login(authUser: AuthUser) {
// New login with user
}
fun login(userName: String, password: String) {
// Do login
}
@Experimental(Experimental.Level.WARNING)
annotation class NewApi
data class AuthUser(val name: String, val password: String)
fun login(authUser: AuthUser) {
// New login with user
}
fun login(userName: String, password: String) {
// Do login
}
@Experimental(Experimental.Level.WARNING)
annotation class NewApi
@NewApi
data class AuthUser(val name: String, val password: String)
@NewApi
fun login(authUser: AuthUser) {
// New login with user
}
fun login(userName: String, password: String) {
// Do login
}
@Experimental(Experimental.Level.WARNING)
annotation class NewApi
@NewApi
data class AuthUser(val name: String, val password: String)
@NewApi
fun login(authUser: AuthUser) {
// New login with user
}
@UseExperimental(NewApi::class)
fun main() {
login(AuthUser("ngvl", "123"))
}
• JvmStatic
• JvmOverloads
• JvmName
• JvmField
• Throws
@Jvm* annotations
object UserRepository {
fun insertUser(user: User) {
// insert user
}
}
object UserRepository {
fun insertUser(user: User) {
// insert user
}
}
public class MyJavaClass {
...
public void addUser() {
UserRepository.INSTANCE.insertUser(new User("Nelson"));
}
}
object UserRepository {
@JvmStatic
fun insertUser(user: User) {
// insert user
}
}
public class MyJavaClass {
...
public void addUser() {
UserRepository.INSTANCE.insertUser(new User("Nelson"));
}
}
object UserRepository {
@JvmStatic
fun insertUser(user: User) {
// insert user
}
}
public class MyJavaClass {
...
public void addUser() {
UserRepository.insertUser(new User("Nelson"));
}
}
class MyKotlinClass {
fun printName(name: String = "Anonymous") {
println("Hello $name!")
}
//...
}
class MyKotlinClass {
fun printName(name: String = "Anonymous") {
println("Hello $name!")
}
//...
}
MyKotlinClass instance = new MyKotlinClass();
instance.printName("Nelson"); // Works!
instance.printName(); // Error!
class MyKotlinClass {
@JvmOverloads
fun printName(name: String = "Anonymous") {
println("Hello $name!")
}
//...
}
class MyKotlinClass {
@JvmOverloads
fun printName(name: String = "Anonymous") {
println("Hello $name!")
}
//...
}
MyKotlinClass instance = new MyKotlinClass();
instance.printName("Nelson");
instance.printName();
public class MyCustomView extends LinearLayout {
public MyCustomView(Context context) {
super(context);
}
public MyCustomView(Context context,
@Nullable AttributeSet attrs) {
super(context, attrs);
}
public MyCustomView(Context context,
@Nullable AttributeSet attrs,
int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
...
}
class MyCustomView : LinearLayout {
constructor(context: Context) : super(context) {
}
constructor(context: Context,
attrs: AttributeSet?
) : super(context, attrs) {
}
constructor(context: Context,
attrs: AttributeSet?,
defStyleAttr: Int
) : super(context, attrs, defStyleAttr) {
}
class MyCustomView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : LinearLayout(context, attrs, defStyleAttr) {
...
}
class ToggleView {
private var onOff = false
fun switch() {
onOff = !onOff
}
}
ToggleView toggleView = new ToggleView();
toggleView.switch(); // error!
class ToggleView {
private var onOff = false
@JvmName("switchOnOff")
fun switch() {
onOff = !onOff
}
}
ToggleView toggleView = new ToggleView();
toggleView.switchOnOff();
// StringsExtensions.kt
package ngvl.kotlin.demo.string
fun String.shouldCapitalizeName() =
this !in listOf("da", "das", "de", "di", "do", "dos")
fun String.capitalizeName() =
this.split(" ")
.joinToString(" ") {
if (it.shouldCapitalizeName())
it.capitalize()
else it
}
// Some Java file...
String name = StringExtensionsKt.capitalizeName("nelson glauber");
// StringsExtensions.kt
@file:JvmName("StringExt")
package ngvl.kotlin.demo.string
fun String.shouldCapitalizeName() =
this !in listOf("da", "das", "de", "di", "do", "dos")
fun String.capitalizeName() =
this.split(" ")
.joinToString(" ") {
if (it.shouldCapitalizeName())
it.capitalize()
else it
}
// Some Java file...
String name = StringExtensionsKt.capitalizeName("nelson glauber");
// StringsExtensions.kt
@file:JvmName("StringExt")
package ngvl.kotlin.demo.string
fun String.shouldCapitalizeName() =
this !in listOf("da", "das", "de", "di", "do", "dos")
fun String.capitalizeName() =
this.split(" ")
.joinToString(" ") {
if (it.shouldCapitalizeName())
it.capitalize()
else it
}
// Some Java file...
String name = StringExt.capitalizeName("nelson glauber");
data class Product(
val id: String,
val description: String,
val price: Float = 0f
)
Product product = new Product("001", "Smartphone", 0f);
System.out.println(
product.getId() +" - "+
product.getDescription() +" = "+
product.getPrice()
);
Product product = new Product("001", "Smartphone", 0f);
System.out.println(
product.getId() +" - "+
product.getDescription() +" = "+
product.getPrice()
);
data class Product(
@JvmField val id: String,
@JvmField val description: String,
@JvmField val price: Float = 0f
)
data class Product(
@JvmField val id: String,
@JvmField val description: String,
@JvmField val price: Float = 0f
)
Product product = new Product("001", "Smartphone", 0f);
System.out.println(
product.id +" - "+
product.description +" = "+
product.price
);
class MyKotlinClass {
companion object {
val CONSTANT_1 = 1
const val CONSTANT_2 = 2
@JvmField val CONSTANT_3 = 3
@JvmField val ROOT = User("root")
}
}
MyKotlinClass.Companion.getCONSTANT_1();
MyKotlinClass.CONSTANT_2;
MyKotlinClass.CONSTANT_3;
MyKotlinClass.ROOT;
object UserRepository {
@JvmStatic
fun insertUser(user: User) {
if (user.name.length < 5)
throw NameTooShortException()
// insert user ...
}
}
UserRepository.insertUser(new User("ngvl"));
object UserRepository {
@JvmStatic
@Throws(NameTooShortException::class)
fun insertUser(user: User) {
if (user.name.length < 5) {
throw NameTooShortException()
}
// insert user ...
}
}
UserRepository.insertUser(new User("ngvl"));
try {
UserRepository.insertUser(new User("ngvl"));
} catch (NameTooShortException e) {
// handle name too short
}
object UserRepository {
@JvmStatic
@Throws(NameTooShortException::class)
fun insertUser(user: User) {
if (user.name.length < 5) {
throw NameTooShortException()
}
// insert user ...
}
}
data class Recipe(
var name: String? = null,
var ingredients: List<Ingredient> = mutableListOf()
)
data class Ingredient(
var description: String? = null,
var quantity: Int = 0,
var unity: String? = null
)
data class Recipe(
var name: String? = null,
var ingredients: List<Ingredient> = mutableListOf()
)
data class Ingredient(
var description: String? = null,
var quantity: Int = 0,
var unity: String? = null
)
fun recipe(build: Recipe.() -> Unit) = Recipe().apply(build)
fun Recipe.ingredient(build: Ingredient.() -> Unit) {
ingredients += Ingredient().apply(build)
}
public inline fun <T> T.apply(block: T.() -> Unit): T {
block()
return this
}
fun recipe(build: Recipe.() -> Unit) = Recipe().apply(build)
fun Recipe.ingredient(build: Ingredient.() -> Unit) {
ingredients += Ingredient().apply(build)
}
val recipe = recipe {
name = "Chocolate Cake"
ingredient {
name = "Flour"
quantity = 3
unity = "cups"
}
}
println(recipe)
Recipe(name=Flour,	ingredients=[	
				Ingredient(description=null,	quantity=3,	unity=cups)]	
) 🤔
data class Recipe(
var name: String? = null,
var ingredients: List<Ingredient> = mutableListOf()
)
data class Ingredient(
var description: String? = null,
var quantity: Int = 0,
var unity: String? = null
)
fun recipe(build: Recipe.() -> Unit) = Recipe().apply(build)
fun Recipe.ingredient(build: Ingredient.() -> Unit) {
ingredients += Ingredient().apply(build)
}
@DslMarker annotation class RecipeLang
@RecipeLang
data class Recipe(
var name: String? = null,
var ingredients: List<Ingredient> = mutableListOf()
)
@RecipeLang
data class Ingredient(
var description: String? = null,
var quantity: Int = 0,
var unity: String? = null
)
fun recipe(build: Recipe.() -> Unit) = Recipe().apply(build)
fun Recipe.ingredient(build: Ingredient.() -> Unit) {
ingredients += Ingredient().apply(build)
}
val recipe = recipe {
name = "Chocolate Cake"
ingredient {
name = "Flour"
quantity = 3
unity = "cups"
}
}
println(recipe)
fun recipe(build: Recipe.() -> Unit) = Recipe().apply(build)
fun Recipe.ingredient(build: Ingredient.() -> Unit) {
ingredients += Ingredient().apply(build)
}
Compile	error:	'var	name:	String?'		
can't	be	called	in	this	context	by		
implicit	receiver.		
Use	the	explicit	one	if	necessary
val recipe = recipe {
name = "Chocolate Cake"
ingredient {
this@recipe.name = "Choc.Cake"
quantity = 3
unity = "cups"
}
}
println(recipe)
fun recipe(build: Recipe.() -> Unit) = Recipe().apply(build)
fun Recipe.ingredient(build: Ingredient.() -> Unit) {
ingredients += Ingredient().apply(build)
}
val recipe = recipe {
name = "Chocolate Cake"
ingredient {
description = "Flour"
quantity = 3
unity = "cups"
}
}
println(recipe)
fun recipe(build: Recipe.() -> Unit) = Recipe().apply(build)
fun Recipe.ingredient(build: Ingredient.() -> Unit) {
ingredients += Ingredient().apply(build)
}
Recipe(name=Chocolate	Cake,	ingredients=[	
				Ingredient(description=Flour,	quantity=3,	unity=cups)]	
) 😋
• @Deprecated and @Experimental help to document the
evolution of your code
• @Jvm* annotations help the integration with Java code.
• @DslMarker create scopes for your DSLs.
Annotations - Summary
Delegates
abstract class Individual(
val name: String,
val surname: String,
val age: Int
)
class Student(
name: String,
surname: String,
age: Int,
val university: String
) : Individual(name, surname, age)
class Worker(
name: String,
surname: String,
age: Int,
val company: String
) : Individual(name, surname, age)
abstract class Individual(
val name: String,
val surname: String,
val age: Int
)
class Student(
name: String,
surname: String,
age: Int,
val university: String
) : Individual(name, surname, age)
class Worker(
name: String,
surname: String,
age: Int,
val company: String
) : Individual(name, surname, age)
interface Individual {
val name: String
val surname: String
val age: Int
}
data class IndividualData(
override val name: String,
override val surname: String,
override val age: Int
) : Individual
data class Student(
val data: IndividualData,
val university: String
) : Individual by data
data class Worker(
val data: IndividualData,
val company: String
) : Individual by data
interface Individual {
val name: String
val surname: String
val age: Int
}
data class IndividualData(
override val name: String,
override val surname: String,
override val age: Int
) : Individual
data class Student(
val data: IndividualData,
val university: String
) : Individual by data
data class Worker(
val data: IndividualData,
val company: String
) : Individual by data
val student = Student(
IndividualData("Nelson", "Leal", 36), "Universo"
)
student.run {
println("$name $surname - $age - $university")
}
	Nelson	Leal	-	36	-	Universo
class Repository {
private val peopleDAO: PeopleDAO by lazy {
Database.getPeopleDAO()
}
fun insert(person: Person) {
peopleDAO.add(person)
}
fun all(): List<Person> = peopleDAO.list()
}
class Repository {
private val peopleDAO: PeopleDAO by lazy {
Database.getPeopleDAO()
}
fun insert(person: Person) {
peopleDAO.add(person)
}
fun all(): List<Person> = peopleDAO.list()
}
class Repository {
private val peopleDAO: PeopleDAO by lazy {
Database.getPeopleDAO()
}
fun insert(person: Person) {
peopleDAO.add(person)
}
fun all(): List<Person> = peopleDAO.list()
}
val repo = Repository()
repo.insert(Person("1", "Nelson"))
repo.insert(Person("2", "Glauber"))
repo.all().forEach(::printPerson)
Delegates.vetoable(0) { // it's an inline function
kprop, oldValue, newValue ->
newValue in 0..122 // Jeanne Calmen
}
val ageDelegate = {
Delegates.vetoable(0) {
kprop, oldValue, newValue ->
newValue in 0..122
}
}
if you don't use it as a function, it will return
the last value for the new instance
val ageDelegate = {
Delegates.vetoable(0) {
kprop, oldValue, newValue ->
newValue in 0..122
}
}
class Person(val id: String, val name: String) {
var age: Int by ageDelegate()
}
val ageDelegate = {
Delegates.vetoable(0) {
kprop, oldValue, newValue ->
newValue in 0..122
}
}
class Person(val id: String, val name: String) {
var age: Int by ageDelegate()
}
val p = Person("3", "Nelson")
p.age = -1
printPerson(p)
p.age = 150
printPerson(p)
p.age = 35
printPerson(p)
	3	-	Nelson	-	0	
	3	-	Nelson	-	0	
		
	3	-	Nelson	-	35
interface OnFilterCallback {
fun onFilterChanged(f: Filter)
}
class Filter {
var minBathNum: Int = 0
var minPrice: Float = 0f
private val callbacks = mutableSetOf<OnFilterCallback>()
fun addOnFilterChangedCallback(callback: OnFilterCallback) {
callbacks += callback
}
}
class Filter {
var minBathNum: Int = 0
var minPrice: Float = 0f
private val callbacks = mutableSetOf<OnFilterCallback>()
fun addOnFilterChangedCallback(callback: OnFilterCallback) {
callbacks += callback
}
fun notifyObservers() {
callbacks.forEach{ it.onFilterChanged(this) }
}
}
class FilterDelegate<T>(initial: T) {
var internal: T = initial
operator fun getValue(thisRef: Filter, prop: KProperty<*>): T {
return internal
}
operator fun setValue(thisRef: Filter, prop: KProperty<*>, value: T) {
internal = value
thisRef.notifyObservers()
}
}
interface OnFilterCallback {
fun onFilterChanged(f: Filter)
}
class Filter {
var minBathNum: Int by FilterDelegate(0)
var minPrice: Float by FilterDelegate(0f)
private val callbacks = mutableSetOf<OnFilterCallback>()
fun addOnFilterChangedCallback(callback: OnFilterCallback) {
callbacks += callback
}
fun notifyObservers() {
callbacks.forEach{ it.onFilterChanged(this) }
}
}
val filter = Filter()
filter.addOnFilterChangedCallback(object: OnFilterCallback {
override fun onFilterChanged(f: Filter) {
println("Observer #1")
println("MinPrice: ${f.minPrice} - Baths:${f.minBathNum}")
}
})
filter.addOnFilterChangedCallback(object : OnFilterCallback {
override fun onFilterChanged(f: Filter) {
println("Observer #2")
println("MinPrice: ${f.minPrice} - Baths:${f.minBathNum}")
}
})
filter.minBathNum = 2
filter.minPrice = 100_000f
filter.minBathNum = 1
filter.minPrice = 10f
Observer	#1	|	MinPrice:	0.0	-	Baths:2	
Observer	#2	|	MinPrice:	0.0	-	Baths:2	
Observer	#1	|	MinPrice:	100000.0	-	Baths:2	
Observer	#2	|	MinPrice:	100000.0	-	Baths:2	
Observer	#1	|	MinPrice:	100000.0	-	Baths:1	
Observer	#2	|	MinPrice:	100000.0	-	Baths:1	
Observer	#1	|	MinPrice:	10.0	-	Baths:1	
Observer	#2	|	MinPrice:	10.0	-	Baths:1
fun <T> Filter.filterDelegate(initialValue: T) =
Delegates.observable(initialValue) { prop, oldValue, newValue ->
println("old: $oldValue -> new: $newValue")
this.notifyObservers()
}
fun <T> Filter.filterDelegate(initialValue: T) =
Delegates.observable(initialValue) { prop, oldValue, newValue ->
println("old: $oldValue -> new: $newValue")
this.notifyObservers()
}
class Filter {
var minBathNum: Int by filterDelegate(0)
var minPrice: Float by filterDelegate(0f)
...
}
val filter = Filter()
filter.addOnFilterChangedCallback(object: OnFilterCallback {
override fun onFilterChanged(f: Filter) {
println("Observer #1”)
}
})
filter.addOnFilterChangedCallback(object : OnFilterCallback {
override fun onFilterChanged(f: Filter) {
println("Observer #2")
}
})
filter.minBathNum = 2
filter.minPrice = 100_000f
filter.minBathNum = 1
filter.minPrice = 10f
old:	0	->	new:	2	
Observer	#1	
Observer	#2	
old:	0.0	->	new:	100000.0	
Observer	#1	
Observer	#2	
old:	2	->	new:	1	
Observer	#1	
Observer	#2	
old:	100000.0	->	new:	10.0	
Observer	#1	
Observer	#2
• Interface delegation for composition.
• lazy for… lazy initialization.
• vetoable to define a validation to be reused.
• observable if you need both old and new value.
• Custom delegates for everything else.
Delegates - Summary
• Std Lib has a lot of functions to help you to write a more
simple, readable and concise code.
• Check it out the lib internals. You’ll learn a lot!
• Check it out the Kotlin Koans (https://play.kotlinlang.org/
koans). It’s a good place to start (or recap)!
• Write Kotlin code, enjoy the std lib and have fun! 😉
Wrap up!
• Kotlin Standard Functions

https://medium.com/androiddevelopers/kotlin-standard-functions-
cheat-sheet-27f032dd4326
• Mastering Kotlin standard functions: run, with, let, also and apply

https://medium.com/@elye.project/mastering-kotlin-standard-
functions-run-with-let-also-and-apply-9cd334b0ef84
• Java Friendly Kotlin

https://codelabs.developers.google.com/codelabs/java-friendly-kotlin
• Simpler Kotlin class hierarchies using class delegation

https://proandroiddev.com/simpler-kotlin-class-hierarchies-using-
class-delegation-35464106fed5
References
Gracias!
Nelson Glauber
@nglauber

More Related Content

What's hot

Kotlin Bytecode Generation and Runtime Performance
Kotlin Bytecode Generation and Runtime PerformanceKotlin Bytecode Generation and Runtime Performance
Kotlin Bytecode Generation and Runtime Performance
intelliyole
 
OneRing @ OSCamp 2010
OneRing @ OSCamp 2010OneRing @ OSCamp 2010
OneRing @ OSCamp 2010
Qiangning Hong
 
Feel of Kotlin (Berlin JUG 16 Apr 2015)
Feel of Kotlin (Berlin JUG 16 Apr 2015)Feel of Kotlin (Berlin JUG 16 Apr 2015)
Feel of Kotlin (Berlin JUG 16 Apr 2015)
intelliyole
 
ES6 Overview
ES6 OverviewES6 Overview
ES6 Overview
Bruno Scopelliti
 
Exploring Clojurescript
Exploring ClojurescriptExploring Clojurescript
Exploring Clojurescript
Luke Donnet
 
Sneaking inside Kotlin features
Sneaking inside Kotlin featuresSneaking inside Kotlin features
Sneaking inside Kotlin features
Chandra Sekhar Nayak
 
Kotlin Coroutines. Flow is coming
Kotlin Coroutines. Flow is comingKotlin Coroutines. Flow is coming
Kotlin Coroutines. Flow is coming
Kirill Rozov
 
Proxies are Awesome!
Proxies are Awesome!Proxies are Awesome!
Proxies are Awesome!
Brendan Eich
 
FalsyValues. Dmitry Soshnikov - ECMAScript 6
FalsyValues. Dmitry Soshnikov - ECMAScript 6FalsyValues. Dmitry Soshnikov - ECMAScript 6
FalsyValues. Dmitry Soshnikov - ECMAScript 6
Dmitry Soshnikov
 
ES6 in Real Life
ES6 in Real LifeES6 in Real Life
ES6 in Real Life
Domenic Denicola
 
Comparing JVM languages
Comparing JVM languagesComparing JVM languages
Comparing JVM languages
Jose Manuel Ortega Candel
 
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Domenic Denicola
 
Introduction to kotlin coroutines
Introduction to kotlin coroutinesIntroduction to kotlin coroutines
Introduction to kotlin coroutines
NAVER Engineering
 
ES2015 (ES6) Overview
ES2015 (ES6) OverviewES2015 (ES6) Overview
ES2015 (ES6) Overview
hesher
 
Kotlin: a better Java
Kotlin: a better JavaKotlin: a better Java
Kotlin: a better Java
Nils Breunese
 
Intro to Reactive Thinking and RxJava 2
Intro to Reactive Thinking and RxJava 2Intro to Reactive Thinking and RxJava 2
Intro to Reactive Thinking and RxJava 2
JollyRogers5
 
Letswift19-clean-architecture
Letswift19-clean-architectureLetswift19-clean-architecture
Letswift19-clean-architecture
Jung Kim
 
EcmaScript 6 - The future is here
EcmaScript 6 - The future is hereEcmaScript 6 - The future is here
EcmaScript 6 - The future is here
Sebastiano Armeli
 
Think Async: Asynchronous Patterns in NodeJS
Think Async: Asynchronous Patterns in NodeJSThink Async: Asynchronous Patterns in NodeJS
Think Async: Asynchronous Patterns in NodeJS
Adam L Barrett
 
JVMLS 2016. Coroutines in Kotlin
JVMLS 2016. Coroutines in KotlinJVMLS 2016. Coroutines in Kotlin
JVMLS 2016. Coroutines in Kotlin
Andrey Breslav
 

What's hot (20)

Kotlin Bytecode Generation and Runtime Performance
Kotlin Bytecode Generation and Runtime PerformanceKotlin Bytecode Generation and Runtime Performance
Kotlin Bytecode Generation and Runtime Performance
 
OneRing @ OSCamp 2010
OneRing @ OSCamp 2010OneRing @ OSCamp 2010
OneRing @ OSCamp 2010
 
Feel of Kotlin (Berlin JUG 16 Apr 2015)
Feel of Kotlin (Berlin JUG 16 Apr 2015)Feel of Kotlin (Berlin JUG 16 Apr 2015)
Feel of Kotlin (Berlin JUG 16 Apr 2015)
 
ES6 Overview
ES6 OverviewES6 Overview
ES6 Overview
 
Exploring Clojurescript
Exploring ClojurescriptExploring Clojurescript
Exploring Clojurescript
 
Sneaking inside Kotlin features
Sneaking inside Kotlin featuresSneaking inside Kotlin features
Sneaking inside Kotlin features
 
Kotlin Coroutines. Flow is coming
Kotlin Coroutines. Flow is comingKotlin Coroutines. Flow is coming
Kotlin Coroutines. Flow is coming
 
Proxies are Awesome!
Proxies are Awesome!Proxies are Awesome!
Proxies are Awesome!
 
FalsyValues. Dmitry Soshnikov - ECMAScript 6
FalsyValues. Dmitry Soshnikov - ECMAScript 6FalsyValues. Dmitry Soshnikov - ECMAScript 6
FalsyValues. Dmitry Soshnikov - ECMAScript 6
 
ES6 in Real Life
ES6 in Real LifeES6 in Real Life
ES6 in Real Life
 
Comparing JVM languages
Comparing JVM languagesComparing JVM languages
Comparing JVM languages
 
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
 
Introduction to kotlin coroutines
Introduction to kotlin coroutinesIntroduction to kotlin coroutines
Introduction to kotlin coroutines
 
ES2015 (ES6) Overview
ES2015 (ES6) OverviewES2015 (ES6) Overview
ES2015 (ES6) Overview
 
Kotlin: a better Java
Kotlin: a better JavaKotlin: a better Java
Kotlin: a better Java
 
Intro to Reactive Thinking and RxJava 2
Intro to Reactive Thinking and RxJava 2Intro to Reactive Thinking and RxJava 2
Intro to Reactive Thinking and RxJava 2
 
Letswift19-clean-architecture
Letswift19-clean-architectureLetswift19-clean-architecture
Letswift19-clean-architecture
 
EcmaScript 6 - The future is here
EcmaScript 6 - The future is hereEcmaScript 6 - The future is here
EcmaScript 6 - The future is here
 
Think Async: Asynchronous Patterns in NodeJS
Think Async: Asynchronous Patterns in NodeJSThink Async: Asynchronous Patterns in NodeJS
Think Async: Asynchronous Patterns in NodeJS
 
JVMLS 2016. Coroutines in Kotlin
JVMLS 2016. Coroutines in KotlinJVMLS 2016. Coroutines in Kotlin
JVMLS 2016. Coroutines in Kotlin
 

Similar to Mastering Kotlin Standard Library

The Ring programming language version 1.7 book - Part 35 of 196
The Ring programming language version 1.7 book - Part 35 of 196The Ring programming language version 1.7 book - Part 35 of 196
The Ring programming language version 1.7 book - Part 35 of 196
Mahmoud Samir Fayed
 
[Codemotion 2015] patrones de diseño con java8
[Codemotion 2015] patrones de diseño con java8[Codemotion 2015] patrones de diseño con java8
[Codemotion 2015] patrones de diseño con java8
Alonso Torres
 
Kotlin Advanced - Apalon Kotlin Sprint Part 3
Kotlin Advanced - Apalon Kotlin Sprint Part 3Kotlin Advanced - Apalon Kotlin Sprint Part 3
Kotlin Advanced - Apalon Kotlin Sprint Part 3
Kirill Rozov
 
FP in Java - Project Lambda and beyond
FP in Java - Project Lambda and beyondFP in Java - Project Lambda and beyond
FP in Java - Project Lambda and beyond
Mario Fusco
 
C++ theory
C++ theoryC++ theory
C++ theory
Shyam Khant
 
KotlinForJavaDevelopers-UJUG.pptx
KotlinForJavaDevelopers-UJUG.pptxKotlinForJavaDevelopers-UJUG.pptx
KotlinForJavaDevelopers-UJUG.pptx
Ian Robertson
 
Java session4
Java session4Java session4
Java session4
Jigarthacker
 
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
James Titcumb
 
Wien15 java8
Wien15 java8Wien15 java8
Wien15 java8
Jaanus Pöial
 
Java Generics
Java GenericsJava Generics
Java Generics
jeslie
 
GE8151 Problem Solving and Python Programming
GE8151 Problem Solving and Python ProgrammingGE8151 Problem Solving and Python Programming
GE8151 Problem Solving and Python Programming
Muthu Vinayagam
 
Intro to Kotlin
Intro to KotlinIntro to Kotlin
Intro to Kotlin
Magda Miu
 
Kotlin - The Swiss army knife of programming languages - Visma Mobile Meet-up...
Kotlin - The Swiss army knife of programming languages - Visma Mobile Meet-up...Kotlin - The Swiss army knife of programming languages - Visma Mobile Meet-up...
Kotlin - The Swiss army knife of programming languages - Visma Mobile Meet-up...
Tudor Dragan
 
Ruby Programming Assignment Help
Ruby Programming Assignment HelpRuby Programming Assignment Help
Ruby Programming Assignment Help
HelpWithAssignment.com
 
Ruby Programming Assignment Help
Ruby Programming Assignment HelpRuby Programming Assignment Help
Ruby Programming Assignment Help
HelpWithAssignment.com
 
SeaJUG March 2004 - Groovy
SeaJUG March 2004 - GroovySeaJUG March 2004 - Groovy
SeaJUG March 2004 - Groovy
Ted Leung
 
documents.pub_new-features-in-java-8-it-jpoialjavanaitedwien15java8pdf-java-8...
documents.pub_new-features-in-java-8-it-jpoialjavanaitedwien15java8pdf-java-8...documents.pub_new-features-in-java-8-it-jpoialjavanaitedwien15java8pdf-java-8...
documents.pub_new-features-in-java-8-it-jpoialjavanaitedwien15java8pdf-java-8...
Akaks
 
Thumbtack Expertise Days # 5 - Javaz
Thumbtack Expertise Days # 5 - JavazThumbtack Expertise Days # 5 - Javaz
Thumbtack Expertise Days # 5 - Javaz
Alexey Remnev
 
Боремся с NPE вместе с Kotlin, Павел Шацких СберТех
Боремся с NPE вместе с Kotlin, Павел Шацких СберТехБоремся с NPE вместе с Kotlin, Павел Шацких СберТех
Боремся с NPE вместе с Kotlin, Павел Шацких СберТех
Сбертех | SberTech
 
Twig tips and tricks
Twig tips and tricksTwig tips and tricks
Twig tips and tricks
Javier Eguiluz
 

Similar to Mastering Kotlin Standard Library (20)

The Ring programming language version 1.7 book - Part 35 of 196
The Ring programming language version 1.7 book - Part 35 of 196The Ring programming language version 1.7 book - Part 35 of 196
The Ring programming language version 1.7 book - Part 35 of 196
 
[Codemotion 2015] patrones de diseño con java8
[Codemotion 2015] patrones de diseño con java8[Codemotion 2015] patrones de diseño con java8
[Codemotion 2015] patrones de diseño con java8
 
Kotlin Advanced - Apalon Kotlin Sprint Part 3
Kotlin Advanced - Apalon Kotlin Sprint Part 3Kotlin Advanced - Apalon Kotlin Sprint Part 3
Kotlin Advanced - Apalon Kotlin Sprint Part 3
 
FP in Java - Project Lambda and beyond
FP in Java - Project Lambda and beyondFP in Java - Project Lambda and beyond
FP in Java - Project Lambda and beyond
 
C++ theory
C++ theoryC++ theory
C++ theory
 
KotlinForJavaDevelopers-UJUG.pptx
KotlinForJavaDevelopers-UJUG.pptxKotlinForJavaDevelopers-UJUG.pptx
KotlinForJavaDevelopers-UJUG.pptx
 
Java session4
Java session4Java session4
Java session4
 
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
 
Wien15 java8
Wien15 java8Wien15 java8
Wien15 java8
 
Java Generics
Java GenericsJava Generics
Java Generics
 
GE8151 Problem Solving and Python Programming
GE8151 Problem Solving and Python ProgrammingGE8151 Problem Solving and Python Programming
GE8151 Problem Solving and Python Programming
 
Intro to Kotlin
Intro to KotlinIntro to Kotlin
Intro to Kotlin
 
Kotlin - The Swiss army knife of programming languages - Visma Mobile Meet-up...
Kotlin - The Swiss army knife of programming languages - Visma Mobile Meet-up...Kotlin - The Swiss army knife of programming languages - Visma Mobile Meet-up...
Kotlin - The Swiss army knife of programming languages - Visma Mobile Meet-up...
 
Ruby Programming Assignment Help
Ruby Programming Assignment HelpRuby Programming Assignment Help
Ruby Programming Assignment Help
 
Ruby Programming Assignment Help
Ruby Programming Assignment HelpRuby Programming Assignment Help
Ruby Programming Assignment Help
 
SeaJUG March 2004 - Groovy
SeaJUG March 2004 - GroovySeaJUG March 2004 - Groovy
SeaJUG March 2004 - Groovy
 
documents.pub_new-features-in-java-8-it-jpoialjavanaitedwien15java8pdf-java-8...
documents.pub_new-features-in-java-8-it-jpoialjavanaitedwien15java8pdf-java-8...documents.pub_new-features-in-java-8-it-jpoialjavanaitedwien15java8pdf-java-8...
documents.pub_new-features-in-java-8-it-jpoialjavanaitedwien15java8pdf-java-8...
 
Thumbtack Expertise Days # 5 - Javaz
Thumbtack Expertise Days # 5 - JavazThumbtack Expertise Days # 5 - Javaz
Thumbtack Expertise Days # 5 - Javaz
 
Боремся с NPE вместе с Kotlin, Павел Шацких СберТех
Боремся с NPE вместе с Kotlin, Павел Шацких СберТехБоремся с NPE вместе с Kotlin, Павел Шацких СберТех
Боремся с NPE вместе с Kotlin, Павел Шацких СберТех
 
Twig tips and tricks
Twig tips and tricksTwig tips and tricks
Twig tips and tricks
 

More from Nelson Glauber Leal

Seu primeiro app Android e iOS com Compose Multiplatform
Seu primeiro app Android e iOS com Compose MultiplatformSeu primeiro app Android e iOS com Compose Multiplatform
Seu primeiro app Android e iOS com Compose Multiplatform
Nelson Glauber Leal
 
Desenvolvimento Moderno de Aplicações Android 2023
Desenvolvimento Moderno de Aplicações Android 2023Desenvolvimento Moderno de Aplicações Android 2023
Desenvolvimento Moderno de Aplicações Android 2023
Nelson Glauber Leal
 
Novidades incríveis do Android em 2023
Novidades incríveis do Android em 2023Novidades incríveis do Android em 2023
Novidades incríveis do Android em 2023
Nelson Glauber Leal
 
Novidades das Bibliotecas Jetpack do Android (2021)
Novidades das Bibliotecas Jetpack do Android (2021)Novidades das Bibliotecas Jetpack do Android (2021)
Novidades das Bibliotecas Jetpack do Android (2021)
Nelson Glauber Leal
 
Android Jetpack Compose - Turkey 2021
Android Jetpack Compose - Turkey 2021Android Jetpack Compose - Turkey 2021
Android Jetpack Compose - Turkey 2021
Nelson Glauber Leal
 
Jetpack Compose a new way to implement UI on Android
Jetpack Compose a new way to implement UI on AndroidJetpack Compose a new way to implement UI on Android
Jetpack Compose a new way to implement UI on Android
Nelson Glauber Leal
 
Jetpack Compose a nova forma de implementar UI no Android
Jetpack Compose a nova forma de implementar UI no AndroidJetpack Compose a nova forma de implementar UI no Android
Jetpack Compose a nova forma de implementar UI no Android
Nelson Glauber Leal
 
O que é preciso para ser um desenvolvedor Android
O que é preciso para ser um desenvolvedor AndroidO que é preciso para ser um desenvolvedor Android
O que é preciso para ser um desenvolvedor Android
Nelson Glauber Leal
 
Arquitetando seu app Android com Jetpack
Arquitetando seu app Android com JetpackArquitetando seu app Android com Jetpack
Arquitetando seu app Android com Jetpack
Nelson Glauber Leal
 
Arquitetando seu app Android com Jetpack
Arquitetando seu app Android com JetpackArquitetando seu app Android com Jetpack
Arquitetando seu app Android com Jetpack
Nelson Glauber Leal
 
Aplicações assíncronas no Android com Coroutines & Jetpack
Aplicações assíncronas no Android com Coroutines & JetpackAplicações assíncronas no Android com Coroutines & Jetpack
Aplicações assíncronas no Android com Coroutines & Jetpack
Nelson Glauber Leal
 
Introdução ao Desenvolvimento Android com Kotlin
Introdução ao Desenvolvimento Android com KotlinIntrodução ao Desenvolvimento Android com Kotlin
Introdução ao Desenvolvimento Android com Kotlin
Nelson Glauber Leal
 
Arquitetando seu aplicativo Android com Jetpack
Arquitetando seu aplicativo Android com JetpackArquitetando seu aplicativo Android com Jetpack
Arquitetando seu aplicativo Android com Jetpack
Nelson Glauber Leal
 
Desenvolvimento Moderno de Aplicativos Android
Desenvolvimento Moderno de Aplicativos AndroidDesenvolvimento Moderno de Aplicativos Android
Desenvolvimento Moderno de Aplicativos Android
Nelson Glauber Leal
 
Desenvolvimento Moderno de aplicativos Android
Desenvolvimento Moderno de aplicativos AndroidDesenvolvimento Moderno de aplicativos Android
Desenvolvimento Moderno de aplicativos Android
Nelson Glauber Leal
 
Turbinando o desenvolvimento Android com Kotlin
Turbinando o desenvolvimento Android com KotlinTurbinando o desenvolvimento Android com Kotlin
Turbinando o desenvolvimento Android com Kotlin
Nelson Glauber Leal
 
Tudo que você precisa saber sobre Constraint Layout
Tudo que você precisa saber sobre Constraint LayoutTudo que você precisa saber sobre Constraint Layout
Tudo que você precisa saber sobre Constraint Layout
Nelson Glauber Leal
 
Persistência de Dados no SQLite com Room
Persistência de Dados no SQLite com RoomPersistência de Dados no SQLite com Room
Persistência de Dados no SQLite com Room
Nelson Glauber Leal
 
The world of Android Animations
The world of Android AnimationsThe world of Android Animations
The world of Android Animations
Nelson Glauber Leal
 
Android Constraint Layout
Android Constraint LayoutAndroid Constraint Layout
Android Constraint Layout
Nelson Glauber Leal
 

More from Nelson Glauber Leal (20)

Seu primeiro app Android e iOS com Compose Multiplatform
Seu primeiro app Android e iOS com Compose MultiplatformSeu primeiro app Android e iOS com Compose Multiplatform
Seu primeiro app Android e iOS com Compose Multiplatform
 
Desenvolvimento Moderno de Aplicações Android 2023
Desenvolvimento Moderno de Aplicações Android 2023Desenvolvimento Moderno de Aplicações Android 2023
Desenvolvimento Moderno de Aplicações Android 2023
 
Novidades incríveis do Android em 2023
Novidades incríveis do Android em 2023Novidades incríveis do Android em 2023
Novidades incríveis do Android em 2023
 
Novidades das Bibliotecas Jetpack do Android (2021)
Novidades das Bibliotecas Jetpack do Android (2021)Novidades das Bibliotecas Jetpack do Android (2021)
Novidades das Bibliotecas Jetpack do Android (2021)
 
Android Jetpack Compose - Turkey 2021
Android Jetpack Compose - Turkey 2021Android Jetpack Compose - Turkey 2021
Android Jetpack Compose - Turkey 2021
 
Jetpack Compose a new way to implement UI on Android
Jetpack Compose a new way to implement UI on AndroidJetpack Compose a new way to implement UI on Android
Jetpack Compose a new way to implement UI on Android
 
Jetpack Compose a nova forma de implementar UI no Android
Jetpack Compose a nova forma de implementar UI no AndroidJetpack Compose a nova forma de implementar UI no Android
Jetpack Compose a nova forma de implementar UI no Android
 
O que é preciso para ser um desenvolvedor Android
O que é preciso para ser um desenvolvedor AndroidO que é preciso para ser um desenvolvedor Android
O que é preciso para ser um desenvolvedor Android
 
Arquitetando seu app Android com Jetpack
Arquitetando seu app Android com JetpackArquitetando seu app Android com Jetpack
Arquitetando seu app Android com Jetpack
 
Arquitetando seu app Android com Jetpack
Arquitetando seu app Android com JetpackArquitetando seu app Android com Jetpack
Arquitetando seu app Android com Jetpack
 
Aplicações assíncronas no Android com Coroutines & Jetpack
Aplicações assíncronas no Android com Coroutines & JetpackAplicações assíncronas no Android com Coroutines & Jetpack
Aplicações assíncronas no Android com Coroutines & Jetpack
 
Introdução ao Desenvolvimento Android com Kotlin
Introdução ao Desenvolvimento Android com KotlinIntrodução ao Desenvolvimento Android com Kotlin
Introdução ao Desenvolvimento Android com Kotlin
 
Arquitetando seu aplicativo Android com Jetpack
Arquitetando seu aplicativo Android com JetpackArquitetando seu aplicativo Android com Jetpack
Arquitetando seu aplicativo Android com Jetpack
 
Desenvolvimento Moderno de Aplicativos Android
Desenvolvimento Moderno de Aplicativos AndroidDesenvolvimento Moderno de Aplicativos Android
Desenvolvimento Moderno de Aplicativos Android
 
Desenvolvimento Moderno de aplicativos Android
Desenvolvimento Moderno de aplicativos AndroidDesenvolvimento Moderno de aplicativos Android
Desenvolvimento Moderno de aplicativos Android
 
Turbinando o desenvolvimento Android com Kotlin
Turbinando o desenvolvimento Android com KotlinTurbinando o desenvolvimento Android com Kotlin
Turbinando o desenvolvimento Android com Kotlin
 
Tudo que você precisa saber sobre Constraint Layout
Tudo que você precisa saber sobre Constraint LayoutTudo que você precisa saber sobre Constraint Layout
Tudo que você precisa saber sobre Constraint Layout
 
Persistência de Dados no SQLite com Room
Persistência de Dados no SQLite com RoomPersistência de Dados no SQLite com Room
Persistência de Dados no SQLite com Room
 
The world of Android Animations
The world of Android AnimationsThe world of Android Animations
The world of Android Animations
 
Android Constraint Layout
Android Constraint LayoutAndroid Constraint Layout
Android Constraint Layout
 

Recently uploaded

Celebrity Girls Call Mumbai 🛵🚡9910780858 💃 Choose Best And Top Girl Service A...
Celebrity Girls Call Mumbai 🛵🚡9910780858 💃 Choose Best And Top Girl Service A...Celebrity Girls Call Mumbai 🛵🚡9910780858 💃 Choose Best And Top Girl Service A...
Celebrity Girls Call Mumbai 🛵🚡9910780858 💃 Choose Best And Top Girl Service A...
norina2645
 
VVIP Girls Call Mumbai 9910780858 Provide Best And Top Girl Service And No1 i...
VVIP Girls Call Mumbai 9910780858 Provide Best And Top Girl Service And No1 i...VVIP Girls Call Mumbai 9910780858 Provide Best And Top Girl Service And No1 i...
VVIP Girls Call Mumbai 9910780858 Provide Best And Top Girl Service And No1 i...
jealousviolet
 
Comprehensive Vulnerability Assessments Process _ Aardwolf Security.docx
Comprehensive Vulnerability Assessments Process _ Aardwolf Security.docxComprehensive Vulnerability Assessments Process _ Aardwolf Security.docx
Comprehensive Vulnerability Assessments Process _ Aardwolf Security.docx
Aardwolf Security
 
HIRE A HACKER FOR CHEATING HUSBAND/WIFE)
HIRE A HACKER FOR CHEATING HUSBAND/WIFE)HIRE A HACKER FOR CHEATING HUSBAND/WIFE)
HIRE A HACKER FOR CHEATING HUSBAND/WIFE)
josephinedrea942
 
Celebrity Girls Call Mumbai 9920725232 Unlimited Short Providing Girls Servic...
Celebrity Girls Call Mumbai 9920725232 Unlimited Short Providing Girls Servic...Celebrity Girls Call Mumbai 9920725232 Unlimited Short Providing Girls Servic...
Celebrity Girls Call Mumbai 9920725232 Unlimited Short Providing Girls Servic...
45unexpected
 
GT degree offer diploma Transcript
GT degree offer diploma TranscriptGT degree offer diploma Transcript
GT degree offer diploma Transcript
attueb
 
AI - Your Startup Sidekick (Leveraging AI to Bootstrap a Lean Startup).pdf
AI - Your Startup Sidekick (Leveraging AI to Bootstrap a Lean Startup).pdfAI - Your Startup Sidekick (Leveraging AI to Bootstrap a Lean Startup).pdf
AI - Your Startup Sidekick (Leveraging AI to Bootstrap a Lean Startup).pdf
Daniel Zivkovic
 
Il Data Streaming per un’AI real-time di nuova generazione
Il Data Streaming per un’AI real-time di nuova generazioneIl Data Streaming per un’AI real-time di nuova generazione
Il Data Streaming per un’AI real-time di nuova generazione
confluent
 
bangalore Girls call 👀 XXXXXXXXXXX 👀 Rs.9.5 K Cash Payment With Room Delivery
bangalore Girls call  👀 XXXXXXXXXXX 👀 Rs.9.5 K Cash Payment With Room Deliverybangalore Girls call  👀 XXXXXXXXXXX 👀 Rs.9.5 K Cash Payment With Room Delivery
bangalore Girls call 👀 XXXXXXXXXXX 👀 Rs.9.5 K Cash Payment With Room Delivery
sunilverma7884
 
Russian Girls Call Mumbai 🎈🔥9930687706 🔥💋🎈 Provide Best And Top Girl Service ...
Russian Girls Call Mumbai 🎈🔥9930687706 🔥💋🎈 Provide Best And Top Girl Service ...Russian Girls Call Mumbai 🎈🔥9930687706 🔥💋🎈 Provide Best And Top Girl Service ...
Russian Girls Call Mumbai 🎈🔥9930687706 🔥💋🎈 Provide Best And Top Girl Service ...
shanihomely
 
Verified Girls Call Mumbai 👀 9820252231 👀 Cash Payment With Room DeliveryDeli...
Verified Girls Call Mumbai 👀 9820252231 👀 Cash Payment With Room DeliveryDeli...Verified Girls Call Mumbai 👀 9820252231 👀 Cash Payment With Room DeliveryDeli...
Verified Girls Call Mumbai 👀 9820252231 👀 Cash Payment With Room DeliveryDeli...
87tomato
 
Attendance Tracking From Paper To Digital
Attendance Tracking From Paper To DigitalAttendance Tracking From Paper To Digital
Attendance Tracking From Paper To Digital
Task Tracker
 
ERP Software Solutions Provider in Coimbatore
ERP Software Solutions Provider in CoimbatoreERP Software Solutions Provider in Coimbatore
ERP Software Solutions Provider in Coimbatore
Nextskill Technologies
 
TEQnation 2024: Sustainable Software: May the Green Code Be with You
TEQnation 2024: Sustainable Software: May the Green Code Be with YouTEQnation 2024: Sustainable Software: May the Green Code Be with You
TEQnation 2024: Sustainable Software: May the Green Code Be with You
marcofolio
 
The Ultimate Guide to Phone Spy Apps: Everything You Need to Know
The Ultimate Guide to Phone Spy Apps: Everything You Need to KnowThe Ultimate Guide to Phone Spy Apps: Everything You Need to Know
The Ultimate Guide to Phone Spy Apps: Everything You Need to Know
onemonitarsoftware
 
AWS DevOps-Tutorial CHANAKYA SRIYAN DUKKA.
AWS DevOps-Tutorial CHANAKYA SRIYAN DUKKA.AWS DevOps-Tutorial CHANAKYA SRIYAN DUKKA.
AWS DevOps-Tutorial CHANAKYA SRIYAN DUKKA.
Srinivas Dukka
 
Independent Girls call Service Pune 000XX00000 Provide Best And Top Girl Serv...
Independent Girls call Service Pune 000XX00000 Provide Best And Top Girl Serv...Independent Girls call Service Pune 000XX00000 Provide Best And Top Girl Serv...
Independent Girls call Service Pune 000XX00000 Provide Best And Top Girl Serv...
bhumivarma35300
 
Cisco Live Announcements: New ThousandEyes Release Highlights - July 2024
Cisco Live Announcements: New ThousandEyes Release Highlights - July 2024Cisco Live Announcements: New ThousandEyes Release Highlights - July 2024
Cisco Live Announcements: New ThousandEyes Release Highlights - July 2024
ThousandEyes
 
Amadeus Travel API, Amadeus Booking API, Amadeus GDS
Amadeus Travel API, Amadeus Booking API, Amadeus GDSAmadeus Travel API, Amadeus Booking API, Amadeus GDS
Amadeus Travel API, Amadeus Booking API, Amadeus GDS
aadhiyaeliza
 
IoT In Manufacturing_ Use Cases, Benefits, and Challenges.pdf
IoT In Manufacturing_ Use Cases, Benefits, and Challenges.pdfIoT In Manufacturing_ Use Cases, Benefits, and Challenges.pdf
IoT In Manufacturing_ Use Cases, Benefits, and Challenges.pdf
mohitd6
 

Recently uploaded (20)

Celebrity Girls Call Mumbai 🛵🚡9910780858 💃 Choose Best And Top Girl Service A...
Celebrity Girls Call Mumbai 🛵🚡9910780858 💃 Choose Best And Top Girl Service A...Celebrity Girls Call Mumbai 🛵🚡9910780858 💃 Choose Best And Top Girl Service A...
Celebrity Girls Call Mumbai 🛵🚡9910780858 💃 Choose Best And Top Girl Service A...
 
VVIP Girls Call Mumbai 9910780858 Provide Best And Top Girl Service And No1 i...
VVIP Girls Call Mumbai 9910780858 Provide Best And Top Girl Service And No1 i...VVIP Girls Call Mumbai 9910780858 Provide Best And Top Girl Service And No1 i...
VVIP Girls Call Mumbai 9910780858 Provide Best And Top Girl Service And No1 i...
 
Comprehensive Vulnerability Assessments Process _ Aardwolf Security.docx
Comprehensive Vulnerability Assessments Process _ Aardwolf Security.docxComprehensive Vulnerability Assessments Process _ Aardwolf Security.docx
Comprehensive Vulnerability Assessments Process _ Aardwolf Security.docx
 
HIRE A HACKER FOR CHEATING HUSBAND/WIFE)
HIRE A HACKER FOR CHEATING HUSBAND/WIFE)HIRE A HACKER FOR CHEATING HUSBAND/WIFE)
HIRE A HACKER FOR CHEATING HUSBAND/WIFE)
 
Celebrity Girls Call Mumbai 9920725232 Unlimited Short Providing Girls Servic...
Celebrity Girls Call Mumbai 9920725232 Unlimited Short Providing Girls Servic...Celebrity Girls Call Mumbai 9920725232 Unlimited Short Providing Girls Servic...
Celebrity Girls Call Mumbai 9920725232 Unlimited Short Providing Girls Servic...
 
GT degree offer diploma Transcript
GT degree offer diploma TranscriptGT degree offer diploma Transcript
GT degree offer diploma Transcript
 
AI - Your Startup Sidekick (Leveraging AI to Bootstrap a Lean Startup).pdf
AI - Your Startup Sidekick (Leveraging AI to Bootstrap a Lean Startup).pdfAI - Your Startup Sidekick (Leveraging AI to Bootstrap a Lean Startup).pdf
AI - Your Startup Sidekick (Leveraging AI to Bootstrap a Lean Startup).pdf
 
Il Data Streaming per un’AI real-time di nuova generazione
Il Data Streaming per un’AI real-time di nuova generazioneIl Data Streaming per un’AI real-time di nuova generazione
Il Data Streaming per un’AI real-time di nuova generazione
 
bangalore Girls call 👀 XXXXXXXXXXX 👀 Rs.9.5 K Cash Payment With Room Delivery
bangalore Girls call  👀 XXXXXXXXXXX 👀 Rs.9.5 K Cash Payment With Room Deliverybangalore Girls call  👀 XXXXXXXXXXX 👀 Rs.9.5 K Cash Payment With Room Delivery
bangalore Girls call 👀 XXXXXXXXXXX 👀 Rs.9.5 K Cash Payment With Room Delivery
 
Russian Girls Call Mumbai 🎈🔥9930687706 🔥💋🎈 Provide Best And Top Girl Service ...
Russian Girls Call Mumbai 🎈🔥9930687706 🔥💋🎈 Provide Best And Top Girl Service ...Russian Girls Call Mumbai 🎈🔥9930687706 🔥💋🎈 Provide Best And Top Girl Service ...
Russian Girls Call Mumbai 🎈🔥9930687706 🔥💋🎈 Provide Best And Top Girl Service ...
 
Verified Girls Call Mumbai 👀 9820252231 👀 Cash Payment With Room DeliveryDeli...
Verified Girls Call Mumbai 👀 9820252231 👀 Cash Payment With Room DeliveryDeli...Verified Girls Call Mumbai 👀 9820252231 👀 Cash Payment With Room DeliveryDeli...
Verified Girls Call Mumbai 👀 9820252231 👀 Cash Payment With Room DeliveryDeli...
 
Attendance Tracking From Paper To Digital
Attendance Tracking From Paper To DigitalAttendance Tracking From Paper To Digital
Attendance Tracking From Paper To Digital
 
ERP Software Solutions Provider in Coimbatore
ERP Software Solutions Provider in CoimbatoreERP Software Solutions Provider in Coimbatore
ERP Software Solutions Provider in Coimbatore
 
TEQnation 2024: Sustainable Software: May the Green Code Be with You
TEQnation 2024: Sustainable Software: May the Green Code Be with YouTEQnation 2024: Sustainable Software: May the Green Code Be with You
TEQnation 2024: Sustainable Software: May the Green Code Be with You
 
The Ultimate Guide to Phone Spy Apps: Everything You Need to Know
The Ultimate Guide to Phone Spy Apps: Everything You Need to KnowThe Ultimate Guide to Phone Spy Apps: Everything You Need to Know
The Ultimate Guide to Phone Spy Apps: Everything You Need to Know
 
AWS DevOps-Tutorial CHANAKYA SRIYAN DUKKA.
AWS DevOps-Tutorial CHANAKYA SRIYAN DUKKA.AWS DevOps-Tutorial CHANAKYA SRIYAN DUKKA.
AWS DevOps-Tutorial CHANAKYA SRIYAN DUKKA.
 
Independent Girls call Service Pune 000XX00000 Provide Best And Top Girl Serv...
Independent Girls call Service Pune 000XX00000 Provide Best And Top Girl Serv...Independent Girls call Service Pune 000XX00000 Provide Best And Top Girl Serv...
Independent Girls call Service Pune 000XX00000 Provide Best And Top Girl Serv...
 
Cisco Live Announcements: New ThousandEyes Release Highlights - July 2024
Cisco Live Announcements: New ThousandEyes Release Highlights - July 2024Cisco Live Announcements: New ThousandEyes Release Highlights - July 2024
Cisco Live Announcements: New ThousandEyes Release Highlights - July 2024
 
Amadeus Travel API, Amadeus Booking API, Amadeus GDS
Amadeus Travel API, Amadeus Booking API, Amadeus GDSAmadeus Travel API, Amadeus Booking API, Amadeus GDS
Amadeus Travel API, Amadeus Booking API, Amadeus GDS
 
IoT In Manufacturing_ Use Cases, Benefits, and Challenges.pdf
IoT In Manufacturing_ Use Cases, Benefits, and Challenges.pdfIoT In Manufacturing_ Use Cases, Benefits, and Challenges.pdf
IoT In Manufacturing_ Use Cases, Benefits, and Challenges.pdf
 

Mastering Kotlin Standard Library

  • 2. • Provides the essential types, classes and functions for everyday work with Kotlin. • In version 1.3 it contains approximately 50 sub packages organized in 4 categories: 
 Common, JVM, JS and Native. Kotlin Std Lib
  • 3. • Provides the essential types, classes and functions for everyday work with Kotlin. • In version 1.3 it contains approximately 50 sub packages organized in 4 categories: 
 Common, JVM, JS and Native. Kotlin Std Lib
  • 5. • T.let { } • T.apply { } • T.also { } • T.run { } • run { } • with(T) { } Scope Functions
  • 6. • It’s an extension function. • Caller is represented by it. • Returns the block’s last line. • It’s commonly used for nullability checking. public inline fun <T, R> T.let(block: (T) -> R): R { return block(this) }
  • 7. fun deleteTempPhoto() { var tempImageFile: File? = // ... tempImageFile?.let { if (it.exists()) it.delete() } }
  • 8. fun deleteTempPhoto() { var tempImageFile: File? = // ... if (tempImageFile != null) { if (tempImageFile.exists()) // thanks smart cast! tempImageFile.delete() } }
  • 9. class SomeClass { var tempImageFile: File? = null fun deleteTempPhoto() { if (tempImageFile != null && tempImageFile.exists()) tempImageFile.delete() } }
  • 10. class SomeClass { var tempImageFile: File? = null fun deleteTempPhoto() { if (tempImageFile != null && tempImageFile.exists()) tempImageFile.delete() } }
  • 11. Smart cast to 'File' is impossible, because 'tempImageFile' is a mutable property that could have been changed by this time class SomeClass { var tempImageFile: File? = null fun deleteTempPhoto() { if (tempImageFile != null && tempImageFile.exists()) tempImageFile.delete() } }
  • 12. class SomeClass { var tempImageFile: File? = null fun deleteTempPhoto() { if (tempImageFile != null && tempImageFile?.exists() == true ) tempImageFile?.delete() } } 😒😱
  • 13. class SomeClass { var tempImageFile: File? = null fun deleteTempPhoto() { tempImageFile?.let { if (it.exists()) it.delete() } } }
  • 14. class SomeClass { var tempImageFile: File? = null fun deleteTempPhoto() { tempImageFile?.let { file -> if (file.exists()) file.delete() } } } 😎
  • 15. • It’s an extension function. • Caller is represented by this. • Returns the caller itself (this). • It’s commonly used for initializing and configuring an object. public inline fun <T> T.apply(block: T.() -> Unit): T { block() return this }
  • 16. val chip = Chip(this) chip.text = weatherType.name.capitalize() chip.setChipBackgroundColorResource(R.color.colorAccent) chip.isClickable = false chip.isCheckable = false chip.isCloseIconVisible = true chip.setOnCloseIconClickListener { if (viewModel.unselectWeatherType(weatherType)) { chipGroup.removeView(it) } } chipGroup.addView(chip)
  • 17. val chip = Chip(this) chip.text = weatherType.name.capitalize() chip.setChipBackgroundColorResource(R.color.colorAccent) chip.isClickable = false chip.isCheckable = false chip.isCloseIconVisible = true chip.setOnCloseIconClickListener { if (viewModel.unselectWeatherType(weatherType)) { chipGroup.removeView(it) } } chipGroup.addView(chip)
  • 18. val chip = Chip(this).apply { text = weatherType.name.capitalize() setChipBackgroundColorResource(R.color.colorAccent) isClickable = false isCheckable = false isCloseIconVisible = true setOnCloseIconClickListener { if (viewModel.unselectWeatherType(weatherType)) { chipGroup.removeView(it) } } } chipGroup.addView(chip)
  • 19. • It’s an extension function. • Caller is represented by it. • Returns the caller itself (this). • It’s commonly used for chaining object initialization or simple to separate one action from another. public inline fun <T> T.also(block: (T) -> Unit): T { block(this) return this }
  • 20. val chip = Chip(this).apply { text = weatherType.name.capitalize() setChipBackgroundColorResource(R.color.colorAccent) isClickable = false isCheckable = false isCloseIconVisible = true setOnCloseIconClickListener { if (viewModel.unselectWeatherType(weatherType)) { chipGroup.removeView(it) } } } chipGroup.addView(chip)
  • 21. Chip(this).apply { text = weatherType.name.capitalize() setChipBackgroundColorResource(R.color.colorAccent) isClickable = false isCheckable = false isCloseIconVisible = true setOnCloseIconClickListener { if (viewModel.unselectWeatherType(weatherType)) { chipGroup.removeView(it) } } }.also { chipGroup.addView(it) }
  • 22. • It’s an extension function. • Caller is represented by this. • Returns the block’s last line. • It’s commonly used to get the result of an operation using an object. public inline fun <T, R> T.run(block: T.() -> R): R { return block() }
  • 23. public inline fun <R> run(block: () -> R): R { return block() } • It’s not an extension function. • There’s no reference to the caller (once it’s not an extension function). • Returns the block’s last line. • It’s commonly used to get the result of an operation.
  • 24. private fun getFavoriteCity(): String { val prefs = PreferenceManager.getDefaultSharedPreferences(this) return prefs.getString("favCity", null) ?: getString(R.string.pref_city_default) }
  • 25. private fun getFavoriteCity() = PreferenceManager.getDefaultSharedPreferences(this).run { getString("favCity", null) } ?: run { getString(R.string.pref_city_default) }
  • 26. • It’s not an extension function. • The caller is passed as parameter and is referenced by this. • Returns the block’s last line. • It’s commonly used when you want to remember Delphi. public inline fun <T, R> with(receiver: T, block: T.() -> R): R { return receiver.block() }
  • 27. val webView: WebView = loadWebView() with(webView) { settings.javaScriptEnabled = true loadUrl("file:///android_asset/app_page.html") }
  • 28. val webView: WebView? = loadWebView() with(webView) { settings.javaScriptEnabled = true loadUrl("file:///android_asset/app_page.html") }
  • 29. val webView: WebView? = loadWebView() with(webView) { settings.javaScriptEnabled = true loadUrl("file:///android_asset/app_page.html") } Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type WebView?
  • 30. val webView: WebView? = loadWebView() with(webView) { this?.settings?.javaScriptEnabled = true this?.loadUrl("file:///android_asset/app_page.html") } 😩
  • 31. val webView: WebView? = loadWebView() webView?.let { it.settings.javaScriptEnabled = true it.loadUrl("file:///android_asset/app_page.html") } %
  • 32. • T.let { } for nullability check. • T.apply { } for object initialization. • T.also { } for initialization chaining or a simple change of scope. • T.run { } to get a result from an object sequence of calls. • run { } to get a result from a sequence of calls. • with(T) { } for some reason you don’t know how to explain… :) Scope Functions - Summary
  • 35. fun sayHello() { println("Hello!") } fun greetings(message: String = "Hello") { println(message) }
  • 36. @Deprecated( message = "This function is being replaced.", replaceWith = ReplaceWith("greetings(message)"), level = DeprecationLevel.WARNING) fun sayHello() { println("Hello!") } fun greetings(message: String = "Hello") { println(message) }
  • 37. @Deprecated( message = "This function is being replaced.", replaceWith = ReplaceWith("greetings(message)"), level = DeprecationLevel.WARNING) fun sayHello() { println("Hello!") } fun greetings(message: String = "Hello") { println(message) } fun main() { sayHello() }
  • 38. fun login(userName: String, password: String) { // Do login }
  • 39. fun login(userName: String, password: String) { // Do login } data class AuthUser(val name: String, val password: String) fun login(authUser: AuthUser) { // New login with user }
  • 40. fun login(userName: String, password: String) { // Do login } @Experimental(Experimental.Level.WARNING) annotation class NewApi data class AuthUser(val name: String, val password: String) fun login(authUser: AuthUser) { // New login with user }
  • 41. fun login(userName: String, password: String) { // Do login } @Experimental(Experimental.Level.WARNING) annotation class NewApi @NewApi data class AuthUser(val name: String, val password: String) @NewApi fun login(authUser: AuthUser) { // New login with user }
  • 42. fun login(userName: String, password: String) { // Do login } @Experimental(Experimental.Level.WARNING) annotation class NewApi @NewApi data class AuthUser(val name: String, val password: String) @NewApi fun login(authUser: AuthUser) { // New login with user } @UseExperimental(NewApi::class) fun main() { login(AuthUser("ngvl", "123")) }
  • 43. • JvmStatic • JvmOverloads • JvmName • JvmField • Throws @Jvm* annotations
  • 44. object UserRepository { fun insertUser(user: User) { // insert user } }
  • 45. object UserRepository { fun insertUser(user: User) { // insert user } } public class MyJavaClass { ... public void addUser() { UserRepository.INSTANCE.insertUser(new User("Nelson")); } }
  • 46. object UserRepository { @JvmStatic fun insertUser(user: User) { // insert user } } public class MyJavaClass { ... public void addUser() { UserRepository.INSTANCE.insertUser(new User("Nelson")); } }
  • 47. object UserRepository { @JvmStatic fun insertUser(user: User) { // insert user } } public class MyJavaClass { ... public void addUser() { UserRepository.insertUser(new User("Nelson")); } }
  • 48. class MyKotlinClass { fun printName(name: String = "Anonymous") { println("Hello $name!") } //... }
  • 49. class MyKotlinClass { fun printName(name: String = "Anonymous") { println("Hello $name!") } //... } MyKotlinClass instance = new MyKotlinClass(); instance.printName("Nelson"); // Works! instance.printName(); // Error!
  • 50. class MyKotlinClass { @JvmOverloads fun printName(name: String = "Anonymous") { println("Hello $name!") } //... }
  • 51. class MyKotlinClass { @JvmOverloads fun printName(name: String = "Anonymous") { println("Hello $name!") } //... } MyKotlinClass instance = new MyKotlinClass(); instance.printName("Nelson"); instance.printName();
  • 52. public class MyCustomView extends LinearLayout { public MyCustomView(Context context) { super(context); } public MyCustomView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); } public MyCustomView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } ... }
  • 53. class MyCustomView : LinearLayout { constructor(context: Context) : super(context) { } constructor(context: Context, attrs: AttributeSet? ) : super(context, attrs) { } constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int ) : super(context, attrs, defStyleAttr) { }
  • 54. class MyCustomView @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 ) : LinearLayout(context, attrs, defStyleAttr) { ... }
  • 55. class ToggleView { private var onOff = false fun switch() { onOff = !onOff } } ToggleView toggleView = new ToggleView(); toggleView.switch(); // error!
  • 56. class ToggleView { private var onOff = false @JvmName("switchOnOff") fun switch() { onOff = !onOff } } ToggleView toggleView = new ToggleView(); toggleView.switchOnOff();
  • 57. // StringsExtensions.kt package ngvl.kotlin.demo.string fun String.shouldCapitalizeName() = this !in listOf("da", "das", "de", "di", "do", "dos") fun String.capitalizeName() = this.split(" ") .joinToString(" ") { if (it.shouldCapitalizeName()) it.capitalize() else it } // Some Java file... String name = StringExtensionsKt.capitalizeName("nelson glauber");
  • 58. // StringsExtensions.kt @file:JvmName("StringExt") package ngvl.kotlin.demo.string fun String.shouldCapitalizeName() = this !in listOf("da", "das", "de", "di", "do", "dos") fun String.capitalizeName() = this.split(" ") .joinToString(" ") { if (it.shouldCapitalizeName()) it.capitalize() else it } // Some Java file... String name = StringExtensionsKt.capitalizeName("nelson glauber");
  • 59. // StringsExtensions.kt @file:JvmName("StringExt") package ngvl.kotlin.demo.string fun String.shouldCapitalizeName() = this !in listOf("da", "das", "de", "di", "do", "dos") fun String.capitalizeName() = this.split(" ") .joinToString(" ") { if (it.shouldCapitalizeName()) it.capitalize() else it } // Some Java file... String name = StringExt.capitalizeName("nelson glauber");
  • 60. data class Product( val id: String, val description: String, val price: Float = 0f ) Product product = new Product("001", "Smartphone", 0f); System.out.println( product.getId() +" - "+ product.getDescription() +" = "+ product.getPrice() );
  • 61. Product product = new Product("001", "Smartphone", 0f); System.out.println( product.getId() +" - "+ product.getDescription() +" = "+ product.getPrice() ); data class Product( @JvmField val id: String, @JvmField val description: String, @JvmField val price: Float = 0f )
  • 62. data class Product( @JvmField val id: String, @JvmField val description: String, @JvmField val price: Float = 0f ) Product product = new Product("001", "Smartphone", 0f); System.out.println( product.id +" - "+ product.description +" = "+ product.price );
  • 63. class MyKotlinClass { companion object { val CONSTANT_1 = 1 const val CONSTANT_2 = 2 @JvmField val CONSTANT_3 = 3 @JvmField val ROOT = User("root") } } MyKotlinClass.Companion.getCONSTANT_1(); MyKotlinClass.CONSTANT_2; MyKotlinClass.CONSTANT_3; MyKotlinClass.ROOT;
  • 64. object UserRepository { @JvmStatic fun insertUser(user: User) { if (user.name.length < 5) throw NameTooShortException() // insert user ... } } UserRepository.insertUser(new User("ngvl"));
  • 65. object UserRepository { @JvmStatic @Throws(NameTooShortException::class) fun insertUser(user: User) { if (user.name.length < 5) { throw NameTooShortException() } // insert user ... } } UserRepository.insertUser(new User("ngvl"));
  • 66. try { UserRepository.insertUser(new User("ngvl")); } catch (NameTooShortException e) { // handle name too short } object UserRepository { @JvmStatic @Throws(NameTooShortException::class) fun insertUser(user: User) { if (user.name.length < 5) { throw NameTooShortException() } // insert user ... } }
  • 67. data class Recipe( var name: String? = null, var ingredients: List<Ingredient> = mutableListOf() ) data class Ingredient( var description: String? = null, var quantity: Int = 0, var unity: String? = null )
  • 68. data class Recipe( var name: String? = null, var ingredients: List<Ingredient> = mutableListOf() ) data class Ingredient( var description: String? = null, var quantity: Int = 0, var unity: String? = null ) fun recipe(build: Recipe.() -> Unit) = Recipe().apply(build) fun Recipe.ingredient(build: Ingredient.() -> Unit) { ingredients += Ingredient().apply(build) } public inline fun <T> T.apply(block: T.() -> Unit): T { block() return this }
  • 69. fun recipe(build: Recipe.() -> Unit) = Recipe().apply(build) fun Recipe.ingredient(build: Ingredient.() -> Unit) { ingredients += Ingredient().apply(build) } val recipe = recipe { name = "Chocolate Cake" ingredient { name = "Flour" quantity = 3 unity = "cups" } } println(recipe) Recipe(name=Flour, ingredients=[ Ingredient(description=null, quantity=3, unity=cups)] ) 🤔
  • 70. data class Recipe( var name: String? = null, var ingredients: List<Ingredient> = mutableListOf() ) data class Ingredient( var description: String? = null, var quantity: Int = 0, var unity: String? = null ) fun recipe(build: Recipe.() -> Unit) = Recipe().apply(build) fun Recipe.ingredient(build: Ingredient.() -> Unit) { ingredients += Ingredient().apply(build) }
  • 71. @DslMarker annotation class RecipeLang @RecipeLang data class Recipe( var name: String? = null, var ingredients: List<Ingredient> = mutableListOf() ) @RecipeLang data class Ingredient( var description: String? = null, var quantity: Int = 0, var unity: String? = null ) fun recipe(build: Recipe.() -> Unit) = Recipe().apply(build) fun Recipe.ingredient(build: Ingredient.() -> Unit) { ingredients += Ingredient().apply(build) }
  • 72. val recipe = recipe { name = "Chocolate Cake" ingredient { name = "Flour" quantity = 3 unity = "cups" } } println(recipe) fun recipe(build: Recipe.() -> Unit) = Recipe().apply(build) fun Recipe.ingredient(build: Ingredient.() -> Unit) { ingredients += Ingredient().apply(build) } Compile error: 'var name: String?' can't be called in this context by implicit receiver. Use the explicit one if necessary
  • 73. val recipe = recipe { name = "Chocolate Cake" ingredient { this@recipe.name = "Choc.Cake" quantity = 3 unity = "cups" } } println(recipe) fun recipe(build: Recipe.() -> Unit) = Recipe().apply(build) fun Recipe.ingredient(build: Ingredient.() -> Unit) { ingredients += Ingredient().apply(build) }
  • 74. val recipe = recipe { name = "Chocolate Cake" ingredient { description = "Flour" quantity = 3 unity = "cups" } } println(recipe) fun recipe(build: Recipe.() -> Unit) = Recipe().apply(build) fun Recipe.ingredient(build: Ingredient.() -> Unit) { ingredients += Ingredient().apply(build) } Recipe(name=Chocolate Cake, ingredients=[ Ingredient(description=Flour, quantity=3, unity=cups)] ) 😋
  • 75. • @Deprecated and @Experimental help to document the evolution of your code • @Jvm* annotations help the integration with Java code. • @DslMarker create scopes for your DSLs. Annotations - Summary
  • 77. abstract class Individual( val name: String, val surname: String, val age: Int ) class Student( name: String, surname: String, age: Int, val university: String ) : Individual(name, surname, age) class Worker( name: String, surname: String, age: Int, val company: String ) : Individual(name, surname, age)
  • 78. abstract class Individual( val name: String, val surname: String, val age: Int ) class Student( name: String, surname: String, age: Int, val university: String ) : Individual(name, surname, age) class Worker( name: String, surname: String, age: Int, val company: String ) : Individual(name, surname, age)
  • 79. interface Individual { val name: String val surname: String val age: Int } data class IndividualData( override val name: String, override val surname: String, override val age: Int ) : Individual data class Student( val data: IndividualData, val university: String ) : Individual by data data class Worker( val data: IndividualData, val company: String ) : Individual by data
  • 80. interface Individual { val name: String val surname: String val age: Int } data class IndividualData( override val name: String, override val surname: String, override val age: Int ) : Individual data class Student( val data: IndividualData, val university: String ) : Individual by data data class Worker( val data: IndividualData, val company: String ) : Individual by data val student = Student( IndividualData("Nelson", "Leal", 36), "Universo" ) student.run { println("$name $surname - $age - $university") } Nelson Leal - 36 - Universo
  • 81. class Repository { private val peopleDAO: PeopleDAO by lazy { Database.getPeopleDAO() } fun insert(person: Person) { peopleDAO.add(person) } fun all(): List<Person> = peopleDAO.list() }
  • 82. class Repository { private val peopleDAO: PeopleDAO by lazy { Database.getPeopleDAO() } fun insert(person: Person) { peopleDAO.add(person) } fun all(): List<Person> = peopleDAO.list() }
  • 83. class Repository { private val peopleDAO: PeopleDAO by lazy { Database.getPeopleDAO() } fun insert(person: Person) { peopleDAO.add(person) } fun all(): List<Person> = peopleDAO.list() } val repo = Repository() repo.insert(Person("1", "Nelson")) repo.insert(Person("2", "Glauber")) repo.all().forEach(::printPerson)
  • 84. Delegates.vetoable(0) { // it's an inline function kprop, oldValue, newValue -> newValue in 0..122 // Jeanne Calmen }
  • 85. val ageDelegate = { Delegates.vetoable(0) { kprop, oldValue, newValue -> newValue in 0..122 } } if you don't use it as a function, it will return the last value for the new instance
  • 86. val ageDelegate = { Delegates.vetoable(0) { kprop, oldValue, newValue -> newValue in 0..122 } } class Person(val id: String, val name: String) { var age: Int by ageDelegate() }
  • 87. val ageDelegate = { Delegates.vetoable(0) { kprop, oldValue, newValue -> newValue in 0..122 } } class Person(val id: String, val name: String) { var age: Int by ageDelegate() } val p = Person("3", "Nelson") p.age = -1 printPerson(p) p.age = 150 printPerson(p) p.age = 35 printPerson(p) 3 - Nelson - 0 3 - Nelson - 0 3 - Nelson - 35
  • 88. interface OnFilterCallback { fun onFilterChanged(f: Filter) } class Filter { var minBathNum: Int = 0 var minPrice: Float = 0f private val callbacks = mutableSetOf<OnFilterCallback>() fun addOnFilterChangedCallback(callback: OnFilterCallback) { callbacks += callback } }
  • 89. class Filter { var minBathNum: Int = 0 var minPrice: Float = 0f private val callbacks = mutableSetOf<OnFilterCallback>() fun addOnFilterChangedCallback(callback: OnFilterCallback) { callbacks += callback } fun notifyObservers() { callbacks.forEach{ it.onFilterChanged(this) } } }
  • 90. class FilterDelegate<T>(initial: T) { var internal: T = initial operator fun getValue(thisRef: Filter, prop: KProperty<*>): T { return internal } operator fun setValue(thisRef: Filter, prop: KProperty<*>, value: T) { internal = value thisRef.notifyObservers() } }
  • 91. interface OnFilterCallback { fun onFilterChanged(f: Filter) } class Filter { var minBathNum: Int by FilterDelegate(0) var minPrice: Float by FilterDelegate(0f) private val callbacks = mutableSetOf<OnFilterCallback>() fun addOnFilterChangedCallback(callback: OnFilterCallback) { callbacks += callback } fun notifyObservers() { callbacks.forEach{ it.onFilterChanged(this) } } }
  • 92. val filter = Filter() filter.addOnFilterChangedCallback(object: OnFilterCallback { override fun onFilterChanged(f: Filter) { println("Observer #1") println("MinPrice: ${f.minPrice} - Baths:${f.minBathNum}") } }) filter.addOnFilterChangedCallback(object : OnFilterCallback { override fun onFilterChanged(f: Filter) { println("Observer #2") println("MinPrice: ${f.minPrice} - Baths:${f.minBathNum}") } }) filter.minBathNum = 2 filter.minPrice = 100_000f filter.minBathNum = 1 filter.minPrice = 10f Observer #1 | MinPrice: 0.0 - Baths:2 Observer #2 | MinPrice: 0.0 - Baths:2 Observer #1 | MinPrice: 100000.0 - Baths:2 Observer #2 | MinPrice: 100000.0 - Baths:2 Observer #1 | MinPrice: 100000.0 - Baths:1 Observer #2 | MinPrice: 100000.0 - Baths:1 Observer #1 | MinPrice: 10.0 - Baths:1 Observer #2 | MinPrice: 10.0 - Baths:1
  • 93. fun <T> Filter.filterDelegate(initialValue: T) = Delegates.observable(initialValue) { prop, oldValue, newValue -> println("old: $oldValue -> new: $newValue") this.notifyObservers() }
  • 94. fun <T> Filter.filterDelegate(initialValue: T) = Delegates.observable(initialValue) { prop, oldValue, newValue -> println("old: $oldValue -> new: $newValue") this.notifyObservers() } class Filter { var minBathNum: Int by filterDelegate(0) var minPrice: Float by filterDelegate(0f) ... }
  • 95. val filter = Filter() filter.addOnFilterChangedCallback(object: OnFilterCallback { override fun onFilterChanged(f: Filter) { println("Observer #1”) } }) filter.addOnFilterChangedCallback(object : OnFilterCallback { override fun onFilterChanged(f: Filter) { println("Observer #2") } }) filter.minBathNum = 2 filter.minPrice = 100_000f filter.minBathNum = 1 filter.minPrice = 10f old: 0 -> new: 2 Observer #1 Observer #2 old: 0.0 -> new: 100000.0 Observer #1 Observer #2 old: 2 -> new: 1 Observer #1 Observer #2 old: 100000.0 -> new: 10.0 Observer #1 Observer #2
  • 96. • Interface delegation for composition. • lazy for… lazy initialization. • vetoable to define a validation to be reused. • observable if you need both old and new value. • Custom delegates for everything else. Delegates - Summary
  • 97. • Std Lib has a lot of functions to help you to write a more simple, readable and concise code. • Check it out the lib internals. You’ll learn a lot! • Check it out the Kotlin Koans (https://play.kotlinlang.org/ koans). It’s a good place to start (or recap)! • Write Kotlin code, enjoy the std lib and have fun! 😉 Wrap up!
  • 98. • Kotlin Standard Functions
 https://medium.com/androiddevelopers/kotlin-standard-functions- cheat-sheet-27f032dd4326 • Mastering Kotlin standard functions: run, with, let, also and apply
 https://medium.com/@elye.project/mastering-kotlin-standard- functions-run-with-let-also-and-apply-9cd334b0ef84 • Java Friendly Kotlin
 https://codelabs.developers.google.com/codelabs/java-friendly-kotlin • Simpler Kotlin class hierarchies using class delegation
 https://proandroiddev.com/simpler-kotlin-class-hierarchies-using- class-delegation-35464106fed5 References