SlideShare a Scribd company logo
1 of 76
Download to read offline
First few months with otlin
Introduction through Android examples
Nebojša Vukšić
Nebojša Vukšić
Android developer @ codecentric
Founder of Kotlin User Group Serbia
Nesh_Wolf
nebojsa92vuksic@gmail.com
Kotlin User Group Serbia
https://www.meetup.com/Serbia-Kotlin-User-Group
https://www.facebook.com/kotlinserbia/
https://twitter.com/kotlin_serbia
What is Kotlin?
What is Kotlin?
● statically-typed object oriented programming language
● targeting JVM, Android and JavaScript
● fully interoperable with Java
● third party library
● has excellent IDE support
Kotlin history
● developed by JetBrains
● unveiled to public in 2011.(development started in 2012.)
● 1.0 first stable version (February 2016.)
● current version 1.1 RC
Why do we need Kotlin?
Problems that we have:
Why do we need Kotlin?
● Java
○ is too verbose
○ burden of previous versions
○ Null Pointer Exception
issues
○ util “hell”
● Android
○ we need inheritance for
almost everything
○ api ceremony
○ nullability
○ lack of Java 8 features
(lambdas, stream api,
method reference...)
Basics
Variables
val avenger: String = “Tony Stark” //constants
avenger = “Ultron” // compile error
var age : Int = 18 //variable
age = 20 // compiles since age is mutable
var number = 20 // Int type is inferred
Nullability
text.length // compiler error
var text: String? = null // This can be null or not-null
Nullability
var name: String = null // compile error
text?.length // compiles ⇔ if ( text != null) {
text.length // smart casted to not-nullable type
}
name.length // this is ok since type is not nullable
Nullability
val s: String? = "This can be null or not-null"
val length = s!!.length
Making NPE explicit
Nullability
val s: String? = "This can be null or not-null"
val length = s!!.length
Making NPE explicit
Functions
fun add(a: Int, b: Int): Int {
return a + b
}
Calling functions:
add(1, 3)
log(1, “Num is”)
//“Num is 1”
fun log(num: Int, msg: String): Unit {
println(“$msg $num”)
}
Functions
fun add(a: Int, b: Int): Int = a + b
fun log(num: Int, msg: String): Unit
= println(“$msg $num”)
Calling functions:
add(1, 3)
log(1, “Num is”)
//“Num is 1”
Functions
fun add(a: Int, b: Int) = a + b
fun log(num: Int, msg: String)
= println(“$msg $num”)
Calling functions:
add(1, 3)
log(1, “Num is”)
//“Num is 1”
Functions
fun add(a: Int = 0, b: Int = 0) = a + b
fun log(num: Int, msg: String = “Num is”)
= println(“$msg $num”)
add() //returns 0
add(1) //returns 1
add(b = 1) //returns 1
log(1) // “Num is 1”
log(msg = “Its ”, num = 2)
// “Its 2”
Functions
fun `should equal 4`() {
assertEquals(4, 2 + 2)
}
`should equal 4`()
Kotlin does classes differently...
Classes and data classes
@Override public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
if (age != user.age) return false;
if (!name.equals(user.name)) return false;
return email.equals(user.email);
}
@Override public int hashCode() {
int result = name.hashCode();
result = 31 * result + email.hashCode();
result = 31 * result + age;
return result;
}
}
class User {
private final String name;
private final String email;
private final int age;
User(String name, String email, int age) {
this.name = name;
this.email = email;
this.age = age;
}
public String getName() { return name; }
public String getEmail() { return email; }
public int getAge() { return age; }
@Override
public String toString() {
return "User{ name='" + name + ''' + ", email='" + email
+ ''' + ", age=" + age + '}';
}
Classes and data classes
@Override public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
if (age != user.age) return false;
if (!name.equals(user.name)) return false;
return email.equals(user.email);
}
@Override public int hashCode() {
int result = name.hashCode();
result = 31 * result + email.hashCode();
result = 31 * result + age;
return result;
}
}
class User {
private final String name;
private final String email;
private final int age;
User(String name, String email, int age) {
this.name = name;
this.email = email;
this.age = age;
}
public String getName() { return name; }
public String getEmail() { return email; }
public int getAge() { return age; }
@Override
public String toString() {
return "User{ name='" + name + ''' + ", email='" + email
+ ''' + ", age=" + age + '}';
}
Classes and data classes
@Override public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
if (age != user.age) return false;
if (!name.equals(user.name)) return false;
return email.equals(user.email);
}
@Override public int hashCode() {
int result = name.hashCode();
result = 31 * result + email.hashCode();
result = 31 * result + age;
return result;
}
class User (
val name: String,
val email: String,
val age: Int
)
@Override
public String toString() {
return "User{ name='" + name + ''' + ", email='" + email
+ ''' + ", age=" + age + '}';
}
Classes and data classes
data class User (
val name: String,
val email: String,
val age: Int
)
val user = User("John Smith", "johnsmith@mail.com", 24)
val newUser = user.copy(name = "Sam")
//newUser == User("Sam", "johnsmith@mail.com", 24)
val (name, email, age) = newUser
Data classes
data class User (
val name: String = "John Smith",
val email: String = "johnsmith@mail.com",
val age: Int = 24
)
val user = User ()
// user == User("John Smith", "johnsmith@mail.com", 24)
Classes and data classes
data class User( val name: String, val email: String, val age: Int)
● Kotlin classes are final by default
● we need to annotate class as open, if we want to inherit them
● data classes can’t be inherited
class limitations:
Classes and data classes
open class User( val name: String, val email: String, val age: Int)
● Kotlin classes are final by default
● we need to annotate class as open, if we want to inherit them
● data classes can’t be inherited
class limitations:
Extension functions and properties
Extension functions
fun String.swapSpacesForUnderscore(): String = this.replace(" ", "_")
"This is random message!".swapSpacesForUnderscore()
// returns "This_is_random_message!"
Compiles to:
public static final String swapSpacesForUnderscore(@NotNull String $receiver) {
Intrinsics.checkParameterIsNotNull($receiver, "$receiver");
return $receiver.replace(," ", "_");
}
Extension functions
package com.app.android.util
fun String.swapSpacesForUnderscore(): String = this.replace(" ", "_")
package com.app.android.main
"Random text!".swapSpacesForUnderscore()
Extension functions
package com.app.android.util
fun String.swapSpacesForUnderscore(): String = this.replace(" ", "_")
package com.app.android.main
import com.app.android.util.swapSpacesForUnderscore
"Random text!".swapSpacesForUnderscore()
Extension properties
val Array<String>.lastElement: String get() = this[size - 1]
val names: Array<String> = arrayOf("John", "Will", "Emma", "Peter")
val name = names.lastElement //returns "Peter"
Compiles to:
public static final String getLastElement(@NotNull String[] $receiver) {
Intrinsics.checkParameterIsNotNull($receiver, "$receiver");
return $receiver[$receiver.length - 1];
}
Extension properties
val <T> Array<T>.lastElement: T get() = this[size - 1]
val names: Array<String> = arrayOf("John", "Will", "Emma", "Peter")
val name = names.lastElement //returns "Peter"
Compiles to:
public static final Object getLastElement(@NotNull Object[] $receiver) {
Intrinsics.checkParameterIsNotNull($receiver, "$receiver");
return $receiver[$receiver.length - 1];
}
Extension properties
val <T> Array<T>.lastElement: T get() = this[size - 1]
val nums: Array<Int> = arrayOf(1, 2, 3, 4)
val num = nums.lastElement //returns 4
Compiles to:
public static final Object getLastElement(@NotNull Object[] $receiver) {
Intrinsics.checkParameterIsNotNull($receiver, "$receiver");
return $receiver[$receiver.length - 1];
}
Android extensions plugin
no more findViewById()
Android extensions plugin
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val toolbar: Toolbar = findViewById(R.id.toolbar) as Toolbar
setSupportActionBar(toolbar)
val fab: FloatingActionButton = findViewById(R.id.fab) as FloatingActionButton
fab.setOnClickListener { Toast.makeText(this, "Hello!", Toast.LENGTH_SHORT).show() }
}
}
Android extensions plugin
class MainActivity : AppCompatActivity() {
@BindView(R.id.toolbar) Toolbar toolbar;
@BindView(R.id.fab) FloatingActionButton fab;
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
ButterKnife.bind(this)
setSupportActionBar(toolbar)
fab.setOnClickListener { Toast.makeText(this, "Hello!", Toast.LENGTH_SHORT).show() }
}
}
Android extensions plugin
import kotlinx.android.synthetic.main.activity_main.toolbar
import kotlinx.android.synthetic.main.activity_main.fab
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setSupportActionBar(toolbar)
fab.setOnClickListener { Toast.makeText(this, "Hello!", Toast.LENGTH_SHORT).show() }
}
}
Android extensions plugin
import kotlinx.android.synthetic.main.activity_main.toolbar
import kotlinx.android.synthetic.main.activity_main.fab
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setSupportActionBar(toolbar)
fab.setOnClickListener { Toast.makeText(this, "Hello!", Toast.LENGTH_SHORT).show() }
}
}
Android extensions plugin
import kotlinx.android.synthetic.main.activity_main.toolbar
import kotlinx.android.synthetic.main.activity_main.loging_btn_registration_fragment
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setSupportActionBar(toolbar)
loging_btn_registration_fragment.setOnClickListener { Toast.makeText(this, "Hello!",
Toast.LENGTH_SHORT).show() }
}
}
Android extensions plugin
import kotlinx.android.synthetic.main.activity_main.toolbar
import kotlinx.android.synthetic.main.activity_main.loging_btn_registration_fragment as login
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setSupportActionBar(toolbar)
login.setOnClickListener { Toast.makeText(this, "Hello!", Toast.LENGTH_SHORT).show()}
}
}
Function expressions
Function expressions
val add: (Int, Int) -> Int = { x,y -> x+y }
add(1,2)
val validator: (String) -> Boolean ={ value -> value.contains("@") }
validator("john@mail.com")
● function expressions are blocks of code which we can
instantiate(represent as type)
Function expressions
val add: (Int, Int) -> Int = { x,y -> x+y }
add(1,2)
● function expressions are blocks of code which we can
instantiate(represent as type)
val validator: (String) -> Boolean ={ it.contains("@") }
validator("john@mail.com")
Function expressions
val add: (Int, Int) -> Int = { x,y -> x+y }
add(1,2)
val validator: (String) -> Boolean ={ it.contains("@") }
validator("john@mail.com")
mailTextview.validateWith{ validator("john@mail.com") }
● function expressions are blocks of code which we can
instantiate(represent as type)
Higher order functions
Higher order functions
fun <T> List<T>.filter(predicate: (T) -> Boolean): List<T>{
}
Higher order functions
fun <T> List<T>.filter(predicate: (T) -> Boolean): List<T>{
val items = ArrayList<T>()
return items
}
Higher order functions
fun <T> List<T>.filter(predicate: (T) -> Boolean): List<T>{
val items = ArrayList<T>()
for (item in this) {
}
return items
}
Higher order functions
fun <T> List<T>.filter(predicate: (T) -> Boolean): List<T>{
val items = ArrayList<T>()
for (item in this) {
if (predicate(item)) {
items.add(item)
}
}
return items
}
val cars = listOf("BMW", "Fiat", "Mercedes", "KIA", "Ford")
val filteredCars = cars.filter ({ it.startsWith("F") })
// filteredCars == listOf("Fiat", "Ford")
Higher order functions
fun <T> List<T>.filter(predicate: (T) -> Boolean): List<T>{
val items = ArrayList<T>()
for (item in this) {
if (predicate(item)) {
items.add(item)
}
}
return items
}
val cars = listOf("BMW", "Fiat", "Mercedes", "KIA", "Ford")
val filteredCars = cars.filter { it.startsWith("F") }
// filteredCars == listOf("Fiat", "Ford")
Quick overview
still not over
Quick overview
● Extension functions - adds functionality to types
without overriding existing methods
● Function expressions - undeclared function body used
as an expression
● Higher order function - function that accepts function or
returns function
Combination of this three makes
powerful combo
fun saveUser(user: User) {
val editor = sharedPref.edit()
editor.putString(ACCESS_TOKEN, user.token)
editor.putString(USER_EMAIL, user.email)
editor.commit()
}
Extension / Higher order function expression combo
fun SharedPreferences.edit(editor : SharedPreferences.Editor, func: () -> Unit) {
func()
editor.commit()
}
Extension / Higher order function expression combo
fun saveUser(user: User) {
val editor = sharedPref.edit()
sharedPref.edit(editor) {
editor.putString(ACCESS_TOKEN, user.token)
editor.putString(USER_EMAIL, user.email)
}
}
fun SharedPreferences.edit(editor : SharedPreferences.Editor, func: () -> Unit) {
func()
editor.commit()
}
fun saveUser(user: User) {
val editor = sharedPref.edit()
sharedPref.edit(editor) {
editor.putString(ACCESS_TOKEN, user.token)
editor.putString(USER_EMAIL, user.email)
}
}
Extension / Higher order function expression combo
fun SharedPreferences.edit(editor : SharedPreferences.Editor, func: () -> Unit) {
func()
editor.commit()
}
fun saveUser(user: User) {
sharedPref.edit {
editor.putString(ACCESS_TOKEN, user.token)
editor.putString(USER_EMAIL, user.email)
}
}
Extension / Higher order function expression combo
fun SharedPreferences.edit(func: () -> Unit) {
val editor = edit()
func()
editor.commit()
}
fun saveUser(user: User) {
sharedPref.edit {
it.putString(ACCESS_TOKEN, user.token)
it.putString(USER_EMAIL, user.email)
}
}
Extension / Higher order function expression combo
fun SharedPreferences.edit(func: (SharedPreferences.Editor) -> Unit) {
val editor = edit()
func(editor)
editor.commit()
}
fun saveUser(user: User) {
sharedPref.edit {
it.putString(ACCESS_TOKEN, user.token)
it.putString(USER_EMAIL, user.email)
}
}
Extension / Higher order function expression combo
fun SharedPreferences.edit(func: (SharedPreferences.Editor) -> Unit) {
val editor = edit()
func(editor)
editor.commit()
}
fun saveUser(user: User) {
sharedPref.edit {
it.putString(ACCESS_TOKEN, user.token)
it.putString(USER_EMAIL, user.email)
}
}
Extension / Higher order function expression combo
fun SharedPreferences.edit(func: SharedPreferences.Editor.() -> Unit)) {
val editor = edit()
func(editor)
editor.commit()
}
fun saveUser(user: User) {
sharedPref.edit {
it.putString(ACCESS_TOKEN, user.token)
it.putString(USER_EMAIL, user.email)
}
}
Extension / Higher order function expression combo
fun SharedPreferences.edit(func: SharedPreferences.Editor.() -> Unit)) {
val editor = edit()
editor.func()
editor.commit()
}
fun saveUser(user: User) {
sharedPref.edit {
putString(ACCESS_TOKEN, user.token)
putString(USER_EMAIL, user.email)
}
}
Extension / Higher order function expression combo
fun SharedPreferences.edit(func: SharedPreferences.Editor.() -> Unit) {
val editor = edit()
editor.func()
editor.commit()
}
Extension / Higher order function expression combo
fun SharedPreferences.Editor.put(pair: Pair<String, Any>) {
val key = pair.first
val value = pair.second
when(value) {
is String -> putString(key, value)
is Int -> putInt(key, value)
is Boolean -> putBoolean(key, value)
is Float -> putFloat(key, value)
is Long -> putLong(key, value)
else -> error(“Only primitive types are supported”)
}
}
fun saveUser(user: User) {
sharedPref.edit {
putString(ACCESS_TOKEN, user.token)
putString(USER_EMAIL, user.email)
}
}
Extension / Higher order function expression combo
fun SharedPreferences.edit(func: SharedPreferences.Editor.() -> Unit)) {
val editor = edit()
editor.func()
editor.commit()
}
Extension / Higher order function expression combo
fun saveUser(user: User) {
sharedPref.edit {
put(Pair(ACCESS_TOKEN, user.token))
put(Pair(USER_EMAIL, user.email))
}
}
fun SharedPreferences.edit(func: SharedPreferences.Editor.() -> Unit) {
val editor = edit()
editor.func()
editor.commit()
}
fun saveUser(user: User) {
sharedPref.edit {
put(ACCESS_TOKEN to user.token)
put(USER_EMAIL to user.email)
}
}
Extension / Higher order function expression combo
fun SharedPreferences.edit(func: SharedPreferences.Editor.() -> Unit) {
val editor = edit()
editor.func()
editor.commit()
}
fun saveUser(user: User) {
sharedPref.edit {
put(ACCESS_TOKEN to user.token)
put(USER_EMAIL to user.email)
}
}
Extension / Higher order function expression combo
fun SharedPreferences.edit(func: SharedPreferences.Editor.() -> Unit) {
val editor = edit()
editor.func()
editor.commit()
}
public infix fun <A, B> A.to(that: B): Pair<A, B> = Pair(this, that)
fun saveUser(user: User) {
sharedPref.edit {
put(ACCESS_TOKEN to user.token)
put(USER_EMAIL to user.email)
}
}
Extension / Higher order function expression combo
inline fun SharedPreferences.edit(func: SharedPreferences.Editor.() -> Unit) {
val editor = edit()
editor.func()
editor.commit()
}
Extension / Higher order function expression combo
From this:
fun saveUser(user: User) {
val editor = sharedPref.edit()
editor.putString(ACCESS_TOKEN, user.token)
editor.putString(USER_EMAIL, user.email)
editor.commit()
}
To this:
inline fun saveUser(user: User) {
sharedPref.edit {
put(ACCESS_TOKEN to user.token)
put(USER_EMAIL to user.email)
}
}
Summary
don’t worry, next slide is the last
Summary
● immutable and mutable variables
● nullability
● functions(default values and named arguments)
● classes and data classes
● extension functions and properties
● function expression
● higher order functions
● ultra mega giga combo of three above concepts
● use inline modifier
Resources
● Official Kotlin documentation
● Official Kotlin Github
● Anko
● Kotlin koans
● Awesome Kotlin – collection of materials
● Slack kanal
● Design patterns in Kotlin
● Keddit - demo app
● Kotlin For Android (at DevFest İzmir 2016)
● Kotlin – Ready for Production – Hadi Hariri
● Android development with Kotlin – Jake Wharton
Questions?.Answers!!
Nebojša Vukšić
Android developer @ codecentric
Founder of Kotlin User Group Serbia
Nesh_Wolf
nebojsa92vuksic@gmail.com
Kotlin User Group Serbia
https://www.meetup.com/Serbia-Kotlin-User-Group
https://www.facebook.com/kotlinserbia/
https://twitter.com/kotlin_serbia

