Bob Dahlberg
Isotop - Team Lead Mobile
Challenge Accepted - Founder
Who’s Bob?
- Building software
- CrossFit Instructor
- Father
- Loves challenges!
Slide 3
Slide 3 text
Background
Android development
Kotlin since late 2015
Studied Java 5 in School
Developed Android with Java 6
Found Scala..
Found Kotlin!
Still stuck on Java 6 in Android
Slide 4
Slide 4 text
Let’s see some code!
Slide 5
Slide 5 text
I’t might be null
The java code
// Not to unusual java-style snippet
public boolean hasQuality(Stream stream) {
boolean quality = false;
if (stream != null && stream.getUri() != null){
String query = stream.getUri().getQuery();
if (query != null) {
quality = query.contains("quality");
}
}
return quality;
}
Slide 6
Slide 6 text
I’t might be null
The java code
- auto convert to kotlin
// Automatically converted to Kotlin
fun hasQuality(stream: Stream?): Boolean {
var quality = false
if (stream != null && stream.uri != null) {
val query = stream.uri!!.query
if (query != null) {
quality = query.contains("quality")
}
}
return quality
}
Slide 7
Slide 7 text
I’t might be null
The java code
- auto convert to kotlin
- use the nullable type
// Manually improved to use the nullable type
fun hasQuality(stream: Stream?): Boolean {
var quality = false
val query: String? = stream?.uri?.query
if (query != null) {
quality = query.contains(“quality”)
}
return quality
}
Slide 8
Slide 8 text
I’t might be null
The java code
- auto convert to kotlin
- use the nullable type
- if as expression
// If as an expression
fun hasQuality(stream: Stream?): Boolean {
val query: String? = stream?.uri?.query
return if(query != null) {
query.contains(“quality”)
} else false
}
Slide 9
Slide 9 text
I’t might be null
The java code
- auto convert to kotlin
- use the nullable type
- if as expression
- no explicit null-checks
// No explicit null-checks
fun hasQuality(stream: Stream?): Boolean {
return stream?.uri?.query?.contains(“quality”) ?: false
}
Slide 10
Slide 10 text
I’t might be null
The java code
- auto convert to kotlin
- use the nullable type
- if as expression
- no explicit null-checks
- three styles of the function
// 1. Regular function
fun hasQuality(stream: Stream?): Boolean {
return stream?.uri?.query?.contains(“quality”) ?: false
}
// 2. The return type us inferred from the expression
fun hasQuality(stream: Stream?) =
stream?.uri?.query?.contains(“quality”) == true
// 3 Extension function
fun Stream.hasQuality() =
uri?.query?.contains(“quality”) == true
myStream?.hasQuality()
Slide 11
Slide 11 text
Next example
Slide 12
Slide 12 text
If ifs and buts..
The java code
public Grade parse(Object from) {
if (from instanceof Integer) {
if ((int) from <= 5 && (int) from > 0) {
return new Grade((int) from);
}
}
else if (from instanceof Character) {
if ((char) from <= 'f' && (char) from >= 'a') {
return new Grade((char) from);
}
}
else if (from == "G" || from == "VG" || from == "MVG"){
return new Grade((String) from);
}
return Grade.FAIL;
}
Slide 13
Slide 13 text
If ifs and buts..
The java code
- translated
fun parse(from: Any): Grade {
if (from is Int) {
if (from as Int <= 5 && from as Int > 0) {
return Grade(from as Int)
}
}
else if (from is Char) {
if (from as Char <= 'f' && from as Char >= 'a') {
return Grade(from as Char)
}
}
else if (from == "G" || from == "VG" || from == "MVG"){
return Grade(from as String)
}
return Grade.FAIL
}
Slide 14
Slide 14 text
If ifs and buts..
The java code
- translated
- smart cast
fun parse(from: Any): Grade {
if (from is Int) {
if (from <= 5 && from > 0) {
return Grade(from)
}
}
else if (from is Char) {
if (from <= 'f' && from >= 'a') {
return Grade(from)
}
}
else if (from == "G" || from == "VG" || from == "MVG"){
return Grade(from as String)
}
return Grade.FAIL
}
Slide 15
Slide 15 text
If ifs and buts..
The java code
- translated
- smart cast
- ranges
fun parse(from: Any): Grade {
if (from is Int) {
if (from in 1..5) {
return Grade(from)
}
}
else if (from is Char) {
if (from in 'a'..’f’) {
return Grade(from)
}
}
else if (from == "G" || from == "VG" || from == "MVG"){
return Grade(from as String)
}
return Grade.FAIL
}
Slide 16
Slide 16 text
If ifs and buts..
The java code
- translated
- smart cast
- ranges
- when
fun parse(from: Any): Grade {
return when (from) {
is Int -> if (from in 1..5) Grade(from)
else Grade.FAIL
is Char -> if (from in ‘a'..’f’) Grade(from)
else Grade.FAIL
“G”, “VG”, “MVG" -> Grade(from as String)
else -> Grade.FAIL
}
Slide 17
Slide 17 text
If ifs and buts..
The java code
- translated
- smart cast
- ranges
- when
- done
fun parse(from: Any) = when (from) {
in 1..5 -> Grade(from as Int)
in ‘a’..’f’ -> Grade(from as Char)
“G”, “VG”, “MVG" -> Grade(from as String)
else -> Grade.FAIL
}
Slide 18
Slide 18 text
Next example
Slide 19
Slide 19 text
Delegation
The java code
class Module extends Controller implements Dispatcher {
private final Dispatcher _dispatcher;
public Module(Dispatcher dispatcher {
_dispatcher = dispatcher;
}
@Override
public void addListener(Listener listener) {
_dispatcher.addListener(listener);
}
@Override
public void removeListener(Listener listener) {
_dispatcher.removeListener(listener);
}
@Override
public void dispatchEvent(Event event) {
_dispatcher.dispatchEvent(event);
}
}
Slide 20
Slide 20 text
Delegation
The java code
- kotlin class delegation
class Module(
private val dispatcher: Dispatcher
): Controller(), Dispatcher by dispatcher
Slide 21
Slide 21 text
Delegation
The java code
- kotlin class delegation
- delegation properties
class Module {
val firstAccess by lazy {
System.currentTimeMillis()
}
}
Slide 22
Slide 22 text
Next example
Slide 23
Slide 23 text
Less is more
The java code
public class Person {
private final String name;
private final int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public int getAge() {
return age;
}
public String getName() {
return name;
}
@Override
public boolean equals(Object other) { /*check equality*/ }
@Override
public int hashCode() { /*generate unique hash*/ }
@Override
public String toString() {
return "Person("+name+", "+age+")";
}
}
Slide 24
Slide 24 text
Less is more
The java code
- the data class
data class Person(val name: String, val age: Int)
Slide 25
Slide 25 text
Less is more
The java code
- the data class
- copy
data class Person(val name: String, val age: Int)
val bob = Person("Bob", 33)
val workingBob = bob.copy()
val agingBob = bob.copy(age=66)
Slide 26
Slide 26 text
Less is more
The java code
- the data class
- copy
- deconstructing
data class Person(val name: String, val age: Int)
val bob = Person("Bob", 33)
val workingBob = bob.copy()
val agingBob = bob.copy(age=66)
val (_,age) = bob
Slide 27
Slide 27 text
Less is more
The java code
- the data class
- copy
- deconstructing
- operation overloading
data class Person(val name: String, val age: Int)
operator fun Person.plus(extra:String) =
copy(“$name $extra”)
val bob = Person("Bob", 33)
val fullNameBob = bob + “Dahlberg”