KEMBAR78
Introduction to kotlin + spring boot demo | PPTX
Introduction to
Kotlin
Riyadh Java Meetup
Nov 2019
Mohammad Hewedy
mhewedy
@mohewedy
1
2
Agenda
● What is Kotlin?
● Language Features
● Demos
2
If I were writing a Spring app today, I would
strongly consider Kotlin. It brings the same kind
of simplification to Java code as Spring did to
J2EE.
Rod Johnson.
3
What is Kotlin?
● Statically with type inference and strongly typed(1).
● Multi paradigm (object-oriented and functional)
● Fully Interoperate with Java
● Mainly targets the JVM (targets other runtimes as well)
● Semicolons are optional
● Type comes after the variable (val age: Int = 30)
(1) see appendix 1
4
What is Kotlin?
● val keyword used to declare immutable variables
● var keyword used to declare mutable variables
● Classes and class members are public by default
● Classes and methods are final by default
● open keyword used to mark class as extensible and method as
overridable
5
What is Kotlin?
● Interface methods are abstract and open by default
● Has package-level functions as well as class-level functions
● Supports extension functions to patch any library classes with new
functionality (a.k.a Monkey patching)
● Support limited set of operator overloading using operator keyword
6
operator fun String.not() = this.reversed()
println(!"hello") // prints olleh
What is Kotlin?
● Functions in kotlin supports:
○ default arguments
○ named arguments
○ variable-length argument lists
● data classes provides:
○ equals()/hashCode()
○ toString()
○ componentN() functions
○ copy()
○ Destructuring declarations: val (name, age) = jane
● Multiline strings with string interpolation
● Delegated Properties that allows lazy variable evaluation 7
What is Kotlin?
● object used to declare objects, which might used as:
○ singletons
○ companion object
○ Anonymous classes
● Access modifiers:
○ public
○ private
○ protected
○ internal
● Can use to write Domain-Specific Languages (DSL)
● Has Tail call optimization (tail recursion)
8
Code or Data?
9
config {
datasource {
url = "jdbc:h2:mem"
username = "root"
}
webservice {
wsdl = "http://example.org/ws?wsdl"
action = "urn:weather-ws"
}
}
source: https://gist.github.com/mhewedy/88d0f63486101501c3d87ff9d2e0231b
Code as Data
10
fun main() {
val config = Config()
config {
datasource {
url = "jdbc:h2:mem"
username = "root"
}
webservice {
wsdl = "http://example.org/ws?wsdl"
action = "urn:weather-ws"
}
}
println(config)
}
source: https://gist.github.com/mhewedy/88d0f63486101501c3d87ff9d2e0231b
Language Features
11
If as an expression
● Traditional usage:
12
var max = a
if (a < b) max = b
If as an expression
● Traditional usage with else:
13
var max: Int
if (a > b) {
max = a
} else {
max = b
}
If as an expression
● As an expression
14
val max = if (a > b) a else b
If as an expression
● As an expression
15
val max = if (a > b) {
print("choose a")
a
} else {
print("choose b")
b
}
When expression
16
when (x) {
1 -> print("x == 1")
2 -> print("x == 2")
else -> { // Note the block
print("x is neither 1 or 2")
}
}
When expression
17
when (x) {
in 1..10 -> print("x is in range")
in validNumbers -> print("x is valid")
!in 10..20 -> print("x is outside the range3")
else -> print("none of the above")
}
When expression
18
fun hasPrefix(x: Any) = when (x) {
is String -> x.startsWith("prefix") // note the smart cast
else -> false
}
When expression
19
when {
x.isOdd() -> print("x is in the range")
x.isEven() -> print("x is even")
else -> print("x is funny")
}
When expression
● when scoped variables:
20
fun Request.getBody() =
when (val response = executeRequest()) {
is Success -> response.body
is HttpError -> throw HttpException(response.status)
}
For Loops
● For loops used to for iterates through anything that provides an iterator,
which means:
○ has a member- or extension-function iterator(), whose return type:
■ has a member- or extension-function next(), and
■ has a member- or extension-function hasNext() that returns Boolean.
21
For Loops
22
for (item: Int in ints) {
}
For Loops
23
for (i in 1..3) {
println(i)
}
For Loops
24
for (i in 6 downTo 0 step 2) {
println(i)
}
For Loops
25
for (i in 6.downTo(0).step(2)) {
println(i)
}
Loops and labels
● Kotlin has while loops as well
● Both for and while loops support break and continue (w/o labels)
26
loop@ for (i in 1..10) {
for (j in 1..10) {
if (...) break@loop
}
}
For Loops
27
var counter = 0
operator fun Int.iterator() = this
operator fun Int.next() = this
operator fun Int.hasNext() = counter++ < this
// usage:
for (n in 20) {
println(n)
}
Classes
28
class Person constructor(firstName: String)
Classes
29
class Person(val name: String) {
var children: MutableList<Person> = mutableListOf();
constructor(name: String, parent: Person) : this(name) {
parent.children.add(this)
}
}
Classes
30
class DontCreateMe private constructor() {/* */ }
Classes
31
val invoice = Invoice()
val customer = Customer("Joe Smith")
32
Type Hierarchy
Inheritance
33
class Example // implicitly inherits from Any
Inheritance
34
open class Base(p: Int)
class Derived(p: Int) : Base(p)
Inheritance
35
class MyView : View {
constructor(ctx: Context) : super(ctx)
constructor(ctx: Context, attrs: AttributeSet)
: super(ctx, attrs)
}
Inheritance
36
open class Polygon {
open fun draw() {}
}
abstract class Rectangle : Polygon() {
abstract override fun draw()
}
Inheritance
37
open class Shape {
open fun draw() {/* ... */}
fun fill() {/* ... */ }
}
class Circle : Shape() {
override fun draw() {/* ... */}
}
Inheritance
38
typealias NodeList = ArrayList<Node>
sealed class Node
object EmptyNode : Node()
data class ValueNode(val value: Any?) : Node()
data class ObjectNode(val props: ArrayList<Pair<String, Any?>>) : Node()
data class ArrayNode(val elements: NodeList) : Node()
source: https://github.com/mhewedy/eureka-klient/blob/de7a1bf2ebec72a3bc1c9ca32868f5d93da32765/src/main/kotlin/helpers/json/Deserializer.kt#L30
Inheritance
39
fun eval(expr: Node): Unit = when (expr) {
is ValueNode -> println(expr.value) // smart case
is ObjectNode -> println(expr.props)
is ArrayNode -> expr.elements.forEach { eval(it) }
is EmptyNode -> print("empty")
// the `else` clause is not required
}
Properties and Fields
40
class State(val name: String)
class Address {
var name: String = "Holmes, Sherlock"
var state: State? = null
}
// used as
val address = Address()
println("${address.name} at ${address.state?.name}")
// note the safe navigation operator with nullable types
Properties and Fields
41
class MyClass {
lateinit var subject: TestSubject
@Setup fun setup() {
subject = TestSubject()
}
@Test fun test() {
subject.method() // dereference directly
}
}
Interfaces
42
interface MyInterface {
fun foo()
fun bar() {
// optional body
}
}
Interfaces
43
interface A{
fun foo() { print("A") }
fun bar()
}
interface B{
fun foo() { print("B") }
fun bar() { print("bar") }
}
class C : A {
override fun bar() { print("bar") }
}
class D: A, B {
override fun foo() {
super<A>.foo()
super<B>.foo()
}
override fun bar() {
super.bar()
}
}
Functions
44
fun double(x: Int): Int {
return 2 * x
}
Functions
45
fun double(x: Int): Int = x * 2
Functions
46
fun double(x: Int) = x * 2
Functions
47
fun foo(vararg strings: String) { /* ... */}
// calling as
foo(strings = *arrayOf("a", "b", "c"))
Functions
48
fun read(b: Array<Byte>, off: Int = 0, len: Int = b.size) {
/* ... */
}
Functions
49
fun reformat(
str: String,
normalizeCase: Boolean = true,
upperCaseFirstLetter: Boolean = true,
divideByCamelHumps: Boolean = false,
wordSeparator: Char = ' '
) {
/* ... */
}
// calling as
reformat(str,
normalizeCase = true,
upperCaseFirstLetter = true,
divideByCamelHumps = false,
wordSeparator = '_')
// can shuffle args as well
Functions
50
infix fun Int.shl(x: Int): Int { /* ... */ }
// calling the function using the infix notation
1 shl 2
// is the same as
1.shl(2)
Functions
51
fun dfs(graph: Graph) {
fun dfs(current: Vertex, visited: MutableSet<Vertex>) {
if (!visited.add(current)) return
for (v in current.neighbors)
dfs(v, visited)
}
dfs(graph.vertices[0], HashSet())
}
Functions
52
class Sample {
fun foo() {
print("Foo")
}
}
Functions
● Classes and objects can extend functions
53
object Identity : (Int) -> Int {
override fun invoke(p1: Int) = p1
}
// called as
Identity(10)
Functions
● Lambda with receiver
54
operator fun Config.invoke(block: Config.() -> Unit) {
block.invoke(this)
}
Functions
55
fun add(x: Int): (Int) -> Int {
return fun(y: Int): Int {
return x + y
}
}
val result = add(10)(30)
Functions
56
fun add(x: Int): (Int) -> Int {
return { y: Int -> x + y }
}
val addFunc = add(10)
val result = addFunc(30)
Functions
57
fun add(x: Int): (Int) -> Int {
return { x + it }
}
val addFunc = add(10)
val result = addFunc(30)
Functions
58
fun <T> map(x: String, op: (String) -> T): T {
return op(x)
}
// used as
map("John Smith", fun(n: String): Int {
return n.length
})
Functions
59
fun <T> map(x: String, op: (String) -> T): T {
return op(x)
}
// used as
map("John Smith", { it.length })
Functions
60
fun <T> map(x: String, op: (String) -> T): T {
return op(x)
}
// used as
map("John Smith") { it.length }
Functions
61
fun <E> List<E>.test(op: (e: E) -> Boolean): List<E> {
val ret = arrayListOf<E>()
for (element in this) {
if (op(element)) ret += element
}
return ret
}
// used as
employees.test { it.age > 25 }
Functions
● fold is one of most important functional operators
62
fun <T, R> Collection<T>.fold(
initial: R,
combine: (acc: R, nextElement: T) -> R
): R {
var accumulator: R = initial
for (element: T in this) {
accumulator = combine(accumulator, element)
}
return accumulator
}
fold (a.k.a reduce): how it works
63source: http://perugini.cps.udayton.edu/teaching/books/PL/www/lecture_notes/currying.html
Collections
64
Collections
65
val numbers = mutableListOf("one", "two", "three", "four")
numbers += "five"
val immutableNumbers = listOf("one", "two", "three", "four")
immutableNumbers += "five" // compilation error
Collection Operations
● Transformations
○ Mapping (map)
○ Zipping (zip)
○ Flattening (flatmap)
● Filtering
○ Filtering (filter)
○ Partitioning (partition)
○ Testing predicates (any, none, all)
● Plus and Minus
66
Collection Operations
● Grouping
○ Group By (groupBy)
● Retrieving Collection Parts
○ Take and drop (takeWhile, dropWhile, takeLast, dropLast, take(n), drop(n))
○ Partitioning (partition)
○ Testing predicates (any, none, all)
● Retrieve:
○ At index: (elementAt, [])
○ By condition: (first, last, find, findLast)
67
Collection Operations
● Order:
○ Sorting: (sortBy, sortedByDescending, reversed, shuffled)
● Aggregate:
○ Built-in: min, max, average, sum, count, maxBy, minBy
○ Custom: reduce, fold
68
So, How to start?
69
Write your test cases in Kotlin
70
@Test
fun `Test getContentType for image pdf byte stream`() {
val pdfBytes = byteArrayOf(0x25, 0x50, 0x44, 0x46, 0x2d, 0x31, 0x2e, 0x34) // %PDF-1.4
val contentType = StreamUtil.
getContentType(ByteArrayInputStream(pngPdfBytes), "abc.png") //give invalid name
assertThat(contentType).isEqualTo("application/pdf")
}
Test Spring Apps
71
@Test
fun `test calling translateToCategories will calculate the agent category correctly`() {
// setup
val agentRepository = mock(AgentRepository::class.java)
val agentCategoryRepository = mock(AgentCategoryRepository::class.java)
whenever(agentRepository.findAllById(any()))
.thenReturn(listOf(createAgentOfExperience(10), createAgentOfExperience(5)))
whenever(agentCategoryRepository.findAll()).thenReturn(dbLookup())
val carrierService = CarrierService(agentRepository, agentCategoryRepository) // SUT
// when
val translatedList: List<Long> = carrierService.translateToCategories()
// then
assertThat(translatedList).asList().containsExactlyInAnyOrder(CAT_5, CAT_6)
}
Demo
72
● https://github.com/mhewedy/eureka-klient (pure Kotlin app)
● https://gitlab.com/ticketz/ticketz-api (Kotlin + spring boot)
● https://github.com/mhewedy/condition-engine (Kotlin + java + spring
boot)
73
Appendix
74
1. Strong vs Weak types
75
// Kotlin (strong typed)
fun main() {
val x: Float = 10.5f
val y: Int = x // compilation error
println("y = $y")
}
// C (weak typed)
#include <stdio.h>
int main() {
float x = 10.5;
int y = x;
printf("y = %dn", y); // prints 10
}
Resources
76
Resources
● https://www.wikiwand.com/en/Kotlin_(programming_language)
● https://kotlinlang.org/docs/reference/ (very good resource)
● http://shop.oreilly.com/product/0636920052982.do
● http://shop.oreilly.com/product/0636920052999.do
● https://www.manning.com/books/kotlin-in-action
● https://medium.com/sngular-devs/from-closures-to-curry-and-compose-197d2abcadd8
77
Thanks.
78