More Related Content

What's hot

Scala - en bedre og mere effektiv Java?
Scala - en bedre og mere effektiv Java?Scala - en bedre og mere effektiv Java?
Scala - en bedre og mere effektiv Java?Jesper Kamstrup Linnet
 
Poor Man's Functional Programming
Poor Man's Functional ProgrammingPoor Man's Functional Programming
Poor Man's Functional ProgrammingDmitry Buzdin
 
かとうの Kotlin 講座 こってり版
かとうの Kotlin 講座 こってり版かとうの Kotlin 講座 こってり版
かとうの Kotlin 講座 こってり版Yutaka Kato
 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with ClojureDmitry Buzdin
 
Kotlin for Android Developers - Victor Kropp - Codemotion Rome 2018
Kotlin for Android Developers - Victor Kropp - Codemotion Rome 2018Kotlin for Android Developers - Victor Kropp - Codemotion Rome 2018
Kotlin for Android Developers - Victor Kropp - Codemotion Rome 2018Codemotion
 
Kotlin Austin Droids April 14 2016
Kotlin Austin Droids April 14 2016Kotlin Austin Droids April 14 2016
Kotlin Austin Droids April 14 2016DesertJames
 
TDC218SP | Trilha Kotlin - DSLs in a Kotlin Way
TDC218SP | Trilha Kotlin - DSLs in a Kotlin WayTDC218SP | Trilha Kotlin - DSLs in a Kotlin Way
TDC218SP | Trilha Kotlin - DSLs in a Kotlin Waytdc-globalcode
 
