SlideShare a Scribd company logo
1 of 69
Download to read offline
From Java to Kotlin beyond
Alt+Shift+Cmd+K
Fabio Collini
@fabioCollini
linkedin.com/in/fabiocollini
github.com/fabioCollini
medium.com/@fabioCollini
codingjam.it
Android programmazione avanzata
Android Developers Italia
Ego slide
Kotlin can be configured in one click
A Java class can be converted easily
ok, now what?
LAMB
DAS
DATACLASSES
COLLE
CTIONS
ASYNC
CODE
DELE
GATES
Agenda
LAMB
DAS
JavaCode KotlinCode
/**
* Returns the first element matching the given [predicate].
* @throws [NoSuchElementException] if no such element is found.
*/
inline fun <T> Iterable<T>.first(predicate: (T) -> Boolean): T {
for (element in this) {
if (predicate(element)) {
return element
}1
}2
throw NoSuchElementException(
"Collection contains no element matching the predicate.")
}3
val list = listOf("Java", "Kotlin")
val s = list.first({_v: String ->
v.length > 4
_})
val list = listOf("Java", "Kotlin")
val s = list.first({_v ->
v.length > 4
_})
val list = listOf("Java", "Kotlin")
val s = list.first({_
it.length > 4
_})
val list = listOf("Java", "Kotlin")
val s = list.first {_
it.length > 4
_}
val list = listOf("Java", "Kotlin")
val s = list.first { it.length > 4_}
public static <T> T first(Iterable<T> list, Predicate<T> predicate) {_
for (T t : list) {__
if (predicate.test(t)) {___
return t;
}____
}_____
throw new NoSuchElementException(
"Collection contains no element matching the predicate.");
}______
inline fun <T> Iterable<T>.first(predicate: (T) -> Boolean): T {_
for (element in this) {__
if (predicate(element)) {___
return element
}____
}____
throw NoSuchElementException(
"Collection contains no element matching the predicate.")
}_____
List<String> list = Arrays.asList("Java", “Kotlin");
String s = first(list, p -> p.length() > 4);
List<String> list = Arrays.asList("Java", “Kotlin");
String s = first(list, p -> p.length() > 4);
val list = listOf("Java", "Kotlin")
val s = list.first { it.length > 4 }
inline fun <T> Iterable<T>.first(predicate: (T) -> Boolean): T {
for (element in this) {
if (predicate(element)) {
return element
}
}
throw NoSuchElementException(
"Collection contains no element matching the predicate.")
}
public static <T> T first(List<T> list, Predicate<T> predicate) {
for (T t : list) {
if (predicate.test(t)) {
return t;
}
}
throw new NoSuchElementException(
“Collection contains no element matching the predicate.");
}
inline
val list = listOf("Java", "Kotlin")
val s = list.first { it.length > 4 }
inline fun <T> Iterable<T>.first(predicate: (T) -> Boolean): T {
for (element in this) {
if (predicate(element)) {
return element
}
}
throw NoSuchElementException(
"Collection contains no element matching the predicate.")
}
val list = listOf("Java", "Kotlin")
var ret: String? = null
for (element in list) {
if (element.length > 4) {
ret = element;
break
}
}
if (ret == null)
throw NoSuchElementException(
"Collection contains no element matching the predicate.")
val s = ret
DATACLASSES
class Person(var name:_String)_
public class Person {
private String name;
public Person(String name) {
this.name = name;
}1
public String getName() {
return name;
}2
public void setName(String name) {
this.name = name;
}3
}4
public class Person {
private long id;
private String name;
private int age;
public Person(long id, String name, int age) {
this.id = id;
this.name = name;
this.age = age;
}
public long getId()_{_return id;_}
public String getName()_{_return name;_}
public int getAge()_{_return age;_}
}4
class Person(
val id: Long,
val name: String,
val age: Int
)_
@Parcelize
data class Person(
val id: Long,
val name: String,
val age: Int
)_: Parcelable
public class Person implements Parcelable {
private long id;
private String name;
private int age;
public Person(long id, String name, int age) {
this.id = id;
this.name = name;
this.age = age;
}1
protected Person(Parcel in) {
id = in.readLong();
name = in.readString();
age = in.readInt();
}2
public long getId()_{_return id;_}
public String getName()_{_return name;_}
public int getAge()_{_return age;_}
@Override public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person that = (Person) o;
if (id != that.id) return false;
if (age != that.age) return false;
return name != null ? name.equals(that.name) : that.name == null;
}3
@Override public int hashCode() {
int result = (int) (id ^ (id >>> 32));
result = 31 * result + (name != null ? name.hashCode() : 0);
result = 31 * result + age;
return result;
}4
@Override public String toString() {
return "Person{" +
"id=" + id +
", name='" + name + ''' +
", age=" + age +
'}';
}5
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeLong(id);
dest.writeString(name);
dest.writeInt(age);
}6
@Override
public int describeContents() {
return 0;
}7
public static final Creator<Person> CREATOR = new Creator<Person>() {
@Override
public Person createFromParcel(Parcel in) {
return new Person(in);
}8
@Override
public Person[] newArray(int size) {
return new Person[size];
}9
};
}_
@AutoValue
public abstract class Person
implements Parcelable {_
public static Person create(
long id, String name, int age) {
return new AutoValue_Person(
id, name, age);
}__
public abstract long id();
public abstract String name();
public abstract int age();
public abstract Person withName(String name);
}_
@Parcelize
data class Person(
val id: Long,
val name: String,
val age: Int
)_: Parcelable
val p = Person(1, "name", 10)
val p1 = p.copy(name = "newName", age = 20)_
Person p = Person.create(1, "name", 10);
Person p1 = p.withName("newName");
val p = Person(1, "name", 10)
val (_, name, age) = p
println("$name $age")
data class Pair<out A, out B>(
val first: A,
val second: B
) : Serializable {
override fun toString(): String = "($first, $second)"
}_
data class Pair<out A, out B>(
val first: A,
val second: B
) : Serializable {
override fun toString(): String = "($first, $second)"
}_
val myPair: Pair<Int, Int> = Pair(10, 20)
val otherPair: Pair<Int, Int> = 10 to 20
infix fun <A, B> A.to(that: B): Pair<A, B> = Pair(this, that)
fun myMethod(): Pair<Int, Int> {
//...
return 10 to 20
}
val (a, b) = myMethod()
COLLE
CTIONS
System.out.println(b.toString());
List<Person> people = Arrays.asList(...);
StringBuilder b = new StringBuilder();
for (String s : cities) {
if (b.length() > 0) {
b.append(", ");
}3
b.append(s);
}4
for (Person person : people) {
City city = person.getAddress().getCity();
if (city.getRegion().equals("Tuscany")) {
cities.add(city.getName() + " (" + city.getCode() + ")");
}1
}2
Set<String> cities = new TreeSet<>();
val people = listOf(...)
val s = people
.map { it.address.city }
.filter { it.region == "Tuscany" }
.distinct()
.sortedBy { it.name }
.joinToString { "${it.name} (${it.code})" }
println(s)
String s = Stream.of(people)
.map(it -> it.getAddress().getCity())
.filter(it -> it.getRegion().equals("Tuscany"))
.distinct()
.sortBy(City::getName)
.map(it -> it.getName() + " (" + it.getCode() + ")")
.collect(Collectors.joining(", "));
System.out.println(s);
val people = listOf(...)
val s = people
.asSequence()
.map { it.address.city }
.map { "${it.name} (${it.code})" }
.first { it.region == "Tuscany" }
println(s)
val youngest = people.minBy { it.age }
val peopleByCity: Map<City, List<Person>> =
people.groupBy { it.address.city }
val all: Boolean = people.all {
it.address.city.name == "Florence"
}1
val any: Boolean = people.any {
it.address.city.name == "Florence"
}2
val (adults: List<Person>, minors: List<Person>) =
people.partition { it.age >= 18 }
val readOnlyList: List<Int> = listOf(10, 20, 30)
val secondElement = readOnlyList[1]
val mutableList: MutableList<Int> = mutableListOf(10, 20, 30)
mutableList[1] = 21
val map = mapOf(1 to "ABC", 2 to "DEF")
val abc = map[1]
val mutableMap = mutableMapOf(1 to "ABC", 2 to "DEF")
mutableMap[3] = "XYZ"
val otherList = (mutableList - readOnlyList) + mutableMap.keys
ASYNC
CODE
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val myTextView = findViewById<TextView>(R.id.text)
myTextView.text = "Loading..."
Thread.sleep(2000)
myTextView.text = "Loading something else..."
Thread.sleep(2000)
myTextView.text = "Done"
}_
/**
* Delays coroutine for a given time without blocking
* a thread and resumes it after a specified time.
* ...
*/
suspend fun delay(time: Long, unit: TimeUnit = MILLISECONDS) {
//...
}
suspend
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val myTextView = findViewById<TextView>(R.id.text)
async(UI) {
myTextView.text = "Loading..."
delay(2000)
myTextView.text = "Loading something else..."
delay(2000)
myTextView.text = "Done"
}async
}end
interface StackOverflowService {
@GET("/users")
fun getTopUsers(): Deferred<List<User>>
}A
async(UI) {
try {
val topUsers = service.getTopUsers().await()
val usersUi = topUsers.map { createUserUi(it) }
showInUi(usersUi)
} catch (e: Exception) {
showError(e)
}__
}___
interface MyService {
fun login(): Deferred<String>
fun loadData(token: String): Deferred<Data>
}A
async(UI) {
try {
val token = service.login().await()
val data = service.loadData(token).await()
showInUi(data)
} catch (e: Exception) {
showError(e)
}__
}___
service.login()
.flatMap { service.loadData(it) }
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
{ data -> showInUi(data) },
{ showError(it) }
)end
RxJavaCoroutines
async(UI) {
try {
val token = service.login().await()
val data = service.loadData(token).await()
showInUi(data)
} catch (e: Exception) {
showError(e)
}__
}___
RxJava
Coroutines
OR
RxJava
Coroutines
AND
RxJava Coroutines->
RxJavaCoroutines ->
rxCompletable, rxMaybe, rxSingle, rxObservable, rxFlowable
CompletableSource.await, MaybeSource.await, MaybeSource.awaitOrDefault,
MaybeSource.openSubscription, SingleSource.await,
ObservableSource.awaitFirst, ObservableSource.awaitFirstOrDefault,
ObservableSource.awaitFirstOrElse, ObservableSource.awaitFirstOrNull,
ObservableSource.awaitLast, ObservableSource.awaitSingle,
ObservableSource.openSubscription, ObservableSource.iterator
github.com/Kotlin/kotlinx.coroutines/tree/master/reactive/kotlinx-coroutines-rx2
My 2 cents
Suspending methods are easier to
use than RxJava Singles
Observables/Flowables are the best
abstraction for a stream of data
async(UI) {
try {
val token = service.login().await()
val data = service.loadData(token).await()
showInUi(data)
} catch (e: Exception) {
showError(e)
}__
}___
async(UI) {
try {
val token = service.login().await()
val data = service.loadData(token).await()
val otherData = service.loadOtherData(token).await()
showInUi(data, otherData)
} catch (e: Exception) {
showError(e)
}__
}___
async(UI) {
try {
val token = service.login().await()
val data = service.loadData(token)
val otherData = service.loadOtherData(token)
showInUi(data.await(), otherData.await())
} catch (e: Exception) {
showError(e)
}__
}___
async(UI) {
try {
val token = service.login().await()
updateProgress()
val data = service.loadData(token)
val otherData = service.loadOtherData(token)
showInUi(data.await(), otherData.await())
} catch (e: Exception) {
showError(e)
}__
}___
async(UI) {
try {
withTimeout(10, SECONDS) {
val token = retry(3) {
service.login().await()
}T
updateProgress()
val data = service.loadData(token)
val otherData = service.loadOtherData(token)
showInUi(data.await(), otherData.await())
}B
} catch (e: Exception) {
showError(e)
}__
}___
async(UI) {
try {
withTimeout(10, SECONDS) {
val token = retry(3) {
service.login().await()
}T
updateProgress()
val data = service.loadData(token)
val otherData = service.loadOtherData(token)
showInUi(data.await(), otherData.await())
}B
} catch (e: Exception) {
showError(e)
}__
}___
suspend fun <T> retry(times: Int, block: suspend () -> T): T {
repeat(times - 1) {
try {
return block()
} catch (ignored: Exception) {
}
}
return block()
}
DELE
GATES
class TokenHolder {0
var token = ""
}1
class TokenHolder(val prefs: SharedPreferences) {0
var token = ""
}1
class TokenHolder(val prefs: SharedPreferences) {
var token
get() = prefs.getString("token", "")
set(value) = prefs.edit().putString("token", value).apply()
}1
class TokenHolder(prefs: SharedPreferences) {
var token by prefs.string()
}1
class TokenHolder(prefs: SharedPreferences) {
var token by prefs.string()
}1
fun SharedPreferences.string(
defaultValue: String = "",
key: String? = null
): ReadWriteProperty<Any, String> {
return object : ReadWriteProperty<Any, String> {
override fun getValue(thisRef: Any, property: KProperty<*>): String {
return getString(key ?: property.name, defaultValue)
}2
override fun setValue(thisRef: Any, property: KProperty<*>,
value: String) {
edit().putString(key ?: property.name, value).apply()
}3
}4
}5
class TokenHolder(prefs: SharedPreferences) {
var token by prefs.string()
}1
tokenHolder.token += "ABC"
prefs.edit().putString(
"token",
prefs.getString("token", "") + "ABC"
).apply()
Wrapping up
inline methods to avoid extra classes
functional code is natural in Kotlin
code can be simplified using data
classes, coroutines and delegates
Links
AutoValue
https://github.com/google/auto/blob/master/value/userguide/index.md
Lightweight Stream
https://github.com/aNNiMON/Lightweight-Stream-API
Guide to kotlinx.coroutines by example
https://github.com/Kotlin/kotlinx.coroutines/blob/master/coroutines-guide.md
Kotlin coroutines, a deeper look
https://medium.com/@elizarov/kotlin-coroutines-a-deeper-look-180536305c3f
Kotlin delegates in Android development - part 1
https://hackernoon.com/kotlin-delegates-in-android-development-part-1-50346cf4aed7
Kotlin delegates in Android development - part 2
https://proandroiddev.com/kotlin-delegates-in-android-development-part-2-2c15c11ff438
THANKS
FOR YOUR
ATTENTION
QUESTIONS?
Android Developers Italia
androiddevs.it

More Related Content

What's hot

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
 
Nik Graf - Get started with Reason and ReasonReact
Nik Graf - Get started with Reason and ReasonReactNik Graf - Get started with Reason and ReasonReact
Nik Graf - Get started with Reason and ReasonReact
OdessaJS Conf
 

What's hot (18)

Kotlin standard
Kotlin standardKotlin standard
Kotlin standard
 
2014-11-01 01 Денис Нелюбин. О сортах кофе
2014-11-01 01 Денис Нелюбин. О сортах кофе2014-11-01 01 Денис Нелюбин. О сортах кофе
2014-11-01 01 Денис Нелюбин. О сортах кофе
 
Kotlin, why?
Kotlin, why?Kotlin, why?
Kotlin, why?
 
The Ring programming language version 1.5.2 book - Part 32 of 181
The Ring programming language version 1.5.2 book - Part 32 of 181The Ring programming language version 1.5.2 book - Part 32 of 181
The Ring programming language version 1.5.2 book - Part 32 of 181
 
Tuga it 2016 - What's New In C# 6
Tuga it 2016 - What's New In C# 6Tuga it 2016 - What's New In C# 6
Tuga it 2016 - What's New In C# 6
 
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)
 
Idiomatic Kotlin
Idiomatic KotlinIdiomatic Kotlin
Idiomatic Kotlin
 
Nik Graf - Get started with Reason and ReasonReact
Nik Graf - Get started with Reason and ReasonReactNik Graf - Get started with Reason and ReasonReact
Nik Graf - Get started with Reason and ReasonReact
 
What's new in C# 6 - NetPonto Porto 20160116
What's new in C# 6  - NetPonto Porto 20160116What's new in C# 6  - NetPonto Porto 20160116
What's new in C# 6 - NetPonto Porto 20160116
 
JAVA 8 : Migration et enjeux stratégiques en entreprise
JAVA 8 : Migration et enjeux stratégiques en entrepriseJAVA 8 : Migration et enjeux stratégiques en entreprise
JAVA 8 : Migration et enjeux stratégiques en entreprise
 
Functional Scala 2020
Functional Scala 2020Functional Scala 2020
Functional Scala 2020
 
Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)
 
The Ring programming language version 1.4 book - Part 9 of 30
The Ring programming language version 1.4 book - Part 9 of 30The Ring programming language version 1.4 book - Part 9 of 30
The Ring programming language version 1.4 book - Part 9 of 30
 
Privet Kotlin (Windy City DevFest)
Privet Kotlin (Windy City DevFest)Privet Kotlin (Windy City DevFest)
Privet Kotlin (Windy City DevFest)
 
The Ring programming language version 1.6 book - Part 35 of 189
The Ring programming language version 1.6 book - Part 35 of 189The Ring programming language version 1.6 book - Part 35 of 189
The Ring programming language version 1.6 book - Part 35 of 189
 
Kotlin
KotlinKotlin
Kotlin
 
The Ring programming language version 1.9 book - Part 41 of 210
The Ring programming language version 1.9 book - Part 41 of 210The Ring programming language version 1.9 book - Part 41 of 210
The Ring programming language version 1.9 book - Part 41 of 210
 
The Ring programming language version 1.2 book - Part 22 of 84
The Ring programming language version 1.2 book - Part 22 of 84The Ring programming language version 1.2 book - Part 22 of 84
The Ring programming language version 1.2 book - Part 22 of 84
 

Similar to From java to kotlin beyond alt+shift+cmd+k

Scala - fra newbie til ninja på en time
Scala - fra newbie til ninja på en timeScala - fra newbie til ninja på en time
Scala - fra newbie til ninja på en time
karianneberg
 
CodeCamp Iasi 10 march 2012 - Practical Groovy
CodeCamp Iasi 10 march 2012 - Practical GroovyCodeCamp Iasi 10 march 2012 - Practical Groovy
CodeCamp Iasi 10 march 2012 - Practical Groovy
Codecamp Romania
 
AST Transformations at JFokus
AST Transformations at JFokusAST Transformations at JFokus
AST Transformations at JFokus
HamletDRC
 
Scala presentation by Aleksandar Prokopec
Scala presentation by Aleksandar ProkopecScala presentation by Aleksandar Prokopec
Scala presentation by Aleksandar Prokopec
Loïc Descotte
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
Hiroshi Ono
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
Hiroshi Ono
 

Similar to From java to kotlin beyond alt+shift+cmd+k (20)

つくってあそぼ Kotlin DSL ~拡張編~
つくってあそぼ Kotlin DSL ~拡張編~つくってあそぼ Kotlin DSL ~拡張編~
つくってあそぼ Kotlin DSL ~拡張編~
 
No excuses, switch to kotlin
No excuses, switch to kotlinNo excuses, switch to kotlin
No excuses, switch to kotlin
 
Scala introduction
Scala introductionScala introduction
Scala introduction
 
Scala taxonomy
Scala taxonomyScala taxonomy
Scala taxonomy
 
C# 6.0
C# 6.0C# 6.0
C# 6.0
 
From Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf Milan
From Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf MilanFrom Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf Milan
From Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf Milan
 
Persisting Data on SQLite using Room
Persisting Data on SQLite using RoomPersisting Data on SQLite using Room
Persisting Data on SQLite using Room
 
Scala - fra newbie til ninja på en time
Scala - fra newbie til ninja på en timeScala - fra newbie til ninja på en time
Scala - fra newbie til ninja på en time
 
JDays Lviv 2014: Java8 vs Scala: Difference points & innovation stream
JDays Lviv 2014:  Java8 vs Scala:  Difference points & innovation streamJDays Lviv 2014:  Java8 vs Scala:  Difference points & innovation stream
JDays Lviv 2014: Java8 vs Scala: Difference points & innovation stream
 
Kotlin for Android Developers
Kotlin for Android DevelopersKotlin for Android Developers
Kotlin for Android Developers
 
Introduction kot iin
Introduction kot iinIntroduction kot iin
Introduction kot iin
 
Features of Kotlin I find exciting
Features of Kotlin I find excitingFeatures of Kotlin I find exciting
Features of Kotlin I find exciting
 
Introduction to Scala
Introduction to ScalaIntroduction to Scala
Introduction to Scala
 
First few months with Kotlin - Introduction through android examples
First few months with Kotlin - Introduction through android examplesFirst few months with Kotlin - Introduction through android examples
First few months with Kotlin - Introduction through android examples
 
CodeCamp Iasi 10 march 2012 - Practical Groovy
CodeCamp Iasi 10 march 2012 - Practical GroovyCodeCamp Iasi 10 march 2012 - Practical Groovy
CodeCamp Iasi 10 march 2012 - Practical Groovy
 
AST Transformations at JFokus
AST Transformations at JFokusAST Transformations at JFokus
AST Transformations at JFokus
 
Dotnet 18
Dotnet 18Dotnet 18
Dotnet 18
 
Scala presentation by Aleksandar Prokopec
Scala presentation by Aleksandar ProkopecScala presentation by Aleksandar Prokopec
Scala presentation by Aleksandar Prokopec
 
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
 

More from Fabio Collini

More from Fabio Collini (20)

Architectures in the compose world
Architectures in the compose worldArchitectures in the compose world
Architectures in the compose world
 
Using hilt in a modularized project
Using hilt in a modularized projectUsing hilt in a modularized project
Using hilt in a modularized project
 
Managing parallelism using coroutines
Managing parallelism using coroutinesManaging parallelism using coroutines
Managing parallelism using coroutines
 
Kotlin Delegates in practice - Kotlin community conf
Kotlin Delegates in practice - Kotlin community confKotlin Delegates in practice - Kotlin community conf
Kotlin Delegates in practice - Kotlin community conf
 
Kotlin delegates in practice - Kotlin Everywhere Stockholm
Kotlin delegates in practice - Kotlin Everywhere StockholmKotlin delegates in practice - Kotlin Everywhere Stockholm
Kotlin delegates in practice - Kotlin Everywhere Stockholm
 
Using Dagger in a Clean Architecture project
Using Dagger in a Clean Architecture projectUsing Dagger in a Clean Architecture project
Using Dagger in a Clean Architecture project
 
Solid principles in practice the clean architecture - Droidcon Italy
Solid principles in practice the clean architecture - Droidcon ItalySolid principles in practice the clean architecture - Droidcon Italy
Solid principles in practice the clean architecture - Droidcon Italy
 
SOLID principles in practice: the Clean Architecture - Devfest Emila Romagna
SOLID principles in practice: the Clean Architecture - Devfest Emila RomagnaSOLID principles in practice: the Clean Architecture - Devfest Emila Romagna
SOLID principles in practice: the Clean Architecture - Devfest Emila Romagna
 
SOLID principles in practice: the Clean Architecture
SOLID principles in practice: the Clean ArchitectureSOLID principles in practice: the Clean Architecture
SOLID principles in practice: the Clean Architecture
 
Async code on kotlin: rx java or/and coroutines - Kotlin Night Turin
Async code on kotlin: rx java or/and coroutines - Kotlin Night TurinAsync code on kotlin: rx java or/and coroutines - Kotlin Night Turin
Async code on kotlin: rx java or/and coroutines - Kotlin Night Turin
 
Recap Google I/O 2018
Recap Google I/O 2018Recap Google I/O 2018
Recap Google I/O 2018
 
From java to kotlin beyond alt+shift+cmd+k - Droidcon italy
From java to kotlin beyond alt+shift+cmd+k - Droidcon italyFrom java to kotlin beyond alt+shift+cmd+k - Droidcon italy
From java to kotlin beyond alt+shift+cmd+k - Droidcon italy
 
Testing Android apps based on Dagger and RxJava Droidcon UK
Testing Android apps based on Dagger and RxJava Droidcon UKTesting Android apps based on Dagger and RxJava Droidcon UK
Testing Android apps based on Dagger and RxJava Droidcon UK
 
Intro to Retrofit 2 and RxJava2
Intro to Retrofit 2 and RxJava2Intro to Retrofit 2 and RxJava2
Intro to Retrofit 2 and RxJava2
 
Testing Android apps based on Dagger and RxJava
Testing Android apps based on Dagger and RxJavaTesting Android apps based on Dagger and RxJava
Testing Android apps based on Dagger and RxJava
 
Android Data Binding in action using MVVM pattern - droidconUK
Android Data Binding in action using MVVM pattern - droidconUKAndroid Data Binding in action using MVVM pattern - droidconUK
Android Data Binding in action using MVVM pattern - droidconUK
 
Data Binding in Action using MVVM pattern
Data Binding in Action using MVVM patternData Binding in Action using MVVM pattern
Data Binding in Action using MVVM pattern
 
Android Wear CodeLab - GDG Firenze
Android Wear CodeLab - GDG FirenzeAndroid Wear CodeLab - GDG Firenze
Android Wear CodeLab - GDG Firenze
 
Testable Android Apps using data binding and MVVM
Testable Android Apps using data binding and MVVMTestable Android Apps using data binding and MVVM
Testable Android Apps using data binding and MVVM
 
Introduction to Retrofit and RxJava
Introduction to Retrofit and RxJavaIntroduction to Retrofit and RxJava
Introduction to Retrofit and RxJava
 

Recently uploaded

DeepFakes presentation : brief idea of DeepFakes
DeepFakes presentation : brief idea of DeepFakesDeepFakes presentation : brief idea of DeepFakes
DeepFakes presentation : brief idea of DeepFakes
MayuraD1
 
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ssuser89054b
 

Recently uploaded (20)

Navigating Complexity: The Role of Trusted Partners and VIAS3D in Dassault Sy...
Navigating Complexity: The Role of Trusted Partners and VIAS3D in Dassault Sy...Navigating Complexity: The Role of Trusted Partners and VIAS3D in Dassault Sy...
Navigating Complexity: The Role of Trusted Partners and VIAS3D in Dassault Sy...
 
HAND TOOLS USED AT ELECTRONICS WORK PRESENTED BY KOUSTAV SARKAR
HAND TOOLS USED AT ELECTRONICS WORK PRESENTED BY KOUSTAV SARKARHAND TOOLS USED AT ELECTRONICS WORK PRESENTED BY KOUSTAV SARKAR
HAND TOOLS USED AT ELECTRONICS WORK PRESENTED BY KOUSTAV SARKAR
 
Hazard Identification (HAZID) vs. Hazard and Operability (HAZOP): A Comparati...
Hazard Identification (HAZID) vs. Hazard and Operability (HAZOP): A Comparati...Hazard Identification (HAZID) vs. Hazard and Operability (HAZOP): A Comparati...
Hazard Identification (HAZID) vs. Hazard and Operability (HAZOP): A Comparati...
 
Computer Networks Basics of Network Devices
Computer Networks  Basics of Network DevicesComputer Networks  Basics of Network Devices
Computer Networks Basics of Network Devices
 
S1S2 B.Arch MGU - HOA1&2 Module 3 -Temple Architecture of Kerala.pptx
S1S2 B.Arch MGU - HOA1&2 Module 3 -Temple Architecture of Kerala.pptxS1S2 B.Arch MGU - HOA1&2 Module 3 -Temple Architecture of Kerala.pptx
S1S2 B.Arch MGU - HOA1&2 Module 3 -Temple Architecture of Kerala.pptx
 
FEA Based Level 3 Assessment of Deformed Tanks with Fluid Induced Loads
FEA Based Level 3 Assessment of Deformed Tanks with Fluid Induced LoadsFEA Based Level 3 Assessment of Deformed Tanks with Fluid Induced Loads
FEA Based Level 3 Assessment of Deformed Tanks with Fluid Induced Loads
 
Learn the concepts of Thermodynamics on Magic Marks
Learn the concepts of Thermodynamics on Magic MarksLearn the concepts of Thermodynamics on Magic Marks
Learn the concepts of Thermodynamics on Magic Marks
 
Introduction to Serverless with AWS Lambda
Introduction to Serverless with AWS LambdaIntroduction to Serverless with AWS Lambda
Introduction to Serverless with AWS Lambda
 
Online food ordering system project report.pdf
Online food ordering system project report.pdfOnline food ordering system project report.pdf
Online food ordering system project report.pdf
 
DeepFakes presentation : brief idea of DeepFakes
DeepFakes presentation : brief idea of DeepFakesDeepFakes presentation : brief idea of DeepFakes
DeepFakes presentation : brief idea of DeepFakes
 
Minimum and Maximum Modes of microprocessor 8086
Minimum and Maximum Modes of microprocessor 8086Minimum and Maximum Modes of microprocessor 8086
Minimum and Maximum Modes of microprocessor 8086
 
AIRCANVAS[1].pdf mini project for btech students
AIRCANVAS[1].pdf mini project for btech studentsAIRCANVAS[1].pdf mini project for btech students
AIRCANVAS[1].pdf mini project for btech students
 
Hostel management system project report..pdf
Hostel management system project report..pdfHostel management system project report..pdf
Hostel management system project report..pdf
 
data_management_and _data_science_cheat_sheet.pdf
data_management_and _data_science_cheat_sheet.pdfdata_management_and _data_science_cheat_sheet.pdf
data_management_and _data_science_cheat_sheet.pdf
 
Online electricity billing project report..pdf
Online electricity billing project report..pdfOnline electricity billing project report..pdf
Online electricity billing project report..pdf
 
A Study of Urban Area Plan for Pabna Municipality
A Study of Urban Area Plan for Pabna MunicipalityA Study of Urban Area Plan for Pabna Municipality
A Study of Urban Area Plan for Pabna Municipality
 
Thermal Engineering-R & A / C - unit - V
Thermal Engineering-R & A / C - unit - VThermal Engineering-R & A / C - unit - V
Thermal Engineering-R & A / C - unit - V
 
Computer Lecture 01.pptxIntroduction to Computers
Computer Lecture 01.pptxIntroduction to ComputersComputer Lecture 01.pptxIntroduction to Computers
Computer Lecture 01.pptxIntroduction to Computers
 
kiln thermal load.pptx kiln tgermal load
kiln thermal load.pptx kiln tgermal loadkiln thermal load.pptx kiln tgermal load
kiln thermal load.pptx kiln tgermal load
 
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
 

From java to kotlin beyond alt+shift+cmd+k

  • 1. From Java to Kotlin beyond Alt+Shift+Cmd+K Fabio Collini
  • 3. Kotlin can be configured in one click
  • 4. A Java class can be converted easily
  • 9. /** * Returns the first element matching the given [predicate]. * @throws [NoSuchElementException] if no such element is found. */ inline fun <T> Iterable<T>.first(predicate: (T) -> Boolean): T { for (element in this) { if (predicate(element)) { return element }1 }2 throw NoSuchElementException( "Collection contains no element matching the predicate.") }3
  • 10. val list = listOf("Java", "Kotlin") val s = list.first({_v: String -> v.length > 4 _})
  • 11. val list = listOf("Java", "Kotlin") val s = list.first({_v -> v.length > 4 _})
  • 12. val list = listOf("Java", "Kotlin") val s = list.first({_ it.length > 4 _})
  • 13. val list = listOf("Java", "Kotlin") val s = list.first {_ it.length > 4 _}
  • 14. val list = listOf("Java", "Kotlin") val s = list.first { it.length > 4_}
  • 15. public static <T> T first(Iterable<T> list, Predicate<T> predicate) {_ for (T t : list) {__ if (predicate.test(t)) {___ return t; }____ }_____ throw new NoSuchElementException( "Collection contains no element matching the predicate."); }______ inline fun <T> Iterable<T>.first(predicate: (T) -> Boolean): T {_ for (element in this) {__ if (predicate(element)) {___ return element }____ }____ throw NoSuchElementException( "Collection contains no element matching the predicate.") }_____
  • 16. List<String> list = Arrays.asList("Java", “Kotlin"); String s = first(list, p -> p.length() > 4);
  • 17. List<String> list = Arrays.asList("Java", “Kotlin"); String s = first(list, p -> p.length() > 4); val list = listOf("Java", "Kotlin") val s = list.first { it.length > 4 }
  • 18.
  • 19. inline fun <T> Iterable<T>.first(predicate: (T) -> Boolean): T { for (element in this) { if (predicate(element)) { return element } } throw NoSuchElementException( "Collection contains no element matching the predicate.") } public static <T> T first(List<T> list, Predicate<T> predicate) { for (T t : list) { if (predicate.test(t)) { return t; } } throw new NoSuchElementException( “Collection contains no element matching the predicate."); }
  • 21. val list = listOf("Java", "Kotlin") val s = list.first { it.length > 4 } inline fun <T> Iterable<T>.first(predicate: (T) -> Boolean): T { for (element in this) { if (predicate(element)) { return element } } throw NoSuchElementException( "Collection contains no element matching the predicate.") }
  • 22. val list = listOf("Java", "Kotlin") var ret: String? = null for (element in list) { if (element.length > 4) { ret = element; break } } if (ret == null) throw NoSuchElementException( "Collection contains no element matching the predicate.") val s = ret
  • 24. class Person(var name:_String)_ public class Person { private String name; public Person(String name) { this.name = name; }1 public String getName() { return name; }2 public void setName(String name) { this.name = name; }3 }4
  • 25. public class Person { private long id; private String name; private int age; public Person(long id, String name, int age) { this.id = id; this.name = name; this.age = age; } public long getId()_{_return id;_} public String getName()_{_return name;_} public int getAge()_{_return age;_} }4 class Person( val id: Long, val name: String, val age: Int )_
  • 26. @Parcelize data class Person( val id: Long, val name: String, val age: Int )_: Parcelable public class Person implements Parcelable { private long id; private String name; private int age; public Person(long id, String name, int age) { this.id = id; this.name = name; this.age = age; }1 protected Person(Parcel in) { id = in.readLong(); name = in.readString(); age = in.readInt(); }2 public long getId()_{_return id;_} public String getName()_{_return name;_} public int getAge()_{_return age;_} @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Person that = (Person) o; if (id != that.id) return false; if (age != that.age) return false; return name != null ? name.equals(that.name) : that.name == null; }3 @Override public int hashCode() { int result = (int) (id ^ (id >>> 32)); result = 31 * result + (name != null ? name.hashCode() : 0); result = 31 * result + age; return result; }4 @Override public String toString() { return "Person{" + "id=" + id + ", name='" + name + ''' + ", age=" + age + '}'; }5 @Override public void writeToParcel(Parcel dest, int flags) { dest.writeLong(id); dest.writeString(name); dest.writeInt(age); }6 @Override public int describeContents() { return 0; }7 public static final Creator<Person> CREATOR = new Creator<Person>() { @Override public Person createFromParcel(Parcel in) { return new Person(in); }8 @Override public Person[] newArray(int size) { return new Person[size]; }9 }; }_
  • 27. @AutoValue public abstract class Person implements Parcelable {_ public static Person create( long id, String name, int age) { return new AutoValue_Person( id, name, age); }__ public abstract long id(); public abstract String name(); public abstract int age(); public abstract Person withName(String name); }_ @Parcelize data class Person( val id: Long, val name: String, val age: Int )_: Parcelable
  • 28. val p = Person(1, "name", 10) val p1 = p.copy(name = "newName", age = 20)_ Person p = Person.create(1, "name", 10); Person p1 = p.withName("newName");
  • 29. val p = Person(1, "name", 10) val (_, name, age) = p println("$name $age")
  • 30. data class Pair<out A, out B>( val first: A, val second: B ) : Serializable { override fun toString(): String = "($first, $second)" }_
  • 31. data class Pair<out A, out B>( val first: A, val second: B ) : Serializable { override fun toString(): String = "($first, $second)" }_ val myPair: Pair<Int, Int> = Pair(10, 20) val otherPair: Pair<Int, Int> = 10 to 20 infix fun <A, B> A.to(that: B): Pair<A, B> = Pair(this, that)
  • 32. fun myMethod(): Pair<Int, Int> { //... return 10 to 20 } val (a, b) = myMethod()
  • 34. System.out.println(b.toString()); List<Person> people = Arrays.asList(...); StringBuilder b = new StringBuilder(); for (String s : cities) { if (b.length() > 0) { b.append(", "); }3 b.append(s); }4 for (Person person : people) { City city = person.getAddress().getCity(); if (city.getRegion().equals("Tuscany")) { cities.add(city.getName() + " (" + city.getCode() + ")"); }1 }2 Set<String> cities = new TreeSet<>();
  • 35. val people = listOf(...) val s = people .map { it.address.city } .filter { it.region == "Tuscany" } .distinct() .sortedBy { it.name } .joinToString { "${it.name} (${it.code})" } println(s)
  • 36.
  • 37. String s = Stream.of(people) .map(it -> it.getAddress().getCity()) .filter(it -> it.getRegion().equals("Tuscany")) .distinct() .sortBy(City::getName) .map(it -> it.getName() + " (" + it.getCode() + ")") .collect(Collectors.joining(", ")); System.out.println(s);
  • 38. val people = listOf(...) val s = people .asSequence() .map { it.address.city } .map { "${it.name} (${it.code})" } .first { it.region == "Tuscany" } println(s)
  • 39. val youngest = people.minBy { it.age } val peopleByCity: Map<City, List<Person>> = people.groupBy { it.address.city } val all: Boolean = people.all { it.address.city.name == "Florence" }1 val any: Boolean = people.any { it.address.city.name == "Florence" }2 val (adults: List<Person>, minors: List<Person>) = people.partition { it.age >= 18 }
  • 40. val readOnlyList: List<Int> = listOf(10, 20, 30) val secondElement = readOnlyList[1] val mutableList: MutableList<Int> = mutableListOf(10, 20, 30) mutableList[1] = 21 val map = mapOf(1 to "ABC", 2 to "DEF") val abc = map[1] val mutableMap = mutableMapOf(1 to "ABC", 2 to "DEF") mutableMap[3] = "XYZ" val otherList = (mutableList - readOnlyList) + mutableMap.keys
  • 42. override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val myTextView = findViewById<TextView>(R.id.text) myTextView.text = "Loading..." Thread.sleep(2000) myTextView.text = "Loading something else..." Thread.sleep(2000) myTextView.text = "Done" }_
  • 43. /** * Delays coroutine for a given time without blocking * a thread and resumes it after a specified time. * ... */ suspend fun delay(time: Long, unit: TimeUnit = MILLISECONDS) { //... }
  • 45. override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val myTextView = findViewById<TextView>(R.id.text) async(UI) { myTextView.text = "Loading..." delay(2000) myTextView.text = "Loading something else..." delay(2000) myTextView.text = "Done" }async }end
  • 46. interface StackOverflowService { @GET("/users") fun getTopUsers(): Deferred<List<User>> }A async(UI) { try { val topUsers = service.getTopUsers().await() val usersUi = topUsers.map { createUserUi(it) } showInUi(usersUi) } catch (e: Exception) { showError(e) }__ }___
  • 47. interface MyService { fun login(): Deferred<String> fun loadData(token: String): Deferred<Data> }A async(UI) { try { val token = service.login().await() val data = service.loadData(token).await() showInUi(data) } catch (e: Exception) { showError(e) }__ }___
  • 48. service.login() .flatMap { service.loadData(it) } .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe( { data -> showInUi(data) }, { showError(it) } )end RxJavaCoroutines async(UI) { try { val token = service.login().await() val data = service.loadData(token).await() showInUi(data) } catch (e: Exception) { showError(e) }__ }___
  • 51. RxJava Coroutines-> RxJavaCoroutines -> rxCompletable, rxMaybe, rxSingle, rxObservable, rxFlowable CompletableSource.await, MaybeSource.await, MaybeSource.awaitOrDefault, MaybeSource.openSubscription, SingleSource.await, ObservableSource.awaitFirst, ObservableSource.awaitFirstOrDefault, ObservableSource.awaitFirstOrElse, ObservableSource.awaitFirstOrNull, ObservableSource.awaitLast, ObservableSource.awaitSingle, ObservableSource.openSubscription, ObservableSource.iterator github.com/Kotlin/kotlinx.coroutines/tree/master/reactive/kotlinx-coroutines-rx2
  • 52. My 2 cents Suspending methods are easier to use than RxJava Singles Observables/Flowables are the best abstraction for a stream of data
  • 53. async(UI) { try { val token = service.login().await() val data = service.loadData(token).await() showInUi(data) } catch (e: Exception) { showError(e) }__ }___
  • 54. async(UI) { try { val token = service.login().await() val data = service.loadData(token).await() val otherData = service.loadOtherData(token).await() showInUi(data, otherData) } catch (e: Exception) { showError(e) }__ }___
  • 55. async(UI) { try { val token = service.login().await() val data = service.loadData(token) val otherData = service.loadOtherData(token) showInUi(data.await(), otherData.await()) } catch (e: Exception) { showError(e) }__ }___
  • 56. async(UI) { try { val token = service.login().await() updateProgress() val data = service.loadData(token) val otherData = service.loadOtherData(token) showInUi(data.await(), otherData.await()) } catch (e: Exception) { showError(e) }__ }___
  • 57. async(UI) { try { withTimeout(10, SECONDS) { val token = retry(3) { service.login().await() }T updateProgress() val data = service.loadData(token) val otherData = service.loadOtherData(token) showInUi(data.await(), otherData.await()) }B } catch (e: Exception) { showError(e) }__ }___
  • 58. async(UI) { try { withTimeout(10, SECONDS) { val token = retry(3) { service.login().await() }T updateProgress() val data = service.loadData(token) val otherData = service.loadOtherData(token) showInUi(data.await(), otherData.await()) }B } catch (e: Exception) { showError(e) }__ }___ suspend fun <T> retry(times: Int, block: suspend () -> T): T { repeat(times - 1) { try { return block() } catch (ignored: Exception) { } } return block() }
  • 60. class TokenHolder {0 var token = "" }1
  • 61. class TokenHolder(val prefs: SharedPreferences) {0 var token = "" }1
  • 62. class TokenHolder(val prefs: SharedPreferences) { var token get() = prefs.getString("token", "") set(value) = prefs.edit().putString("token", value).apply() }1
  • 63. class TokenHolder(prefs: SharedPreferences) { var token by prefs.string() }1
  • 64. class TokenHolder(prefs: SharedPreferences) { var token by prefs.string() }1 fun SharedPreferences.string( defaultValue: String = "", key: String? = null ): ReadWriteProperty<Any, String> { return object : ReadWriteProperty<Any, String> { override fun getValue(thisRef: Any, property: KProperty<*>): String { return getString(key ?: property.name, defaultValue) }2 override fun setValue(thisRef: Any, property: KProperty<*>, value: String) { edit().putString(key ?: property.name, value).apply() }3 }4 }5
  • 65. class TokenHolder(prefs: SharedPreferences) { var token by prefs.string() }1 tokenHolder.token += "ABC" prefs.edit().putString( "token", prefs.getString("token", "") + "ABC" ).apply()
  • 66. Wrapping up inline methods to avoid extra classes functional code is natural in Kotlin code can be simplified using data classes, coroutines and delegates
  • 67. Links AutoValue https://github.com/google/auto/blob/master/value/userguide/index.md Lightweight Stream https://github.com/aNNiMON/Lightweight-Stream-API Guide to kotlinx.coroutines by example https://github.com/Kotlin/kotlinx.coroutines/blob/master/coroutines-guide.md Kotlin coroutines, a deeper look https://medium.com/@elizarov/kotlin-coroutines-a-deeper-look-180536305c3f Kotlin delegates in Android development - part 1 https://hackernoon.com/kotlin-delegates-in-android-development-part-1-50346cf4aed7 Kotlin delegates in Android development - part 2 https://proandroiddev.com/kotlin-delegates-in-android-development-part-2-2c15c11ff438