8. Operator overloading
a == b a > b
a != b a < b
a >= b
a <= b
a + b a +- b a++ a..b
a - b a -= b a-- a in b
a * b a *= b a !in b
a / b a /= b a[]
a % b a %= b a()
9. Lab 6
• Reverse the words in a sentence
• Write a kotlin program to reverse each word in a sentence, so
“cat and dog” became “tac dna god”
10. Lab 7
• Generate all passwords from given character set
• Given a set of characters generate all possible passwords from
them. This means we should generate all possible permutations of
words using the given characters, with repetitions and also upto a
given length.
Example:
Input : arr[] = {a, b}, len = 2.
Output :
a b aa ab ba bb
11. Lab 8
• Geofence App
• Build a geofenc Android app tacking into
consideration the following :
• The phone is turning silent when the user
enters ITI premises.
• The phone is turning back to normal mode
when the user exits ITI premises.
• Use the following :
• Use Android geofencing API
• Use Servcies
• Optional : Use MVP or MVVM
• Optional : sync with Firebase Firestore
23. Late initialization
class KotlinActivity: Activity() {
var myData: MyData? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
myData = intent.getParcelableExtra("MY_DATA")
}
... myData?.foo ...
}
24. class KotlinActivity: Activity() {
lateinit var myData: MyData
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
myData = intent.getParcelableExtra("MY_DATA")
}
... myData.foo ...
}
Late initialization
25. If the property wasn’t initialized
Still runtime exception, but with the detailed message
kotlin.UninitializedPropertyAccessException: lateinit
property myDatahas not been initialized
... myData.foo ...
What is the difference between lateinit and Lazy ?!
32. Full primary constructor syntax (1)
constructor parameter
class Person(name: String) {
constructor body
init {
}
}
33. Full primary constructor syntax (2)
constructor parameter
class Person(name: String) {
val name: String
constructor body
init {
this.name = name
}
}
34. val/var on parameter creates a property
class Person(name: String) {
val name: String
init {
this.name = name
}
}
class Person(val name: String)
is the same as:
38. Enum class
represents enumeration
import Color.*
enum class Color {
BLUE, ORANGE, RED
}
fun getDescription(color: Color) =
when (color) {
BLUE -> "cold"
ORANGE -> "mild"
RED -> "hot"
}
39. Data modifier
generates useful methods:
equals, hashCode, copy, toString, and some others
data class Contact(val name: String, val address: String)
contact.copy(address = "new address")
44. Object = singleton
public class JSingleton {
public final static JSingleton INSTANCE = new JSingleton();
private JSingleton() {
}
public void foo() {}
}
object KSingleton {
fun foo() {}
}
45. companion object
Special object inside a class (Static)
class A {
companion object {
fun foo() = 1
}
}
fun main(args: Array<String>) {
A.foo()
}
46. No static keyword
Declare “static” members:
- at the top-level
- Inside companion objects
- Use annotation @JvmStatic
47. Constants
• By default, top-level properties, just like any other properties, are
exposed to Java code as accessor methods
• a getter for a val property and a getter/setter pair for a var
property
• If you want to expose a constant to Java code as a public static
final field, to make its usage more natural, you can mark it with the
const modifier (this is allowed for properties of primitive types, as
well as String)
48. Compile-time constants
for primitive types
and String
const val answer = 42
const val UNIX_LINE_SEPARATOR = "n"
/* Java */
public static final String UNIX_LINE_SEPARATOR = "n";
50. Exceptions in Kotlin
• Exception handling in Kotlin is very similar to Java and many other languages
if (percentage !in 0..100) {
throw IllegalArgumentException( "A percentage value must be
between 0 and 100: $percentage")
}
51. 'try' as an expression
fun readNumber(reader: BufferedReader) {
val number = try {
Integer.parseInt(reader.readLine())
} catch (e: NumberFormatException) {
return
}
println(number)
}
>>> val reader = BufferedReader(StringReader("not a number"))
>>> readNumber(reader)
Nothing is printed
52. 'try' as an expression
fun readNumber(reader: BufferedReader) {
val number = try {
Integer.parseInt(reader.readLine())
} catch (e: NumberFormatException) {
null
}
println(number)
}
>>> val reader = BufferedReader(StringReader("not a number"))
>>> readNumber(reader)
An exception is thrown, so the function prints "null".
67. Nothing is different to Unit/void
fun fail(message: String): Nothing {
throw IllegalStateException(message)
}
It means “this function never returns”
68. “a type that allows
only one value
and thus can hold no
information”
Unit Nothing
“a type that has
no values”
“the function completes
successfully” “the function never
completes”
72. What is Functional Programming?
• A style of programming that treats computation as the evaluation
of mathematical functions
• Eliminates side effects
• Treats data as being immutable
• Expressions have referential transparency
• Functions can take functions as arguments and return functions as
results
• Prefers recursion over explicit for-loops
73. Why do Functional Programming?
• Allows us to write easier-to-understand, more
declarative, more concise programs than imperative
programming
• Allows us to focus on the problem rather than the
code
• Facilitates parallelism
74. Java 8
• Java 8 is the biggest change to Java since the
inception of the language
• Lambdas are the most important new addition
• Java is playing catch-up: most major programming
languages already have support for lambda
expressions
• A big challenge was to introduce lambdas without
requiring recompilation of existing binaries
75. Benefits of Lambdas in Java 8
• Enabling functional programming
• Writing small more compact code
• Facilitating parallel programming
• Developing more generic, flexible and reusable APIs
• Being able to pass behaviors as well as data to
functions
76. Example 1:
Print a list of integers with a lambda
List<Integer> intSeq = Arrays.asList(1,2,3);
intSeq.forEach(x -> System.out.println(x));
• x -> System.out.println(x) is a lambda expression that
defines an anonymous function with one parameter named x of
type Integer
77. Example 2:
A multiline lambda
List<Integer> intSeq = Arrays.asList(1,2,3);
intSeq.forEach(x -> {
x += 2;
System.out.println(x);
});
• Braces are needed to enclose a multiline body in a lambda
expression.
78. Example 3:
A lambda with a defined local variable
List<Integer> intSeq = Arrays.asList(1,2,3);
intSeq.forEach(x -> {
int y = x * 2;
System.out.println(y);
});
• Just as with ordinary functions, you can define local variables inside
the body of a lambda expression
79. Example 4:
A lambda with a declared parameter type
List<Integer> intSeq = Arrays.asList(1,2,3);
intSeq.forEach((Integer x -> {
x += 2;
System.out.println(x);
});
• You can, if you wish, specify the parameter type.
80. Implementation of Java 8 Lambdas
• The Java 8 compiler first converts a lambda expression into a
function
• It then calls the generated function
• For example, x -> System.out.println(x) could be converted
into a generated static function
public static void genName(Integer x) {
System.out.println(x);
}
• But what type should be generated for this function? How should it
be called? What class should it go in?
81. • Is an interface
• Must have only one abstract method
• In JDK 7 this would mean only one method (likeActionListener)
• JDK 8 introduced default methods
• Adding multiple inheritance of types to Java
• These are, by definition, not abstract
• JDK 8 also now allows interfaces to have static methods
• @FunctionalInterface to have the compiler check
Functional Interface Definition
83. @FunctionalInterface
public interface Predicate<T> {
default Predicate<T> and(Predicate<? super T> p) {…};
default Predicate<T> negate() {…};
default Predicate<T> or(Predicate<? super T> p) {…};
static <T> Predicate<T> isEqual(Object target) {…};
boolean test(T t);
}
Yes. There is still only
one abstract method
Is This A Functional Interface?
84. @FunctionalInterface
public interface Comparator {
// Static and default methods
int compare(T o1, T o2);
boolean equals(Object obj);
}
The equals(Object)
method is implicit from
the Object class
Therefore only one
abstract method
Is This A Functional Interface?
85. • A stream pipeline consists of three types of things
• A source
• Zero or more intermediate operations
• A terminaloperation
• Producing a result or a side-effect
Source
int total = transactions.stream()
.filter(t -> t.getBuyer().getCity().equals(“London”))
.mapToInt(Transaction::getPrice)
.sum();
Intermediate operation
Terminal operation
Stream Overview
86. Stream Overview
Many Ways To Create
• From collections and arrays
Collection.stream()
Collection.parallelStream()
Arrays.stream(T array) or Stream.of()
• Static factories
IntStream.range()
Files.walk()
87. Stream Terminal Operations
• The pipeline is only evaluated when the
terminal operation is called
• All operations can execute sequentially or in parallel
• Intermediate operations can be merged
• Avoiding multiple redundant passes on data
• Short-circuit operations (e.g. findFirst)
• Lazy evaluation
• Stream characteristics help identify optimisations
• DISTINT stream passed to distinct() is a no-op
88. Optional Class
• Terminal operations like min(), max(), etc do not
return a direct result
• Suppose the input Stream is empty?
• Optional<T>
• Container for an object reference (null, or real object)
• Think of it like a Stream of 0 or 1 elements
• use get(), ifPresent() and or Else() to access the stored
reference
• Can use in more complex ways: filter(), map(), etc
90. What’s an average
age of employees
working in Prague?
Working with collections in a functional style
val employees: List<Employee>
data class Employee(
val city: City, val age: Int )
employees.filter { it.city == City.PRAGUE }
.map { it.age }
.average()
98. Function type
val sum = { x: Int, y: Int -> x + y }
val sum: (Int, Int) -> Int = { x, y -> x + y }
99. Storing lambda in a variable
val list = listOf(1, 2, 3, 4)
list.any(isEven)
list.filter(isEven)
true
[2, 4]
val isEven: (Int) -> Boolean =
{ i: Int -> i % 2 == 0 }
100. Passing member reference as argument
fun isEven(i: Int): Boolean = i % 2 == 0
val list = listOf(1, 2, 3, 4)
list.any(::isEven)
list.filter(::isEven)
true
[2, 4]
101. Class References & Function References
Class References:
• The most basic reflection feature is getting the runtime
reference to a Kotlin class. To obtain the reference to a
statically known Kotlin class, you can use the class literal
syntax:
val c = MyClass::class
102. Class References & Function References Cont.
Function References
When we have a named function declared like this:
fun isOdd(x: Int) = x % 2 != 0
We can easily call it directly (isOdd(5)), but we can also use it as a
function type value, e.g. pass it to another function. To do this, we use
the :: operator:
val numbers = listOf(1, 2, 3)
println(numbers.filter(::isOdd))
Here ::isOdd is a value of function type (Int) -> Boolean
103. Getters and Setters
• The full syntax for declaring a property is
var <propertyName>[: <PropertyType>] [=
<property_initializer>]
[<getter>]
[<setter>]
Example:
val isEmpty: Boolean
get() = this.size == 0
104. Getters and Setters Cont.
var stringRepresentation: String
get() = this.toString()
set(value) {
setDataFromString(value) //
parses the string and assigns values to other
properties
}
105. Getters and Setters Cont.
var setterVisibility: String = "abc"
private set // the setter is private and has
the default implementation
107. Kotlin Android Extensions Plugin
• What it does?
• Provides reference to all layout views (which have id’s) with
single line of code.
• How?
• Adds a hidden caching function and a field inside each Kotlin
Activity.
116. alert("Santa", "You were a good boy?") {
positiveButton("Yes") { toast("You are now in GOOD list") }
negativeButton("No") { toast("You are now in BAD list") }
}.show()
val countries = listOf("Ukraine", "USA", "UK",)
selector("Where are you from?", countries) { i ->
toast("So you're living in ${countries[i]}, right?")
}
Anko
117. async() {
// long background task
uiThread {
// won't be executed if isFinishing() is true
toolbar.title = "Done"
}
}
Anko
120. Android KTX
• A set of Kotlin extensions for Android app development.
• The goal of Android KTX is to make Android development
with Kotlin more concise, pleasant, and idiomatic by
leveraging the features of the language such as extension
functions/properties, lambdas, named parameters, and
parameter defaults.
• It is an explicit goal of this project to not add any new
features to the existing Android APIs.
121. Animator functions
• In KTX we can set an animation listener on an animator
instance
• We can even add function for specific callbacks of the
listener, you’ll only need to pass functions for the callbacks
that you want to receive data for
animator.addListener{ handleAnimation(it) }
animator.addListener(
onEnd = {},
onStart = {},
onCancel = {},
onRepeat = {}
)
122. Content
• There are a bunch of extension functions that have been added
within the Content package.
• If we need to retrieve system service then there is an extension
available for us to do so
• Performing write operations to shared preferences is now super
nice with the use the edit function:
val alarmManager = systemService<AlarmManager>()
sharedPreferences.edit {
putBoolean(key, value)
}
123. Time operations
• KTX also offers a collection of operations related to Time.
Let’s take a look at what there is currently on offer.
• The Duration class also has a bunch of functions available:
DayOfWeek.FRIDAY.asInt()
Month.APRIL.asInt()
Year.now().asInt()
// Retrieve values from destructuring
val (seconds, nanoseconds) = Duration.ofSeconds(1)
124. Time operations
• The Instant, LocalData, LocalDateTime, LocalTime properties can also be
accessed by these functions:
• These following functions are really cool additions, these allow us to
easily take an Int value and retrieve the corresponding representation for
the given function call:
// Retrieve values from destructuring
val (seconds, nanoseconds) = Instant.now() // Retrieve values from destructuring
val (year, month, day) = LocalDate.now() // Retrieve values from destructuring
val (localDate, localTime) = LocalDateTime.now() // Retrieve values from destructuring
val (hour, minute, second, nanosecond) = LocalTime.now()
someInt.asDayOfWeek() // return DayOfWeek instance
someInt.asMonth() // returns Month instance
someLong.hours() // returns Duration instance
someLong.millis() // returns Duration instance
125. OS
• There are a collection of functions provided for the android OS
package. This includes some extensions to working with the handler
class:
• Creating new instance of the Bundle class is now also a lot nicer:
handler.postAtTime(uptimeMillis = 200L) {
// some action
}
handler.postDelayed(delayInMillis = 200L) {
// some action
}
val bundle = bundleOf("some_key" to 12, "another_key" to 15)
val bundle = persistableBundleOf("some_key" to 12, "another_key" to 15)
126. Other packages
• Utils
• Database Cursor
• SQLite
• Resources
• Text
• Net
• Graphics
• Transitions
• Views
• ViewGroup
• Margins
Refrenace:
https://android.github.io/android-ktx/core-ktx/
127. Getting Started
• To add Android KTX to your project, add the following to
your app module's build.gradle:
• Then, in your Kotlin files where you'd like to use the
extensions, import the appropriate packages.
repositories {
google()
}
dependencies {
implementation 'androidx.core:core-ktx:0.3'
}
128. Lab 9
• To-do App
• Build a to-do Android app tacking into
consideration the following :
• User can add and delete to-do
• Optional : user can mark task as done
• Each task has a name and a due data.
• Use the following :
• Use offline storage (Realm, Objectbox or
Room).
• Optional : Use MVP or MVVM
• Use RecyclerView
• Optional : sync with Firebase Firestore
130. Some Advice - General
• Contribute to StackOverflow
• Challenge yourself
• Great exercise in practical problem-solving
• Looks nice on your CV
• Arguably, the best way of learning is to get a question and find an answer for it
• Take part in OpenSource projects on GitHub
(and/or your own projects)
• Read others code, do code reviews – try to notice good and bad practices from others
• Gives a great practical experience with team work, code source control, problem
solving
131. Some Advice - Android
• Read twitter, blogs, listen to podcasts:
• http://fragmentedpodcast.com
• @chethaase, @JakeWharton, @Piwai, @ianhlake,
@AndroidDev, @dontmesswithjo, @yigitboyar
• https://android-developers.googleblog.com
• Udacity - free video-courses about Android & all other cool
technologies
• https://www.udacity.com
• Most code you need is already written - use Open Source
Libraries
132. Some Advice - Android
• Square, Inc & Jake Wharton are main contributors into Android
community. Check out their GitHub-repository: http://square.github.io
• If you want to be a professional, these libraries are mandatory:
• Standard Pack
• Picasso, facebook/fresco, Glide
• ButterKnife
• Parceler
• IcePick
• LeakCanary
• Okhttp
• Retrofit
• EasyPermissions
• Objectbox
• Realm
• Advanced Pack
• Dagger 2
• EventBus
• Espresso
• Robolectric
• Lottie
• Activity Recognition API
• Smart Lock for
Passwords on Android
• RxJava