G3 Summit 2016 - Taking Advantage of Groovy Annotations
G3 Summit 2016 - Taking Advantage of Groovy AnnotationsG3 Summit 2016 - Taking Advantage of Groovy Annotations
G3 Summit 2016 - Taking Advantage of Groovy AnnotationsIván López Martín
 
7 Habits For a More Functional Swift
7 Habits For a More Functional Swift7 Habits For a More Functional Swift
7 Habits For a More Functional SwiftJason Larsen
 
Clojure: The Art of Abstraction
Clojure: The Art of AbstractionClojure: The Art of Abstraction
Clojure: The Art of AbstractionAlex Miller
 
Madrid gug - sacando partido a las transformaciones ast de groovy
Madrid gug - sacando partido a las transformaciones ast de groovyMadrid gug - sacando partido a las transformaciones ast de groovy
Madrid gug - sacando partido a las transformaciones ast de groovyIván López Martín
 
Python data structures
Python data structuresPython data structures
Python data structureskalyanibedekar
 
Java programs
Java programsJava programs
Java programsjojeph
 
Functional streams with Kafka - A comparison between Akka-streams and FS2
Functional streams with Kafka - A comparison between Akka-streams and FS2Functional streams with Kafka - A comparison between Akka-streams and FS2
Functional streams with Kafka - A comparison between Akka-streams and FS2Luis Miguel Reis
 
An Introduction to Scala (2014)
An Introduction to Scala (2014)An Introduction to Scala (2014)
An Introduction to Scala (2014)William Narmontas
 
Stream-based Data Synchronization
Stream-based Data SynchronizationStream-based Data Synchronization
Stream-based Data SynchronizationKlemen Verdnik
 

What's hot (20)

Scala - en bedre og mere effektiv Java?
Scala - en bedre og mere effektiv Java?Scala - en bedre og mere effektiv Java?
Scala - en bedre og mere effektiv Java?
 
Poor Man's Functional Programming
Poor Man's Functional ProgrammingPoor Man's Functional Programming
Poor Man's Functional Programming
 
かとうの Kotlin 講座 こってり版
かとうの Kotlin 講座 こってり版かとうの Kotlin 講座 こってり版
かとうの Kotlin 講座 こってり版
 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with Clojure
 
Kotlin for Android Developers - Victor Kropp - Codemotion Rome 2018
Kotlin for Android Developers - Victor Kropp - Codemotion Rome 2018Kotlin for Android Developers - Victor Kropp - Codemotion Rome 2018
Kotlin for Android Developers - Victor Kropp - Codemotion Rome 2018
 
Ggplot2 v3
Ggplot2 v3Ggplot2 v3
Ggplot2 v3
 
Kotlin Austin Droids April 14 2016
Kotlin Austin Droids April 14 2016Kotlin Austin Droids April 14 2016
Kotlin Austin Droids April 14 2016
 
TDC218SP | Trilha Kotlin - DSLs in a Kotlin Way
TDC218SP | Trilha Kotlin - DSLs in a Kotlin WayTDC218SP | Trilha Kotlin - DSLs in a Kotlin Way
TDC218SP | Trilha Kotlin - DSLs in a Kotlin Way
 
G3 Summit 2016 - Taking Advantage of Groovy Annotations
G3 Summit 2016 - Taking Advantage of Groovy AnnotationsG3 Summit 2016 - Taking Advantage of Groovy Annotations
G3 Summit 2016 - Taking Advantage of Groovy Annotations
 
7 Habits For a More Functional Swift
7 Habits For a More Functional Swift7 Habits For a More Functional Swift
7 Habits For a More Functional Swift
 
Clojure: The Art of Abstraction
Clojure: The Art of AbstractionClojure: The Art of Abstraction
Clojure: The Art of Abstraction
 
Hammurabi
HammurabiHammurabi
Hammurabi
 