Introduction to kotlin + spring boot demo

  • 1.
    Introduction to Kotlin Riyadh JavaMeetup Nov 2019 Mohammad Hewedy mhewedy @mohewedy 1 2
  • 2.
    Agenda ● What isKotlin? ● Language Features ● Demos 2
  • 3.
    If I werewriting a Spring app today, I would strongly consider Kotlin. It brings the same kind of simplification to Java code as Spring did to J2EE. Rod Johnson. 3
  • 4.
    What is Kotlin? ●Statically with type inference and strongly typed(1). ● Multi paradigm (object-oriented and functional) ● Fully Interoperate with Java ● Mainly targets the JVM (targets other runtimes as well) ● Semicolons are optional ● Type comes after the variable (val age: Int = 30) (1) see appendix 1 4
  • 5.
    What is Kotlin? ●val keyword used to declare immutable variables ● var keyword used to declare mutable variables ● Classes and class members are public by default ● Classes and methods are final by default ● open keyword used to mark class as extensible and method as overridable 5
  • 6.
    What is Kotlin? ●Interface methods are abstract and open by default ● Has package-level functions as well as class-level functions ● Supports extension functions to patch any library classes with new functionality (a.k.a Monkey patching) ● Support limited set of operator overloading using operator keyword 6 operator fun String.not() = this.reversed() println(!"hello") // prints olleh
  • 7.
    What is Kotlin? ●Functions in kotlin supports: ○ default arguments ○ named arguments ○ variable-length argument lists ● data classes provides: ○ equals()/hashCode() ○ toString() ○ componentN() functions ○ copy() ○ Destructuring declarations: val (name, age) = jane ● Multiline strings with string interpolation ● Delegated Properties that allows lazy variable evaluation 7
  • 8.
    What is Kotlin? ●object used to declare objects, which might used as: ○ singletons ○ companion object ○ Anonymous classes ● Access modifiers: ○ public ○ private ○ protected ○ internal ● Can use to write Domain-Specific Languages (DSL) ● Has Tail call optimization (tail recursion) 8
  • 9.
    Code or Data? 9 config{ datasource { url = "jdbc:h2:mem" username = "root" } webservice { wsdl = "http://example.org/ws?wsdl" action = "urn:weather-ws" } } source: https://gist.github.com/mhewedy/88d0f63486101501c3d87ff9d2e0231b
  • 10.
    Code as Data 10 funmain() { val config = Config() config { datasource { url = "jdbc:h2:mem" username = "root" } webservice { wsdl = "http://example.org/ws?wsdl" action = "urn:weather-ws" } } println(config) } source: https://gist.github.com/mhewedy/88d0f63486101501c3d87ff9d2e0231b
  • 11.
  • 12.
    If as anexpression ● Traditional usage: 12 var max = a if (a < b) max = b
  • 13.
    If as anexpression ● Traditional usage with else: 13 var max: Int if (a > b) { max = a } else { max = b }
  • 14.
    If as anexpression ● As an expression 14 val max = if (a > b) a else b
  • 15.
    If as anexpression ● As an expression 15 val max = if (a > b) { print("choose a") a } else { print("choose b") b }
  • 16.
    When expression 16 when (x){ 1 -> print("x == 1") 2 -> print("x == 2") else -> { // Note the block print("x is neither 1 or 2") } }
  • 17.
    When expression 17 when (x){ in 1..10 -> print("x is in range") in validNumbers -> print("x is valid") !in 10..20 -> print("x is outside the range3") else -> print("none of the above") }
  • 18.
    When expression 18 fun hasPrefix(x:Any) = when (x) { is String -> x.startsWith("prefix") // note the smart cast else -> false }
  • 19.
    When expression 19 when { x.isOdd()-> print("x is in the range") x.isEven() -> print("x is even") else -> print("x is funny") }
  • 20.
    When expression ● whenscoped variables: 20 fun Request.getBody() = when (val response = executeRequest()) { is Success -> response.body is HttpError -> throw HttpException(response.status) }
  • 21.
    For Loops ● Forloops used to for iterates through anything that provides an iterator, which means: ○ has a member- or extension-function iterator(), whose return type: ■ has a member- or extension-function next(), and ■ has a member- or extension-function hasNext() that returns Boolean. 21
  • 22.
    For Loops 22 for (item:Int in ints) { }
  • 23.
    For Loops 23 for (iin 1..3) { println(i) }
  • 24.
    For Loops 24 for (iin 6 downTo 0 step 2) { println(i) }
  • 25.
    For Loops 25 for (iin 6.downTo(0).step(2)) { println(i) }
  • 26.
    Loops and labels ●Kotlin has while loops as well ● Both for and while loops support break and continue (w/o labels) 26 loop@ for (i in 1..10) { for (j in 1..10) { if (...) break@loop } }
  • 27.
    For Loops 27 var counter= 0 operator fun Int.iterator() = this operator fun Int.next() = this operator fun Int.hasNext() = counter++ < this // usage: for (n in 20) { println(n) }
  • 28.
  • 29.
    Classes 29 class Person(val name:String) { var children: MutableList<Person> = mutableListOf(); constructor(name: String, parent: Person) : this(name) { parent.children.add(this) } }
  • 30.
  • 31.
    Classes 31 val invoice =Invoice() val customer = Customer("Joe Smith")
  • 32.
  • 33.
    Inheritance 33 class Example //implicitly inherits from Any
  • 34.
    Inheritance 34 open class Base(p:Int) class Derived(p: Int) : Base(p)
  • 35.
    Inheritance 35 class MyView :View { constructor(ctx: Context) : super(ctx) constructor(ctx: Context, attrs: AttributeSet) : super(ctx, attrs) }
  • 36.
    Inheritance 36 open class Polygon{ open fun draw() {} } abstract class Rectangle : Polygon() { abstract override fun draw() }
  • 37.
    Inheritance 37 open class Shape{ open fun draw() {/* ... */} fun fill() {/* ... */ } } class Circle : Shape() { override fun draw() {/* ... */} }
  • 38.
    Inheritance 38 typealias NodeList =ArrayList<Node> sealed class Node object EmptyNode : Node() data class ValueNode(val value: Any?) : Node() data class ObjectNode(val props: ArrayList<Pair<String, Any?>>) : Node() data class ArrayNode(val elements: NodeList) : Node() source: https://github.com/mhewedy/eureka-klient/blob/de7a1bf2ebec72a3bc1c9ca32868f5d93da32765/src/main/kotlin/helpers/json/Deserializer.kt#L30
  • 39.
    Inheritance 39 fun eval(expr: Node):Unit = when (expr) { is ValueNode -> println(expr.value) // smart case is ObjectNode -> println(expr.props) is ArrayNode -> expr.elements.forEach { eval(it) } is EmptyNode -> print("empty") // the `else` clause is not required }
  • 40.
    Properties and Fields 40 classState(val name: String) class Address { var name: String = "Holmes, Sherlock" var state: State? = null } // used as val address = Address() println("${address.name} at ${address.state?.name}") // note the safe navigation operator with nullable types
  • 41.
    Properties and Fields 41 classMyClass { lateinit var subject: TestSubject @Setup fun setup() { subject = TestSubject() } @Test fun test() { subject.method() // dereference directly } }
  • 42.
    Interfaces 42 interface MyInterface { funfoo() fun bar() { // optional body } }
  • 43.
    Interfaces 43 interface A{ fun foo(){ print("A") } fun bar() } interface B{ fun foo() { print("B") } fun bar() { print("bar") } } class C : A { override fun bar() { print("bar") } } class D: A, B { override fun foo() { super<A>.foo() super<B>.foo() } override fun bar() { super.bar() } }
  • 44.
  • 45.
  • 46.
  • 47.
    Functions 47 fun foo(vararg strings:String) { /* ... */} // calling as foo(strings = *arrayOf("a", "b", "c"))
  • 48.
    Functions 48 fun read(b: Array<Byte>,off: Int = 0, len: Int = b.size) { /* ... */ }
  • 49.
    Functions 49 fun reformat( str: String, normalizeCase:Boolean = true, upperCaseFirstLetter: Boolean = true, divideByCamelHumps: Boolean = false, wordSeparator: Char = ' ' ) { /* ... */ } // calling as reformat(str, normalizeCase = true, upperCaseFirstLetter = true, divideByCamelHumps = false, wordSeparator = '_') // can shuffle args as well
  • 50.
    Functions 50 infix fun Int.shl(x:Int): Int { /* ... */ } // calling the function using the infix notation 1 shl 2 // is the same as 1.shl(2)
  • 51.
    Functions 51 fun dfs(graph: Graph){ fun dfs(current: Vertex, visited: MutableSet<Vertex>) { if (!visited.add(current)) return for (v in current.neighbors) dfs(v, visited) } dfs(graph.vertices[0], HashSet()) }
  • 52.
    Functions 52 class Sample { funfoo() { print("Foo") } }
  • 53.
    Functions ● Classes andobjects can extend functions 53 object Identity : (Int) -> Int { override fun invoke(p1: Int) = p1 } // called as Identity(10)
  • 54.
    Functions ● Lambda withreceiver 54 operator fun Config.invoke(block: Config.() -> Unit) { block.invoke(this) }
  • 55.
    Functions 55 fun add(x: Int):(Int) -> Int { return fun(y: Int): Int { return x + y } } val result = add(10)(30)
  • 56.
    Functions 56 fun add(x: Int):(Int) -> Int { return { y: Int -> x + y } } val addFunc = add(10) val result = addFunc(30)
  • 57.
    Functions 57 fun add(x: Int):(Int) -> Int { return { x + it } } val addFunc = add(10) val result = addFunc(30)
  • 58.
    Functions 58 fun <T> map(x:String, op: (String) -> T): T { return op(x) } // used as map("John Smith", fun(n: String): Int { return n.length })
  • 59.
    Functions 59 fun <T> map(x:String, op: (String) -> T): T { return op(x) } // used as map("John Smith", { it.length })
  • 60.
    Functions 60 fun <T> map(x:String, op: (String) -> T): T { return op(x) } // used as map("John Smith") { it.length }
  • 61.
    Functions 61 fun <E> List<E>.test(op:(e: E) -> Boolean): List<E> { val ret = arrayListOf<E>() for (element in this) { if (op(element)) ret += element } return ret } // used as employees.test { it.age > 25 }
  • 62.
    Functions ● fold isone of most important functional operators 62 fun <T, R> Collection<T>.fold( initial: R, combine: (acc: R, nextElement: T) -> R ): R { var accumulator: R = initial for (element: T in this) { accumulator = combine(accumulator, element) } return accumulator }
  • 63.
    fold (a.k.a reduce):how it works 63source: http://perugini.cps.udayton.edu/teaching/books/PL/www/lecture_notes/currying.html
  • 64.
  • 65.
    Collections 65 val numbers =mutableListOf("one", "two", "three", "four") numbers += "five" val immutableNumbers = listOf("one", "two", "three", "four") immutableNumbers += "five" // compilation error
  • 66.
    Collection Operations ● Transformations ○Mapping (map) ○ Zipping (zip) ○ Flattening (flatmap) ● Filtering ○ Filtering (filter) ○ Partitioning (partition) ○ Testing predicates (any, none, all) ● Plus and Minus 66
  • 67.
    Collection Operations ● Grouping ○Group By (groupBy) ● Retrieving Collection Parts ○ Take and drop (takeWhile, dropWhile, takeLast, dropLast, take(n), drop(n)) ○ Partitioning (partition) ○ Testing predicates (any, none, all) ● Retrieve: ○ At index: (elementAt, []) ○ By condition: (first, last, find, findLast) 67
  • 68.
    Collection Operations ● Order: ○Sorting: (sortBy, sortedByDescending, reversed, shuffled) ● Aggregate: ○ Built-in: min, max, average, sum, count, maxBy, minBy ○ Custom: reduce, fold 68
  • 69.
    So, How tostart? 69
  • 70.
    Write your testcases in Kotlin 70 @Test fun `Test getContentType for image pdf byte stream`() { val pdfBytes = byteArrayOf(0x25, 0x50, 0x44, 0x46, 0x2d, 0x31, 0x2e, 0x34) // %PDF-1.4 val contentType = StreamUtil. getContentType(ByteArrayInputStream(pngPdfBytes), "abc.png") //give invalid name assertThat(contentType).isEqualTo("application/pdf") }
  • 71.
    Test Spring Apps 71 @Test fun`test calling translateToCategories will calculate the agent category correctly`() { // setup val agentRepository = mock(AgentRepository::class.java) val agentCategoryRepository = mock(AgentCategoryRepository::class.java) whenever(agentRepository.findAllById(any())) .thenReturn(listOf(createAgentOfExperience(10), createAgentOfExperience(5))) whenever(agentCategoryRepository.findAll()).thenReturn(dbLookup()) val carrierService = CarrierService(agentRepository, agentCategoryRepository) // SUT // when val translatedList: List<Long> = carrierService.translateToCategories() // then assertThat(translatedList).asList().containsExactlyInAnyOrder(CAT_5, CAT_6) }
  • 72.
  • 73.
    ● https://github.com/mhewedy/eureka-klient (pureKotlin app) ● https://gitlab.com/ticketz/ticketz-api (Kotlin + spring boot) ● https://github.com/mhewedy/condition-engine (Kotlin + java + spring boot) 73
  • 74.
  • 75.
    1. Strong vsWeak types 75 // Kotlin (strong typed) fun main() { val x: Float = 10.5f val y: Int = x // compilation error println("y = $y") } // C (weak typed) #include <stdio.h> int main() { float x = 10.5; int y = x; printf("y = %dn", y); // prints 10 }
  • 76.
  • 77.
    Resources ● https://www.wikiwand.com/en/Kotlin_(programming_language) ● https://kotlinlang.org/docs/reference/(very good resource) ● http://shop.oreilly.com/product/0636920052982.do ● http://shop.oreilly.com/product/0636920052999.do ● https://www.manning.com/books/kotlin-in-action ● https://medium.com/sngular-devs/from-closures-to-curry-and-compose-197d2abcadd8 77
  • 78.

Editor's Notes

  • #28 Iterate over Int by adding iterator() function and then implement next and hasNext for the iterator object (which is the int object in this case as now int is an iterator)
  • #48 Var args and spread operator
  • #49 Default args
  • #50 Default args
  • #51 infix
  • #52 Functions inside functions
  • #54 Operator overloading (invoke operator)
  • #55 Operator overloading (invoke operator)
  • #56 currying
  • #58 Currying and partial function
  • #59 When last parameter is a function
  • #60 When last parameter is a function
  • #61 When last parameter is a function
  • #62 When last parameter is a function: real world example