Madrid gug - sacando partido a las transformaciones ast de groovy
Madrid gug - sacando partido a las transformaciones ast de groovyMadrid gug - sacando partido a las transformaciones ast de groovy
Madrid gug - sacando partido a las transformaciones ast de groovy
 
Python Training
Python TrainingPython Training
Python Training
 
Python data structures
Python data structuresPython data structures
Python data structures
 
Functional Scala 2020
Functional Scala 2020Functional Scala 2020
Functional Scala 2020
 
Java programs
Java programsJava programs
Java programs
 
Functional streams with Kafka - A comparison between Akka-streams and FS2
Functional streams with Kafka - A comparison between Akka-streams and FS2Functional streams with Kafka - A comparison between Akka-streams and FS2
Functional streams with Kafka - A comparison between Akka-streams and FS2
 
An Introduction to Scala (2014)
An Introduction to Scala (2014)An Introduction to Scala (2014)
An Introduction to Scala (2014)
 
Stream-based Data Synchronization
Stream-based Data SynchronizationStream-based Data Synchronization
Stream-based Data Synchronization
 

Viewers also liked

手把手帶你學Docker 03042017
手把手帶你學Docker 03042017手把手帶你學Docker 03042017
手把手帶你學Docker 03042017Paul Chao
 
Концепція відкритих даних. Важливість якісного збору та публікації даних.
Концепція відкритих даних. Важливість якісного збору та публікації даних. Концепція відкритих даних. Важливість якісного збору та публікації даних.
Концепція відкритих даних. Важливість якісного збору та публікації даних. Andriy Gorbal
 
Kotlin For Android (at DevFest İzmir 2016)
Kotlin For Android (at DevFest İzmir 2016)Kotlin For Android (at DevFest İzmir 2016)
Kotlin For Android (at DevFest İzmir 2016)Semih Bozdemir
 
Android & Kotlin - The code awakens #03
Android & Kotlin - The code awakens #03Android & Kotlin - The code awakens #03
Android & Kotlin - The code awakens #03Omar Miatello
 
Android & Kotlin - The code awakens #01
Android & Kotlin - The code awakens #01Android & Kotlin - The code awakens #01
Android & Kotlin - The code awakens #01Omar Miatello
 
Exploring Anko Components, Kotlin, Android
Exploring Anko Components, Kotlin, AndroidExploring Anko Components, Kotlin, Android
Exploring Anko Components, Kotlin, AndroidRakshak R.Hegde
 
Smoothing Your Java with DSLs
Smoothing Your Java with DSLsSmoothing Your Java with DSLs
Smoothing Your Java with DSLsintelliyole
 
Getting started-kotlin-android
Getting started-kotlin-androidGetting started-kotlin-android
Getting started-kotlin-androidLucas Albuquerque
 
No excuses, switch to kotlin
No excuses, switch to kotlinNo excuses, switch to kotlin
No excuses, switch to kotlinThijs Suijten
 
RxJava - Programação assíncrona para Android.
RxJava - Programação assíncrona para Android.RxJava - Programação assíncrona para Android.
RxJava - Programação assíncrona para Android.Clerton Leal
 
Little Helpers for Android Development with Kotlin
Little Helpers for Android Development with KotlinLittle Helpers for Android Development with Kotlin
Little Helpers for Android Development with KotlinKai Koenig
 
Kotlin, smarter development for the jvm
Kotlin, smarter development for the jvmKotlin, smarter development for the jvm
Kotlin, smarter development for the jvmArnaud Giuliani
 
Kotlin in action
Kotlin in actionKotlin in action
Kotlin in actionCiro Rizzo
 
Kotlin for Android - Vali Iorgu - mRready
Kotlin for Android - Vali Iorgu - mRreadyKotlin for Android - Vali Iorgu - mRready
Kotlin for Android - Vali Iorgu - mRreadyMobileAcademy
 
Building web apps with vaadin 8
Building web apps with vaadin 8Building web apps with vaadin 8
Building web apps with vaadin 8Marcus Hellberg
 
Vaadin 8 with Spring Frameworks AutoConfiguration
Vaadin 8 with Spring Frameworks AutoConfigurationVaadin 8 with Spring Frameworks AutoConfiguration
Vaadin 8 with Spring Frameworks AutoConfigurationPeter Lehto
 

Viewers also liked (20)

手把手帶你學Docker 03042017
手把手帶你學Docker 03042017手把手帶你學Docker 03042017
手把手帶你學Docker 03042017
 
Концепція відкритих даних. Важливість якісного збору та публікації даних.
Концепція відкритих даних. Важливість якісного збору та публікації даних. Концепція відкритих даних. Важливість якісного збору та публікації даних.
Концепція відкритих даних. Важливість якісного збору та публікації даних.
 
Kotlin For Android (at DevFest İzmir 2016)
Kotlin For Android (at DevFest İzmir 2016)Kotlin For Android (at DevFest İzmir 2016)
Kotlin For Android (at DevFest İzmir 2016)
 
Kotlin на практике
Kotlin на практикеKotlin на практике
Kotlin на практике
 
Android & Kotlin - The code awakens #03
Android & Kotlin - The code awakens #03Android & Kotlin - The code awakens #03
Android & Kotlin - The code awakens #03
 
Android & Kotlin - The code awakens #01
Android & Kotlin - The code awakens #01Android & Kotlin - The code awakens #01
Android & Kotlin - The code awakens #01
 
Exploring Anko Components, Kotlin, Android
Exploring Anko Components, Kotlin, AndroidExploring Anko Components, Kotlin, Android
Exploring Anko Components, Kotlin, Android
 
Smoothing Your Java with DSLs
Smoothing Your Java with DSLsSmoothing Your Java with DSLs
Smoothing Your Java with DSLs
 
Getting started-kotlin-android
Getting started-kotlin-androidGetting started-kotlin-android
Getting started-kotlin-android
 
No excuses, switch to kotlin
No excuses, switch to kotlinNo excuses, switch to kotlin
No excuses, switch to kotlin
 
RxJava - Programação assíncrona para Android.
RxJava - Programação assíncrona para Android.RxJava - Programação assíncrona para Android.
RxJava - Programação assíncrona para Android.
 
Little Helpers for Android Development with Kotlin
Little Helpers for Android Development with KotlinLittle Helpers for Android Development with Kotlin
Little Helpers for Android Development with Kotlin
 
Android Workshop
Android WorkshopAndroid Workshop
Android Workshop
 
Kotlin, smarter development for the jvm
Kotlin, smarter development for the jvmKotlin, smarter development for the jvm
Kotlin, smarter development for the jvm
 
Kotlin in action
Kotlin in actionKotlin in action
Kotlin in action
 
Kotlin for Android - Vali Iorgu - mRready
Kotlin for Android - Vali Iorgu - mRreadyKotlin for Android - Vali Iorgu - mRready
Kotlin for Android - Vali Iorgu - mRready
 
Building web apps with vaadin 8
Building web apps with vaadin 8Building web apps with vaadin 8
Building web apps with vaadin 8
 
Mob Testing
Mob TestingMob Testing
Mob Testing
 
Vaadin 8 with Spring Frameworks AutoConfiguration
Vaadin 8 with Spring Frameworks AutoConfigurationVaadin 8 with Spring Frameworks AutoConfiguration
Vaadin 8 with Spring Frameworks AutoConfiguration
 
The Awesomeness of Go
The Awesomeness of GoThe Awesomeness of Go
The Awesomeness of Go
 

Similar to First few months with Kotlin through Android examples

pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfHiroshi Ono
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfHiroshi Ono
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfHiroshi Ono
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfHiroshi Ono
 
Meetup di GDG Italia - Leonardo Pirro - Codemotion Rome 2018
Meetup di GDG Italia - Leonardo Pirro -  Codemotion Rome 2018 Meetup di GDG Italia - Leonardo Pirro -  Codemotion Rome 2018
Meetup di GDG Italia - Leonardo Pirro - Codemotion Rome 2018 Codemotion
 
Privet Kotlin (Windy City DevFest)
Privet Kotlin (Windy City DevFest)Privet Kotlin (Windy City DevFest)
Privet Kotlin (Windy City DevFest)Cody Engel
 
Persisting Data on SQLite using Room
Persisting Data on SQLite using RoomPersisting Data on SQLite using Room
Persisting Data on SQLite using RoomNelson Glauber Leal
 
TypeScript Introduction
TypeScript IntroductionTypeScript Introduction
TypeScript IntroductionHans Höchtl
 
Kotlin Data Model
Kotlin Data ModelKotlin Data Model
Kotlin Data ModelKros Huang
 
Go ahead, make my day
Go ahead, make my dayGo ahead, make my day
Go ahead, make my dayTor Ivry
 
No excuses, switch to kotlin
No excuses, switch to kotlinNo excuses, switch to kotlin
No excuses, switch to kotlinThijs Suijten
 
Kotlin for Android Developers - 3
Kotlin for Android Developers - 3Kotlin for Android Developers - 3
Kotlin for Android Developers - 3Mohamed Nabil, MSc.
 
The Ring programming language version 1.5.2 book - Part 14 of 181
The Ring programming language version 1.5.2 book - Part 14 of 181The Ring programming language version 1.5.2 book - Part 14 of 181
The Ring programming language version 1.5.2 book - Part 14 of 181Mahmoud Samir Fayed
 
Scala Quick Introduction
Scala Quick IntroductionScala Quick Introduction
Scala Quick IntroductionDamian Jureczko
 
Object Oriented Solved Practice Programs C++ Exams
Object Oriented Solved Practice Programs C++ ExamsObject Oriented Solved Practice Programs C++ Exams
Object Oriented Solved Practice Programs C++ ExamsMuhammadTalha436
 
Kotlin Basics - Apalon Kotlin Sprint Part 2
Kotlin Basics - Apalon Kotlin Sprint Part 2Kotlin Basics - Apalon Kotlin Sprint Part 2
Kotlin Basics - Apalon Kotlin Sprint Part 2Kirill Rozov
 

Similar to First few months with Kotlin through Android examples (20)

pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
 
Meetup di GDG Italia - Leonardo Pirro - Codemotion Rome 2018
Meetup di GDG Italia - Leonardo Pirro -  Codemotion Rome 2018 Meetup di GDG Italia - Leonardo Pirro -  Codemotion Rome 2018
Meetup di GDG Italia - Leonardo Pirro - Codemotion Rome 2018
 
Scala introduction
Scala introductionScala introduction
Scala introduction
 
Privet Kotlin (Windy City DevFest)
Privet Kotlin (Windy City DevFest)Privet Kotlin (Windy City DevFest)
Privet Kotlin (Windy City DevFest)
 
Persisting Data on SQLite using Room
Persisting Data on SQLite using RoomPersisting Data on SQLite using Room
Persisting Data on SQLite using Room
 
TypeScript Introduction
TypeScript IntroductionTypeScript Introduction
TypeScript Introduction
 
Kotlin Data Model
Kotlin Data ModelKotlin Data Model
Kotlin Data Model
 
Go ahead, make my day
Go ahead, make my dayGo ahead, make my day
Go ahead, make my day
 
Introduction kot iin
Introduction kot iinIntroduction kot iin
Introduction kot iin
 
Scala 2 + 2 > 4
Scala 2 + 2 > 4Scala 2 + 2 > 4
Scala 2 + 2 > 4
 
No excuses, switch to kotlin
No excuses, switch to kotlinNo excuses, switch to kotlin
No excuses, switch to kotlin
 
Kotlin for Android Developers - 3
Kotlin for Android Developers - 3Kotlin for Android Developers - 3
Kotlin for Android Developers - 3
 
The Ring programming language version 1.5.2 book - Part 14 of 181
The Ring programming language version 1.5.2 book - Part 14 of 181The Ring programming language version 1.5.2 book - Part 14 of 181
The Ring programming language version 1.5.2 book - Part 14 of 181
 
Scala Quick Introduction
Scala Quick IntroductionScala Quick Introduction
Scala Quick Introduction
 
Object Oriented Solved Practice Programs C++ Exams
Object Oriented Solved Practice Programs C++ ExamsObject Oriented Solved Practice Programs C++ Exams
Object Oriented Solved Practice Programs C++ Exams
 
Kotlin Basics - Apalon Kotlin Sprint Part 2
Kotlin Basics - Apalon Kotlin Sprint Part 2Kotlin Basics - Apalon Kotlin Sprint Part 2
Kotlin Basics - Apalon Kotlin Sprint Part 2
 
TechTalk - Dotnet
TechTalk - DotnetTechTalk - Dotnet
TechTalk - Dotnet
 

Recently uploaded

Arihant handbook biology for class 11 .pdf
Arihant handbook biology for class 11 .pdfArihant handbook biology for class 11 .pdf
Arihant handbook biology for class 11 .pdfchloefrazer622
 
Introduction to Nonprofit Accounting: The Basics
Introduction to Nonprofit Accounting: The BasicsIntroduction to Nonprofit Accounting: The Basics
Introduction to Nonprofit Accounting: The BasicsTechSoup
 
Z Score,T Score, Percential Rank and Box Plot Graph
Z Score,T Score, Percential Rank and Box Plot GraphZ Score,T Score, Percential Rank and Box Plot Graph
Z Score,T Score, Percential Rank and Box Plot GraphThiyagu K
 
APM Welcome, APM North West Network Conference, Synergies Across Sectors
APM Welcome, APM North West Network Conference, Synergies Across SectorsAPM Welcome, APM North West Network Conference, Synergies Across Sectors
APM Welcome, APM North West Network Conference, Synergies Across SectorsAssociation for Project Management
 
Paris 2024 Olympic Geographies - an activity
Paris 2024 Olympic Geographies - an activityParis 2024 Olympic Geographies - an activity
Paris 2024 Olympic Geographies - an activityGeoBlogs
 
1029 - Danh muc Sach Giao Khoa 10 . pdf
1029 -  Danh muc Sach Giao Khoa 10 . pdf1029 -  Danh muc Sach Giao Khoa 10 . pdf
1029 - Danh muc Sach Giao Khoa 10 . pdfQucHHunhnh
 
Student login on Anyboli platform.helpin
Student login on Anyboli platform.helpinStudent login on Anyboli platform.helpin
Student login on Anyboli platform.helpinRaunakKeshri1
 
A Critique of the Proposed National Education Policy Reform
A Critique of the Proposed National Education Policy ReformA Critique of the Proposed National Education Policy Reform
A Critique of the Proposed National Education Policy ReformChameera Dedduwage
 
Unit-IV- Pharma. Marketing Channels.pptx
Unit-IV- Pharma. Marketing Channels.pptxUnit-IV- Pharma. Marketing Channels.pptx
Unit-IV- Pharma. Marketing Channels.pptxVishalSingh1417
 
Key note speaker Neum_Admir Softic_ENG.pdf
Key note speaker Neum_Admir Softic_ENG.pdfKey note speaker Neum_Admir Softic_ENG.pdf
Key note speaker Neum_Admir Softic_ENG.pdfAdmir Softic
 
Nutritional Needs Presentation - HLTH 104
Nutritional Needs Presentation - HLTH 104Nutritional Needs Presentation - HLTH 104
Nutritional Needs Presentation - HLTH 104misteraugie
 
Call Girls in Dwarka Mor Delhi Contact Us 9654467111
Call Girls in Dwarka Mor Delhi Contact Us 9654467111Call Girls in Dwarka Mor Delhi Contact Us 9654467111
Call Girls in Dwarka Mor Delhi Contact Us 9654467111Sapana Sha
 
Explore beautiful and ugly buildings. Mathematics helps us create beautiful d...
Explore beautiful and ugly buildings. Mathematics helps us create beautiful d...Explore beautiful and ugly buildings. Mathematics helps us create beautiful d...
Explore beautiful and ugly buildings. Mathematics helps us create beautiful d...christianmathematics
 
Presentation by Andreas Schleicher Tackling the School Absenteeism Crisis 30 ...
Presentation by Andreas Schleicher Tackling the School Absenteeism Crisis 30 ...Presentation by Andreas Schleicher Tackling the School Absenteeism Crisis 30 ...
Presentation by Andreas Schleicher Tackling the School Absenteeism Crisis 30 ...EduSkills OECD
 
fourth grading exam for kindergarten in writing
fourth grading exam for kindergarten in writingfourth grading exam for kindergarten in writing
fourth grading exam for kindergarten in writingTeacherCyreneCayanan
 
1029-Danh muc Sach Giao Khoa khoi 6.pdf
1029-Danh muc Sach Giao Khoa khoi  6.pdf1029-Danh muc Sach Giao Khoa khoi  6.pdf
1029-Danh muc Sach Giao Khoa khoi 6.pdfQucHHunhnh
 
Software Engineering Methodologies (overview)
Software Engineering Methodologies (overview)Software Engineering Methodologies (overview)
Software Engineering Methodologies (overview)eniolaolutunde
 
Advanced Views - Calendar View in Odoo 17
Advanced Views - Calendar View in Odoo 17Advanced Views - Calendar View in Odoo 17
Advanced Views - Calendar View in Odoo 17Celine George
 

Recently uploaded (20)

Arihant handbook biology for class 11 .pdf
Arihant handbook biology for class 11 .pdfArihant handbook biology for class 11 .pdf
Arihant handbook biology for class 11 .pdf
 
Introduction to Nonprofit Accounting: The Basics
Introduction to Nonprofit Accounting: The BasicsIntroduction to Nonprofit Accounting: The Basics
Introduction to Nonprofit Accounting: The Basics
 
Z Score,T Score, Percential Rank and Box Plot Graph
Z Score,T Score, Percential Rank and Box Plot GraphZ Score,T Score, Percential Rank and Box Plot Graph
Z Score,T Score, Percential Rank and Box Plot Graph
 
APM Welcome, APM North West Network Conference, Synergies Across Sectors
APM Welcome, APM North West Network Conference, Synergies Across SectorsAPM Welcome, APM North West Network Conference, Synergies Across Sectors
APM Welcome, APM North West Network Conference, Synergies Across Sectors
 
Paris 2024 Olympic Geographies - an activity
Paris 2024 Olympic Geographies - an activityParis 2024 Olympic Geographies - an activity
Paris 2024 Olympic Geographies - an activity
 
INDIA QUIZ 2024 RLAC DELHI UNIVERSITY.pptx
INDIA QUIZ 2024 RLAC DELHI UNIVERSITY.pptxINDIA QUIZ 2024 RLAC DELHI UNIVERSITY.pptx
INDIA QUIZ 2024 RLAC DELHI UNIVERSITY.pptx
 
1029 - Danh muc Sach Giao Khoa 10 . pdf
1029 -  Danh muc Sach Giao Khoa 10 . pdf1029 -  Danh muc Sach Giao Khoa 10 . pdf
1029 - Danh muc Sach Giao Khoa 10 . pdf
 
Student login on Anyboli platform.helpin
Student login on Anyboli platform.helpinStudent login on Anyboli platform.helpin
Student login on Anyboli platform.helpin
 
A Critique of the Proposed National Education Policy Reform
A Critique of the Proposed National Education Policy ReformA Critique of the Proposed National Education Policy Reform
A Critique of the Proposed National Education Policy Reform
 
Mattingly "AI & Prompt Design: Structured Data, Assistants, & RAG"
Mattingly "AI & Prompt Design: Structured Data, Assistants, & RAG"Mattingly "AI & Prompt Design: Structured Data, Assistants, & RAG"
Mattingly "AI & Prompt Design: Structured Data, Assistants, & RAG"
 
Unit-IV- Pharma. Marketing Channels.pptx
Unit-IV- Pharma. Marketing Channels.pptxUnit-IV- Pharma. Marketing Channels.pptx
Unit-IV- Pharma. Marketing Channels.pptx
 
Key note speaker Neum_Admir Softic_ENG.pdf
Key note speaker Neum_Admir Softic_ENG.pdfKey note speaker Neum_Admir Softic_ENG.pdf
Key note speaker Neum_Admir Softic_ENG.pdf
 
Nutritional Needs Presentation - HLTH 104
Nutritional Needs Presentation - HLTH 104Nutritional Needs Presentation - HLTH 104
Nutritional Needs Presentation - HLTH 104
 
Call Girls in Dwarka Mor Delhi Contact Us 9654467111
Call Girls in Dwarka Mor Delhi Contact Us 9654467111Call Girls in Dwarka Mor Delhi Contact Us 9654467111
Call Girls in Dwarka Mor Delhi Contact Us 9654467111
 
Explore beautiful and ugly buildings. Mathematics helps us create beautiful d...
Explore beautiful and ugly buildings. Mathematics helps us create beautiful d...Explore beautiful and ugly buildings. Mathematics helps us create beautiful d...
Explore beautiful and ugly buildings. Mathematics helps us create beautiful d...
 
Presentation by Andreas Schleicher Tackling the School Absenteeism Crisis 30 ...
Presentation by Andreas Schleicher Tackling the School Absenteeism Crisis 30 ...Presentation by Andreas Schleicher Tackling the School Absenteeism Crisis 30 ...
Presentation by Andreas Schleicher Tackling the School Absenteeism Crisis 30 ...
 
fourth grading exam for kindergarten in writing
fourth grading exam for kindergarten in writingfourth grading exam for kindergarten in writing
fourth grading exam for kindergarten in writing
 
1029-Danh muc Sach Giao Khoa khoi 6.pdf
1029-Danh muc Sach Giao Khoa khoi  6.pdf1029-Danh muc Sach Giao Khoa khoi  6.pdf
1029-Danh muc Sach Giao Khoa khoi 6.pdf
 
Software Engineering Methodologies (overview)
Software Engineering Methodologies (overview)Software Engineering Methodologies (overview)
Software Engineering Methodologies (overview)
 
Advanced Views - Calendar View in Odoo 17
Advanced Views - Calendar View in Odoo 17Advanced Views - Calendar View in Odoo 17
Advanced Views - Calendar View in Odoo 17
 

First few months with Kotlin through Android examples

  • 1. First few months with otlin Introduction through Android examples Nebojša Vukšić
  • 2. Nebojša Vukšić Android developer @ codecentric Founder of Kotlin User Group Serbia Nesh_Wolf nebojsa92vuksic@gmail.com
  • 3. Kotlin User Group Serbia https://www.meetup.com/Serbia-Kotlin-User-Group https://www.facebook.com/kotlinserbia/ https://twitter.com/kotlin_serbia
  • 5. What is Kotlin? ● statically-typed object oriented programming language ● targeting JVM, Android and JavaScript ● fully interoperable with Java ● third party library ● has excellent IDE support
  • 6. Kotlin history ● developed by JetBrains ● unveiled to public in 2011.(development started in 2012.) ● 1.0 first stable version (February 2016.) ● current version 1.1 RC
  • 7. Why do we need Kotlin?
  • 8. Problems that we have: Why do we need Kotlin? ● Java ○ is too verbose ○ burden of previous versions ○ Null Pointer Exception issues ○ util “hell” ● Android ○ we need inheritance for almost everything ○ api ceremony ○ nullability ○ lack of Java 8 features (lambdas, stream api, method reference...)
  • 10. Variables val avenger: String = “Tony Stark” //constants avenger = “Ultron” // compile error var age : Int = 18 //variable age = 20 // compiles since age is mutable var number = 20 // Int type is inferred
  • 12. text.length // compiler error var text: String? = null // This can be null or not-null Nullability var name: String = null // compile error text?.length // compiles ⇔ if ( text != null) { text.length // smart casted to not-nullable type } name.length // this is ok since type is not nullable
  • 13. Nullability val s: String? = "This can be null or not-null" val length = s!!.length Making NPE explicit
  • 14. Nullability val s: String? = "This can be null or not-null" val length = s!!.length Making NPE explicit
  • 15. Functions fun add(a: Int, b: Int): Int { return a + b } Calling functions: add(1, 3) log(1, “Num is”) //“Num is 1” fun log(num: Int, msg: String): Unit { println(“$msg $num”) }
  • 16. Functions fun add(a: Int, b: Int): Int = a + b fun log(num: Int, msg: String): Unit = println(“$msg $num”) Calling functions: add(1, 3) log(1, “Num is”) //“Num is 1”
  • 17. Functions fun add(a: Int, b: Int) = a + b fun log(num: Int, msg: String) = println(“$msg $num”) Calling functions: add(1, 3) log(1, “Num is”) //“Num is 1”
  • 18. Functions fun add(a: Int = 0, b: Int = 0) = a + b fun log(num: Int, msg: String = “Num is”) = println(“$msg $num”) add() //returns 0 add(1) //returns 1 add(b = 1) //returns 1 log(1) // “Num is 1” log(msg = “Its ”, num = 2) // “Its 2”
  • 19. Functions fun `should equal 4`() { assertEquals(4, 2 + 2) } `should equal 4`()
  • 20. Kotlin does classes differently...
  • 21. Classes and data classes @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; User user = (User) o; if (age != user.age) return false; if (!name.equals(user.name)) return false; return email.equals(user.email); } @Override public int hashCode() { int result = name.hashCode(); result = 31 * result + email.hashCode(); result = 31 * result + age; return result; } } class User { private final String name; private final String email; private final int age; User(String name, String email, int age) { this.name = name; this.email = email; this.age = age; } public String getName() { return name; } public String getEmail() { return email; } public int getAge() { return age; } @Override public String toString() { return "User{ name='" + name + ''' + ", email='" + email + ''' + ", age=" + age + '}'; }
  • 22. Classes and data classes @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; User user = (User) o; if (age != user.age) return false; if (!name.equals(user.name)) return false; return email.equals(user.email); } @Override public int hashCode() { int result = name.hashCode(); result = 31 * result + email.hashCode(); result = 31 * result + age; return result; } } class User { private final String name; private final String email; private final int age; User(String name, String email, int age) { this.name = name; this.email = email; this.age = age; } public String getName() { return name; } public String getEmail() { return email; } public int getAge() { return age; } @Override public String toString() { return "User{ name='" + name + ''' + ", email='" + email + ''' + ", age=" + age + '}'; }
  • 23. Classes and data classes @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; User user = (User) o; if (age != user.age) return false; if (!name.equals(user.name)) return false; return email.equals(user.email); } @Override public int hashCode() { int result = name.hashCode(); result = 31 * result + email.hashCode(); result = 31 * result + age; return result; } class User ( val name: String, val email: String, val age: Int ) @Override public String toString() { return "User{ name='" + name + ''' + ", email='" + email + ''' + ", age=" + age + '}'; }
  • 24. Classes and data classes data class User ( val name: String, val email: String, val age: Int ) val user = User("John Smith", "johnsmith@mail.com", 24) val newUser = user.copy(name = "Sam") //newUser == User("Sam", "johnsmith@mail.com", 24) val (name, email, age) = newUser
  • 25. Data classes data class User ( val name: String = "John Smith", val email: String = "johnsmith@mail.com", val age: Int = 24 ) val user = User () // user == User("John Smith", "johnsmith@mail.com", 24)
  • 26. Classes and data classes data class User( val name: String, val email: String, val age: Int) ● Kotlin classes are final by default ● we need to annotate class as open, if we want to inherit them ● data classes can’t be inherited class limitations:
  • 27. Classes and data classes open class User( val name: String, val email: String, val age: Int) ● Kotlin classes are final by default ● we need to annotate class as open, if we want to inherit them ● data classes can’t be inherited class limitations:
  • 29. Extension functions fun String.swapSpacesForUnderscore(): String = this.replace(" ", "_") "This is random message!".swapSpacesForUnderscore() // returns "This_is_random_message!" Compiles to: public static final String swapSpacesForUnderscore(@NotNull String $receiver) { Intrinsics.checkParameterIsNotNull($receiver, "$receiver"); return $receiver.replace(," ", "_"); }
  • 30. Extension functions package com.app.android.util fun String.swapSpacesForUnderscore(): String = this.replace(" ", "_") package com.app.android.main "Random text!".swapSpacesForUnderscore()
  • 31. Extension functions package com.app.android.util fun String.swapSpacesForUnderscore(): String = this.replace(" ", "_") package com.app.android.main import com.app.android.util.swapSpacesForUnderscore "Random text!".swapSpacesForUnderscore()
  • 32. Extension properties val Array<String>.lastElement: String get() = this[size - 1] val names: Array<String> = arrayOf("John", "Will", "Emma", "Peter") val name = names.lastElement //returns "Peter" Compiles to: public static final String getLastElement(@NotNull String[] $receiver) { Intrinsics.checkParameterIsNotNull($receiver, "$receiver"); return $receiver[$receiver.length - 1]; }
  • 33. Extension properties val <T> Array<T>.lastElement: T get() = this[size - 1] val names: Array<String> = arrayOf("John", "Will", "Emma", "Peter") val name = names.lastElement //returns "Peter" Compiles to: public static final Object getLastElement(@NotNull Object[] $receiver) { Intrinsics.checkParameterIsNotNull($receiver, "$receiver"); return $receiver[$receiver.length - 1]; }
  • 34. Extension properties val <T> Array<T>.lastElement: T get() = this[size - 1] val nums: Array<Int> = arrayOf(1, 2, 3, 4) val num = nums.lastElement //returns 4 Compiles to: public static final Object getLastElement(@NotNull Object[] $receiver) { Intrinsics.checkParameterIsNotNull($receiver, "$receiver"); return $receiver[$receiver.length - 1]; }
  • 35. Android extensions plugin no more findViewById()
  • 36. Android extensions plugin class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val toolbar: Toolbar = findViewById(R.id.toolbar) as Toolbar setSupportActionBar(toolbar) val fab: FloatingActionButton = findViewById(R.id.fab) as FloatingActionButton fab.setOnClickListener { Toast.makeText(this, "Hello!", Toast.LENGTH_SHORT).show() } } }
  • 37. Android extensions plugin class MainActivity : AppCompatActivity() { @BindView(R.id.toolbar) Toolbar toolbar; @BindView(R.id.fab) FloatingActionButton fab; override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) ButterKnife.bind(this) setSupportActionBar(toolbar) fab.setOnClickListener { Toast.makeText(this, "Hello!", Toast.LENGTH_SHORT).show() } } }
  • 38. Android extensions plugin import kotlinx.android.synthetic.main.activity_main.toolbar import kotlinx.android.synthetic.main.activity_main.fab class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) setSupportActionBar(toolbar) fab.setOnClickListener { Toast.makeText(this, "Hello!", Toast.LENGTH_SHORT).show() } } }
  • 39. Android extensions plugin import kotlinx.android.synthetic.main.activity_main.toolbar import kotlinx.android.synthetic.main.activity_main.fab class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) setSupportActionBar(toolbar) fab.setOnClickListener { Toast.makeText(this, "Hello!", Toast.LENGTH_SHORT).show() } } }
  • 40. Android extensions plugin import kotlinx.android.synthetic.main.activity_main.toolbar import kotlinx.android.synthetic.main.activity_main.loging_btn_registration_fragment class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) setSupportActionBar(toolbar) loging_btn_registration_fragment.setOnClickListener { Toast.makeText(this, "Hello!", Toast.LENGTH_SHORT).show() } } }
  • 41. Android extensions plugin import kotlinx.android.synthetic.main.activity_main.toolbar import kotlinx.android.synthetic.main.activity_main.loging_btn_registration_fragment as login class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) setSupportActionBar(toolbar) login.setOnClickListener { Toast.makeText(this, "Hello!", Toast.LENGTH_SHORT).show()} } }
  • 43. Function expressions val add: (Int, Int) -> Int = { x,y -> x+y } add(1,2) val validator: (String) -> Boolean ={ value -> value.contains("@") } validator("john@mail.com") ● function expressions are blocks of code which we can instantiate(represent as type)
  • 44. Function expressions val add: (Int, Int) -> Int = { x,y -> x+y } add(1,2) ● function expressions are blocks of code which we can instantiate(represent as type) val validator: (String) -> Boolean ={ it.contains("@") } validator("john@mail.com")
  • 45. Function expressions val add: (Int, Int) -> Int = { x,y -> x+y } add(1,2) val validator: (String) -> Boolean ={ it.contains("@") } validator("john@mail.com") mailTextview.validateWith{ validator("john@mail.com") } ● function expressions are blocks of code which we can instantiate(represent as type)
  • 47. Higher order functions fun <T> List<T>.filter(predicate: (T) -> Boolean): List<T>{ }
  • 48. Higher order functions fun <T> List<T>.filter(predicate: (T) -> Boolean): List<T>{ val items = ArrayList<T>() return items }
  • 49. Higher order functions fun <T> List<T>.filter(predicate: (T) -> Boolean): List<T>{ val items = ArrayList<T>() for (item in this) { } return items }
  • 50. Higher order functions fun <T> List<T>.filter(predicate: (T) -> Boolean): List<T>{ val items = ArrayList<T>() for (item in this) { if (predicate(item)) { items.add(item) } } return items } val cars = listOf("BMW", "Fiat", "Mercedes", "KIA", "Ford") val filteredCars = cars.filter ({ it.startsWith("F") }) // filteredCars == listOf("Fiat", "Ford")
  • 51. Higher order functions fun <T> List<T>.filter(predicate: (T) -> Boolean): List<T>{ val items = ArrayList<T>() for (item in this) { if (predicate(item)) { items.add(item) } } return items } val cars = listOf("BMW", "Fiat", "Mercedes", "KIA", "Ford") val filteredCars = cars.filter { it.startsWith("F") } // filteredCars == listOf("Fiat", "Ford")
  • 53. Quick overview ● Extension functions - adds functionality to types without overriding existing methods ● Function expressions - undeclared function body used as an expression ● Higher order function - function that accepts function or returns function
  • 54. Combination of this three makes powerful combo
  • 55. fun saveUser(user: User) { val editor = sharedPref.edit() editor.putString(ACCESS_TOKEN, user.token) editor.putString(USER_EMAIL, user.email) editor.commit() } Extension / Higher order function expression combo fun SharedPreferences.edit(editor : SharedPreferences.Editor, func: () -> Unit) { func() editor.commit() }
  • 56. Extension / Higher order function expression combo fun saveUser(user: User) { val editor = sharedPref.edit() sharedPref.edit(editor) { editor.putString(ACCESS_TOKEN, user.token) editor.putString(USER_EMAIL, user.email) } } fun SharedPreferences.edit(editor : SharedPreferences.Editor, func: () -> Unit) { func() editor.commit() }
  • 57. fun saveUser(user: User) { val editor = sharedPref.edit() sharedPref.edit(editor) { editor.putString(ACCESS_TOKEN, user.token) editor.putString(USER_EMAIL, user.email) } } Extension / Higher order function expression combo fun SharedPreferences.edit(editor : SharedPreferences.Editor, func: () -> Unit) { func() editor.commit() }
  • 58. fun saveUser(user: User) { sharedPref.edit { editor.putString(ACCESS_TOKEN, user.token) editor.putString(USER_EMAIL, user.email) } } Extension / Higher order function expression combo fun SharedPreferences.edit(func: () -> Unit) { val editor = edit() func() editor.commit() }
  • 59. fun saveUser(user: User) { sharedPref.edit { it.putString(ACCESS_TOKEN, user.token) it.putString(USER_EMAIL, user.email) } } Extension / Higher order function expression combo fun SharedPreferences.edit(func: (SharedPreferences.Editor) -> Unit) { val editor = edit() func(editor) editor.commit() }
  • 60. fun saveUser(user: User) { sharedPref.edit { it.putString(ACCESS_TOKEN, user.token) it.putString(USER_EMAIL, user.email) } } Extension / Higher order function expression combo fun SharedPreferences.edit(func: (SharedPreferences.Editor) -> Unit) { val editor = edit() func(editor) editor.commit() }
  • 61. fun saveUser(user: User) { sharedPref.edit { it.putString(ACCESS_TOKEN, user.token) it.putString(USER_EMAIL, user.email) } } Extension / Higher order function expression combo fun SharedPreferences.edit(func: SharedPreferences.Editor.() -> Unit)) { val editor = edit() func(editor) editor.commit() }
  • 62. fun saveUser(user: User) { sharedPref.edit { it.putString(ACCESS_TOKEN, user.token) it.putString(USER_EMAIL, user.email) } } Extension / Higher order function expression combo fun SharedPreferences.edit(func: SharedPreferences.Editor.() -> Unit)) { val editor = edit() editor.func() editor.commit() }
  • 63. fun saveUser(user: User) { sharedPref.edit { putString(ACCESS_TOKEN, user.token) putString(USER_EMAIL, user.email) } } Extension / Higher order function expression combo fun SharedPreferences.edit(func: SharedPreferences.Editor.() -> Unit) { val editor = edit() editor.func() editor.commit() }
  • 64. Extension / Higher order function expression combo fun SharedPreferences.Editor.put(pair: Pair<String, Any>) { val key = pair.first val value = pair.second when(value) { is String -> putString(key, value) is Int -> putInt(key, value) is Boolean -> putBoolean(key, value) is Float -> putFloat(key, value) is Long -> putLong(key, value) else -> error(“Only primitive types are supported”) } }
  • 65. fun saveUser(user: User) { sharedPref.edit { putString(ACCESS_TOKEN, user.token) putString(USER_EMAIL, user.email) } } Extension / Higher order function expression combo fun SharedPreferences.edit(func: SharedPreferences.Editor.() -> Unit)) { val editor = edit() editor.func() editor.commit() }
  • 66. Extension / Higher order function expression combo fun saveUser(user: User) { sharedPref.edit { put(Pair(ACCESS_TOKEN, user.token)) put(Pair(USER_EMAIL, user.email)) } } fun SharedPreferences.edit(func: SharedPreferences.Editor.() -> Unit) { val editor = edit() editor.func() editor.commit() }
  • 67. fun saveUser(user: User) { sharedPref.edit { put(ACCESS_TOKEN to user.token) put(USER_EMAIL to user.email) } } Extension / Higher order function expression combo fun SharedPreferences.edit(func: SharedPreferences.Editor.() -> Unit) { val editor = edit() editor.func() editor.commit() }
  • 68. fun saveUser(user: User) { sharedPref.edit { put(ACCESS_TOKEN to user.token) put(USER_EMAIL to user.email) } } Extension / Higher order function expression combo fun SharedPreferences.edit(func: SharedPreferences.Editor.() -> Unit) { val editor = edit() editor.func() editor.commit() } public infix fun <A, B> A.to(that: B): Pair<A, B> = Pair(this, that)
  • 69. fun saveUser(user: User) { sharedPref.edit { put(ACCESS_TOKEN to user.token) put(USER_EMAIL to user.email) } } Extension / Higher order function expression combo inline fun SharedPreferences.edit(func: SharedPreferences.Editor.() -> Unit) { val editor = edit() editor.func() editor.commit() }
  • 70. Extension / Higher order function expression combo From this: fun saveUser(user: User) { val editor = sharedPref.edit() editor.putString(ACCESS_TOKEN, user.token) editor.putString(USER_EMAIL, user.email) editor.commit() } To this: inline fun saveUser(user: User) { sharedPref.edit { put(ACCESS_TOKEN to user.token) put(USER_EMAIL to user.email) } }
  • 71. Summary don’t worry, next slide is the last
  • 72. Summary ● immutable and mutable variables ● nullability ● functions(default values and named arguments) ● classes and data classes ● extension functions and properties ● function expression ● higher order functions ● ultra mega giga combo of three above concepts ● use inline modifier
  • 73. Resources ● Official Kotlin documentation ● Official Kotlin Github ● Anko ● Kotlin koans ● Awesome Kotlin – collection of materials ● Slack kanal ● Design patterns in Kotlin ● Keddit - demo app ● Kotlin For Android (at DevFest İzmir 2016) ● Kotlin – Ready for Production – Hadi Hariri ● Android development with Kotlin – Jake Wharton
  • 75.
  • 76. Nebojša Vukšić Android developer @ codecentric Founder of Kotlin User Group Serbia Nesh_Wolf nebojsa92vuksic@gmail.com Kotlin User Group Serbia https://www.meetup.com/Serbia-Kotlin-User-Group https://www.facebook.com/kotlinserbia/ https://twitter.com/kotlin_serbia