Hi, my name is Nate and welcome to this tutorial on the Kotlin programming language. If

you’re not familiar, Kotlin is a statically
type programming language developed by JetBrains.

It’s been around since about 2011 and has
steadily increased in popularity ever since.

Today it’s actually the primary development
language for Android and in this tutorial

we’re going to move from basic topics like
setting up your first project up to more advanced

things like modeling data and working with
higher order functions. The goal for this

tutorial is to help you understand how the
work with Kotlin so that you can then take

that knowledge and apply it to building applications
across mobile, web and native code. So without

further ado, let’s jump in and start building
our first Kotlin project.

The first thing we’re going to want to do
is to install JetBrains IDE Intelijay so that

we can work with our Kotlin code on our development
machine. The first thing to do is to open

up your browser and search for it. Until Jay
here, you should see a download link and we

can click on that to be taken directly to
the download page. Now I’ll be working on

a Mac, but intelligent is available on windows
and Linux as well. You’ll also notice here

that there are two different versions of intelligence.
There’s the ultimate edition and the community

edition. The ultimate edition has a lot more
features that we need and there’s also a paid

product. The community edition is supportive
for JVM development and Android development,

so it’s perfect for what we want to look at
in this tutorial. When you’re ready, go ahead

and click the download button and that should
start the download. Once the download is complete,

we’ll get started on installing the IDE and
we’ll take a look at hello and Kotlin. Now

that our downloads complete, we can go ahead
and onto the installer

and I’m Mac. We’ll drag the application into
our applications folder which will start the

install process here for us. Once the files
have been transferred to your machine, we

can go ahead and start intelligent for the
first time to start the install process. In

this case, we want to do a fresh install,
so click that. Do not import settings and

hit okay.

Go ahead and accept the privacy policy. Hit
continue. Now here you can choose your theme.

I’ll choose the dark theme. Go ahead with
the standard and tell the J key settings here

and we’ll go ahead and click next through
to finish the setup process and then we’ll

finally launch intelligent IDE community edition.

The next thing that want to do is create our
first Kotlin project here in intelligence.

So to do that we’ll click on create new project.
Now over on the left side of this panel, we’ll

see a number of different project templates
to choose from because we are going to be

learning about Kotlin. We want to make sure
that we have selected the Kotlin template.

Now within this, there are a number of different
Collin project types that we can choose from.

The default here at the top is a Kotlin module
for a JVM target, so this would be sort of

a standard, just Kotlin project that could
target a the JVM. I have nothing else added

to it. Other examples would be, you know Caitlyn
module for a Java script target or I taught

in the native targeted or an Android or iOS
mobile target. So all of those are interesting

but more advanced. For this, we want to just
stick with the basics so we will make sure

that we have selected Kotlin module for JVM
target and go ahead and hit next. Then we

want to make sure that we name our project
something meaningful. So in this case, let’s

call it hello Caitlyn. We’ll make sure that
our project location is set and then we’ll

go ahead and select finish.

Now we have an empty Kotlin project. Let’s
start by adding our first common file so that

we can write a simple hello world example.
So do that. We’ll come over here to the left

and here we have the project panel within
intelligent. You’ll see at the top we have

our hello Collin module. If we expand that
we can see that we have a source directory

but it’s currently empty. That’s right. Click
on source, go to new and then Caitlyn file

our class. And here we’re going to type main
for the name of our file and then we will

leave this as file so that we can create our
main dot KT file. Now we can get started by

writing our main function here in our main
dotK T file. So to start we’ll type in fun

Maine, no parameters and then we can type
print Ellen parentheses.

Hello Collin. And from there you’ll see now
that we have this little green arrow intelligent

recognizes that this is an executable main
function within this uh hello Caitlyn module.

So we can actually go ahead and run this.
We’ll select to run main KT and that’ll take

a second to go ahead and build the project.
And then we will get our output window here

at the bottom and you can see that we have
hello Collin. Now one extra quick fun fact

here and tell Jay comes with a number of live
templates built it. This means that you can

type something and it will know how to complete
that and auto-generate some code for us. So

we can start typing Maine and then hit enter
and it will automatically generate a main

function for us. And then we are free to fill
in with our, hello Caitlyn text.

Awesome. You’ve just written your first program
in Kotlin. Now let’s dive in and start actually

learning the language to get started. Let’s
look at how you can define variables in Kotlin.

Now there’s two types of variables. In Kotlin
we can define mutable variables, which can

have their values reassigned. Those are declared
using the VAR keyword. Or we can define local

read only variables, which can have their
value assigned only once these are defined

using the vow keyword. So to define a variable,
we can use the keyword of our choice. So in

this case we use vow, then we’ll define the
name and then we need to indicate that type.

In this case I’ll say a type string and then
you can use an equals and then you can assign

the value to this variable. So in this case
I’ve defined a variable called name of type

string.

And then I have assigned the string literal
Nate to that variable. Now, like I mentioned,

vow our assign once variables, meaning this
is read only once it has a value assigned

to it. So if I tried to update the name of
this, we’ll see that we get an error. That

area says vow cannot be reassigned. So this
is our indicator that if we need to be able

to update the value of our variable, we’re
not going to be able to use a vow. Instead

we can use a VAR. Now VAR variables can be
reassigned as many times as you want. So as

soon as I updated that keyword, now I can
update the value of our name variable. And

then if we want to use that variable, we can
pass that in to the print function here. And

if we then run our main function, well now
see the output value of that variable at this

time is blank because we had reassigned it.

If we remove that reassignment, well now see
that we get this little underlying saying

variables never modified and can actually
be declared immutable instead using vow. So

this is nice that the IDE gives us that helpful
hint. So in this case we’ll go back to a vow.

And now if we rerun this once again, well
now see that my name was printed out to the

console and this example we’re using a local
variable, meaning that the variable that we

have defined is available locally within the
current scope. So in this case it’s available

Xem them uu diem cua san go cong nghiep so voi san go tu nhien .

only within the main function we have defined.
Now in Kotlin you can actually declare variables

outside of any type of enclosing function.
Our class, all you have to do is declare a

variable within a Kotlin file. So in this
case we’ve moved our variable name outside

of the main function into the main dot. Kate.
He file variables defined like this are referred

to as top level variables. And you see now
that we’ve moved this outside of the main

function, we can still run it and our variable
is still completely valid.

Top level variables can be worked with just
like a local variable. So we get a fine and

an additional variable. This time we’ll say
VAR greeting of type string equals hello.

We now have a publicly available top level
variable called greeting. So now if we wanted

to come down here and print out a greeting
before the name, we could do that by calling

print line and passing in greeting. We can
also modify that greeting because this is

a mutable variable and if we then print out
this new value, we will see that the message

has changed.

So when we hit run here, we should now see
hello Nate. And then hi mate, let’s take a

closer look at how variable types are defined.
So in defining our variables, in both cases

we use either the voucher or VAR keyword and
then we have the variable name. Both of these

are must haves. Next step we have the colon
and then the type. So in this case we have

the type of string and then we assign our
value. One interesting difference between

Java and Kotlin is that types in Kotlin are
non null. By default this means that there

is a distinct difference between string and
a nullable string. Now what does this look

like in practice? Well in this case because
types are non all by default name is a nano

string. So if I tried to assign a no value
to this, we’ll actually get an error and it

will hopefully say no, cannot be a value of
a non Knoll type string. So if you want to

actually have no as a valid value for your
variable, you need to add a question Mark

after that string value. This indicates that
now named as a knowable string. And I can

assign no or I can go ahead and sign an actual
value. So let’s look at how we could use this

with the greeting variable.

So if we make greeting a knowable variable,
we can come down here and we’ll go ahead and

print out the default greeting value. We’ll
print out the name and then we’ll see that

we can modify the value of greeting to null.
And then we can go ahead and print out these

values ones again and we can then see that
greeting has been updated. And when we try

to print that out, it actually recognizes
that it’s no and prints that out to the console

for us. So let’s look at how we can actually
simplify the declaration of our variables.

I mentioned that vow or bar as well as the
name are mandatory. However, Kotlin supports

type inferences on variables and properties.
What does this mean? Well, this means that

Kotlin can recognize what type the value is
that we’re trying to assign to the variable

and if it can figure that out, we can actually
omit a type declaration of the variable.

So in this case we could actually remove the
colon and string and the name variable will

still be of type string. Now we can do the
same for our greeting variable so we can remove

this. But if we come back down here and tried
to assign knowl to greeting will get an error.

No, it cannot be a value of non node type
string. So why is this? Well again, because

types are non nano by default and Kotlin and
we are assigning a nano string literal to

greeting the compiler. In first the greeting
is meant to be a non null string. So if you

want to have a knowable string you might try
and just assign no. However we get a warning

saying implicit nothing type. This is because
greeting now cannot really be inferred. It

doesn’t know what is a null type of. So in
this case we will need to go ahead and specify

a knowable.

Now down here we can assign Knowlton greeting
or we could assign an actual greeting. Now

that we’ve taken a look at how to create variables
and how the type system works, let’s introduce

some basic control flow and we’ll do this
by working with the nullable string variable

of greeting. So let’s go ahead and remove
these values. Now let’s say that we only want

to print out the value of greeting if it’s
not no. So we could do that in a couple different

ways. The first one we’ll look at is using
an if statement, if statements in Kotlin work

very much the same way as in Java. So we’ll
use the if keyword followed by parentheses,

we use greeting. In this case we want to say
if greeting is not no printed out, so we can

say not equal to know and we’ll finish it
off with curly braces.

And then if we move our print statement within
that, if conditional when we run this, we

should now have no greeting printed out. And
sure enough we see that just the name is printed

and if we modified the value of greeting to
be non null and then rerun this, we’ll now

see that we have our greeting. Now what if
we wanted to add and else claws? So just like

Java, we could add the else, we can add curly
braces again. And so here we could define

a default greeting of hi. So now if we run
this once again, greeting will be normal and

so we should see the default high value. Now
another means of control flow within Kotlin

is the when statement. The Wednesday mint
is very similar to a switch statement in Java.

So to create that we can come down and use
the when keyword and then print the CS.

We didn’t want to pass end to this, the value
that we want to check and switch on depending

on its value. So in this case we’ll pass in
grieving followed by curly braces. Now within

this block we can define each value that we
want to act on differently. So in this case

we can say no. And then to define what action
to take, we use an arrow and then we’ll say

print line, hi. And then we can define and
else case here. And this will act as the default

if none of the values above are matched. So
this case we will print out the value of greeting

on its own.

So now if we run this, we should see high
printed out because greeting is still not.

And once again if we update greeting to be
some other value and rerun, we’ll see that

the branch of the, when statement is hit and
we are printing out the value of treating.

So these are two of the basic ways in which
you can manipulate control flow within Kotlin.

Now we just saw how if and when can we use
as statements to take different actions based

on some checked value if and when can also
be used as expressions to assign a value depending

on that, those logical conditions. So let’s
take a look at how we could use an expression

to assign a value to a local variable. So
let’s go down here and type vow greeting to

print. I can say equals. Now if the greeting
variable in our top level declaration is non

no, then we want to go ahead and stick with
that.

So we can say if greeting does not equal null,
then we want to assign greeting to the new

greeting to print variable. Otherwise we want
to say hi and then we’ll update our print

line to use the local variable. Now when we
print this out, we should see the ELs branch

of high being printed out. This is because
the top level variable is currently no. If

we modify this to pass in a greeting. Now
if greeting does not equal null or return

true and we’ll see that hello is printed out
instead. So if we want to assign different

values to a variable, depending on whether
or not something is normal or some other logical

check, we could use an expression. However,
we can also use a when expression if we want

it. So we can say when, and again, we’ll pass
in treating here and again we’ll use our no

value as the first check and if it’s no, we’ll
go ahead and return high. Otherwise we’ll

go ahead and return the original greeting
value. So now with this, when expression is

saying is assign the value of high to greeting
to print. If greeting is know. And likewise

if greeting is nominal, go ahead and assign
that value to the new greeting to print variable.

So if we run this one more time, we should
see high because grieving is null.

And if we assign that value to greeting and
rerun, we’ll see that updated value of hello.

So again, like the if expression a when expression
can be used to assign a value to a variable

depending on that input value that it’s checking
to start understanding functions in top line.

Let’s look at this example. Within this example,
we actually are using two different functions.

We have our main function and then we’re also
using the print LN function as well. So let’s

take a look at how we can define our own new
function. We’ll start by clicking here and

we’ll define the new function that is going
to return this string that we want to print

out to the console. So the first thing to
do when defining any function is to use the

fun keyword. This denotes that we are going
to define a new function.

Then we want to specify the function name.
So I’m going to call this function, get greeting,

and then you want to follow that up with open
and closed parentheses. And within this we

can actually define any function parameters.
Now for now we’re going to skip any function

parameters and we want to define our return
type for this function. So similarly to variables,

we can define a return type by using a colon.
And then the type in this case string. And

then we’ll do open and closed curly braces.
Now like in Java we can define the return

value by saying return. And then in this case
I’ll say hello Kotlin. So now we have the

function called get greeting this green to
return the string. Hello Caitlyn. If we want

to then invoke that function, we can do so
by calling get greeting with open and closed

parentheses.

This should look very similar to what you’re
familiar with and calling methods from Java.

And now if we run our code, we’ll see to print
statements. We’ll see the first one, hello

world. And the second one. Hello Collin. So
one thing you may have noticed is that in

our gig greeting function, we’re the return
type of stream. However, in our main function

there’s no return type specified. So why is
this? Well let’s illustrate this by an example.

Let’s write a function called say hello. So
again we’ll use the fun keyword and it will

maim it. Say hello, no parameter values. And
then we’re going to declare this as returning

type unit unit. And Kotlin is essentially
the absence of any useful type. It’s similar

to saying this returns nothing useful. And
the reason we’re going to use unit in this

case is because we don’t want to return anything.

We’re going to simply print out our get greeting
functions, return value, so we can then call

say hello. And you’ll notice up here that
unit is underlined and it’s giving us this

message that says redundant unit return type.
Basically what this is saying is that if you

have a function that returns unit, that is
to say if you have a function that doesn’t

return anything useful, you can omit that
type value. So we can actually remove unit

from our say hello function and this is perfectly
valid. So that’s why in our main function,

we also don’t have the return type specified.
Aside from the rules around unit return types,

return types or functions work very similarly
to how you would define them and treat them

for variables or properties. So for example,
if we wanted to return a Knoll string from

our get greeting potion, we would modify the
return type to be a nullable string and then

we could return note in our return statement.

Additionally, functions support type inference
as well. So in our get greeting example here

we are returning a single string literal,
in which case we could actually simplify this

to a single expression. We could remove the
curly braces and add an equals and then the

string literal after that. So this is what’s
known as a single expression function because

the entire function definition is now in a
single expression. And now this is where the

title inference comes into play. Again, because
the compiler understands this single expression

function definition and it knows that it’s
always going to return a string. We can actually

remove the explicit return type. Now our get
greeting is extremely simple and is functionally

equivalent to the previous definition. So
if we run our code, once again, we’ll see

that we now have our three different print
statements. You might be noticing a theme

here of Kotlin allowing us to reduce the amount
of code we need to write to get the equivalent

functionality. This is a theme that will crop
up more and more as you start to learn the

language.

Now let’s take a look at how we can define
function parameters. Now before we get started,

let’s clean up our code a little bit. So we’ll
remove everything from our main function and

we’re going to go ahead and remove the existing
function examples we’ve been working with.

So once again, we’re gonna define a function
named say hello and to start it will print

out. Hello Collin. Now this is exactly like
we have seen before, but what if we wanted

to change the thing that we were greeting?
So instead of saying hello Collin, maybe we

wanted to say hello world or hello mate, or
hello John. So how might we do that? Well

that’s where a function parameter comes into
play. So to define a function parameter, we’ll

go within the parentheses after the function
name, and we’ll define this using a notation

of the parameter name colon, the parameter
type. So in this case we’re going to say item

two Crete as our parameter name, colon. And
then we want this to be a string value that

we’re passing it. Now with dinner function,
we can say, Val, message equals hello. Plus

I even went to greet.

Okay.

And then we could pass in the message. Now
if we come down to our main function, we want

to, when folks say hello, so we can start
typing, say hello. And now we need to pass

in a parameter value which it suggest to us
in this little tool tip. So in this case we’ll

say Caitlyn. And now if we run our main function,

we now see hello Kotlin is printed out to
the console. If we wanted to pronounce something

else, we could duplicate the invocation and
maybe this time we’ll pass it in world. And

if we invoke our main function again, we’ll
now see hello Caitlyn and hello world printed

out to the console. Now if we go back up to
our say hello function. Well notice that there’s

this squiggly line here. This is unrelated
to function parameters, but this is a really

interesting feature in Caitlyn. Caitlyn supports
string templates which allow us to substitute

in variable values or argument values into
a predefined string template. So in this case,

instead of using concatenation, we can say
hello space. And then to define a template,

add value, please a dollar sign and then we
can pass in that parameter name. So now if

we hit run once again, we’ll see the same
output as before.

So this is just one more way in which Kotlin
can produce boilerplate for us by allowing

us to define these convenience string templates.
In fact, in this scenario we can take it one

step further and remove the local variable
all together. And then we can actually take

this one step further and define this as a
single expression. Oh shit. Now we have a

say hello function that will take in a parameter
value, which is the item degree. And then

it will always print out hello item degree.
So now let’s update this to take two parameters

so that we can customize both the greeting
and whatever it is that we want to agree.

So to do that, we’re going to add a new parameter
and we will name this one in greeting and

have it be of type string. And now we will
update our string template here to include

that new parameter.

Awesome. So now we’ve updated the function.
Now we need to update the invocation of that

function. So for this first line we can say,
Hey, common and now for the next one we’ll

say hello world and if we read this well now
see our desired output. So by adding that

second parameter value, we have now made our
say hello function much more flexible. Now

we can add any number of parameters we want
to say hello, but like any programming language,

if you have too many parameters in your function,
it might be an indicator that your function

is doing too much. Now what last thing I’d
like to point out about functions at this

time is that you’ll notice that these functions
are not defined within any type of enclosing

class. These are free functions or as they’re
referred to in Kotlin. These are top level

functions like variables, functions can be
defined outside of any in closing class or

independent of any associated class. Now there
are types of functions that are associated

with a class and we’ll take a look at those
later on in the tutorial.

Like most programming languages, Kotlin has
support for collection data types. These are

things like arrays, lists and maps they can
use to group values together and then operate

on them at a later time. So let’s start off
by looking at how we can define inner Ray

and Fallon. We’ll clear out these invocations
to say hello because we won’t need them right

now, but we’ll leave the say hello function
definition because we’ll come back to it later.

Your create a basic array. We’ll create a
new local variable named interesting things

and then we’ll use the equal sign and then
we can use a convenience function called array

of in parentheses. This will create an array
of whatever the inferred type is and then

we can start defining values within this function.
So in this case, as soon as I add a string

literal, it can infer that this is going to
be an array of strings. And then we can define

some interesting things like Kotlin programming
or comic books.

Now that we have this variable defined, let’s
see what types of operations we can perform

on it. If we start typing interesting things
and hit dot the IDE will start to auto-complete

and show us some of the methods available.
So you see we have a size property, we have

a get method, and we also have this open and
closed of bracket syntax that we can use to

access individual elements in the array. Let’s
try printing out some of these values to demonstrate

how we can use the array to start. Let’s print
out the size. We can do that by saying print

LN and then we’ll do interesting things that
size. Now let’s print out the first element

in the array. We can do that by going print,
LN, interesting things. We can use the open

and closed bracket and then pass in an index.
This is how we can conveniently index in fact

array.

This is similar to doing a jet, so if we duplicate
that line, we could say get, and again, passing

is zero element of that array. If we now run
this, we’ll see three Caitlyn, Caitlyn, but

this is just as we would expect. Now, what
if we wanted to iterate over all of the elements

of this array and then perhaps print out each
of those values? Well, there are a number

of different ways we could do that. For now
we’ll take a look at a basic for-loop so we

could start typing for, and then we could
say interesting thing in interesting things.

Then open and closed curly braces. This is
now the convenient syntax of four loops within

Kotlin. So this is going to iterate over each
value in the array and we can access those

values in the interesting thing variable that
we have defined within this four loop.

So now we can type out interesting thing and
if we rerun this code well now see that we

have printed out each element in the array.
So that type of for-loop is what is probably

most similar to what you’re used to if you’re
coming from Java. However, in Kotlin because

we have top level functions and higher order
functions, really just first class of port

for functions across the board, we can write
code that is a bit more functional. So let’s

take a look at how we could do a more functional
approach to collection iteration. So or remove

our four loop and now we could say interesting
things doc for each. And what this is is invoking

a for each function that is available in the
standard library. That function then takes

in a another function and returns unit. That
function that we pass it in essentially defines

what to do on each iteration over this collection.

So within our curly braces here, this is where
we can define what we want to do with each

element in contrasting things. Now this might
look a little bit confusing at first, but

don’t worry well explain this, but if we simply
want to print out each item in this array,

we can now say print LN and pass in it. It
is the default name for each element in the

array that is passed into this Lambda function
in which we are defining. So if we run this

well, now see that we have our three elements
in the array printed out to the console. Now

it is not always very readable. So another
little quick tip here is if you want it to

be named something else, you can rename that
to value that’s passed into the Lambda. In

this case we could call it interesting thing
and then we’ll use the arrow and now instead

of if we can reference that value by calling
it interesting thing and once again if we

run this, we’ll see that our interesting things
are printed out to the console.

You might be looking at this wondering why
we are not using an open and closed parentheses

when calling the for each function. In fact,
it might seem rather odd that we are not passing

in that argument two for each, but instead
of have just specify this open and closed

  Best practices using compilers in Android Studio

parentheses independent of the rest of the
for each call. So this is actually what’s

known as Lambda syntax within Kotlin. Now
we’ll look at how to implement this later.

But the idea behind Lambda syntax is that
if you have a function and it’s only parameter

is another function, then you can omit the
parentheses all together and you can pass

that function in by specifying this open and
closed parentheses. So again, if we look at

for each, we’ll see that it takes a single
function as a parameter so we can omit the

parenthesis values and past that function
into the for each function using the open

and closed curly braces.

And like I said, we’ll look at how we actually
define this type of higher order function

a little bit later in the tutorial. So here
we looked at a basic for each function on

this array collection. But by doing it this
way, we’ve lost the index data for whatever

index the current interesting thing is in
the containing array. So to handle that there

is another function we can call. So once again
we’ll say interesting things and this time

we’ll say for each indexed. Now this time
it’s going to pass into us the current index

as well as the current string. Now once again,
we’ll update this to be named interesting

thing and that one’s again, we could print
out these values. So we can say print,L ,N

and we can say interesting thing is at index.

And now if we print this out, we’ll see that
we have gotten the value from the array as

well as its current index. So this could be
really useful if you need to iterate and still

maintain that index data. Now everything that
we’ve been looking at here for res is applicable

for lists as well. So if we clear out some
of this previous code, we now go to our declaration

of this interesting things variable. Now we’re
using the convenience function array of to

define this variable as an array of type string.
Now there’s also a list of function as well.

Now if we try to work with interesting things,
we’ll see that we have a lot more methods

to choose from because it’s now a list rather
than an array. And so like an array, we can

access individual elements by using a jet
or also by using the bracket syntax like we’re

familiar with with arrays as well.

And also like with the array, we have functions
available to us to help with integration.

So if we wanted to print out all of the interesting
things again, once again we can say interesting

things doc for each ad. Once again we’ll say
interim vesting thing. We use the arrow here

within our Lambda expression and then we’ll
print out the interesting thing and if we

hit run while that we have our three interesting
things printed to the console. Now that we’ve

looked at arrays and lists, let’s take a look
at one more collection type and Kotlin which

is map. So let’s remove this duration over
our interesting things variable here. Now

let’s create a new variable. I’ll just name
this map equals and once again there is a

map of function that we can use. Now the map
of function will essentially take in pairs.

Pair is a simple wrapper class containing
two values and that there is also the convenience

function to create pairs.

So if you want to create a basic key value
map we could do so like this. We’ll use a

key of one and then we’ll use two and then
the value in this case will be a, and then

we’ll define it. Another pair, we’ll use a
key of two. Then we’ll use the two function

and then a value of B. And then we’ll define
one more pair. And we’ll say three is our

key to C. so what we’ve now done is defined
a map with three pairs of values in it. The

keys are one, two and three, and the associated
values are a, B, and C. now we can iterate

over this by saying map for each and it’s
going to return to us both the key and the

value. Unfortunately the default to it, not

very useful name. So this case we’ll remain
them again within our Lambda expression. So

we’ll say key value and then we can print
these out and we’ll use a string template

and we’ll just say key and then we’ll define
an arrow just for some separation and then

value. And now if we print this out, well
now see that we’re giving each of our key

and value pairs and then we could do with
those whatever that we need to. We’ve seen

how you can define several different types
of collections such as arrays and lists and

maps. And we’ve also seen how you can iterate
over those collections and access individual

elements from our collection. And there’s
an interesting thing to point out about the

way Kotlin handles the collections similar
to the way in which it differentiates between

knowable and nano types. Caitlyn also differentiates
between mutable and immutable collection types.

Now what does this mean? This means that by
default a collection type in Kotlin is immutable

so that you can’t add or subtract values from
that collection once it’s initially created.

So let’s look at an example of this. We have
defined our interesting things list using

the list of function here. And if we wanted
to try and add something to interesting things,

there’s no function available to us to do
that. That’s because it’s immutable by default.

If we wanted a immutable list, we could use
the mutable list of function. Now if we want

to add something, we can say interesting things.
Dot add and we could add a new string to our

interesting things list. The same goes for
map. If we wanted to add a new key value paired

wire map, you could say map doc put, but there’s
no put method available. But if we change

to immutable map, now we could say map dot
put and we can define a new key of four and

a new value of D. so this is something to
keep in mind. If you have a collection that’s

going to be static, once it’s defined, then
you’re fine to use the regular list of array

of map up, et cetera functions. And that is
a good thing because immutability is often

a desirable trait in your code. However, if
you’re going to want to modify the values

in that collection, then you’ll have to create
a mutable collection so that you have access

to things like put or add that let you modify
that collection.

Okay,

now that we have an understanding of working
with collections, let’s modify RSA hello function

to take a collection parameter so that we
can greet multiple things, will modify first

the name of item to greet two items to greet
because it’s now going to be plural because

it will be a collection. And that will update
from string to list of string. And then now

we’re going to update the implementation of
this function. So instead of being a single

expression function, we’ll add a function
body. And then now we’re going to want to

iterate over the items to greet parameter.
So we’ll say items to greet dot for each.

And then we’ll paste it back in our original
print statement. And then we’ll go ahead and

update the receiver value here from it to
item to Crete. It’ll add our arrow. And so

now we have a say hello function that you
can pass a collection into. And then it’ll

print out multiple lines. So now we can say,
say hello and we can still pass in our custom

greeting so we can say hi. And then we can
pass it in our interesting things variable.

And now if we click run, we now see high Caitlyn,
hi programming and high comic books. So this

just a quick example of how you can pass it
in a collection type to a function as a parameter.

There’s nothing wrong with including a collection
parameter in your function, however functions.

And Kotlin do provide an additional piece
of functionality that can satisfy this use

case and provides a little additional flexibility.
Now to demonstrate why this might be interesting

to us. Let’s look at an example. So let’s
say we want to call say hello and we’ll pass

on or greeting, but then we don’t want to
pass in any interesting things in this case.

Well, because of the way that this function
is currently defined, we have to pass in the

second argument. So in this case, if we wanted
to pass in no items, we would have to pass

in an empty list, which isn’t really a big
deal, but it’s also not the most flexible

way of handling things. So let’s take a look
and alternative means of achieving this functionality.

If we come up here to our say hello function,
we’re going to modify this second.

So that is a VAR arch perimeter VAR ARG is
a keyword in Kotlin. It essentially represents

a variable number of arguments. So in this
case, instead of taking a list of string,

we’ll define a VAR R of string. This tells
the compiler that we’re going to take a variable

number of string arguments after the initial
greeting argument to this function. So now

if we try to pass something in to say hello,
well first pass in our grieving and now we

don’t actually have to pass anything in after
the initial argument. This is because the

[inaudible] parameter will essentially be
treated as an array of whichever type it’s

used to specify. So in this case, items to
GRI is now an array of type string. So if

we don’t pass any items after the greeting,
it will be treated as an empty array. If we

did want to start to pass items, we can do
that by separating them with commas. So it

could say Kotlin and now this would be an
array of size one. But where the real flexibility

comes is we can now start to define many argument
values here.

And so now all of those arguments that are
passed in will be grouped together, treated

as an array. And so in our function implementation,
we can still iterate over all the elements

in that array. So if we now run this, we should
get the same outfit as before. So by using

our VAR arc parameter, we’ve eliminated the
need to always pass in a value after the initial

greeting argument and lets us have greater
flexibility because it will support zero one

or any other number of argument values to
be passed it. Now it’s very convenient to

be able to pass multiple arguments to this
[inaudible] hard perimeter. However, you’re

usually not going to be hard coding those
arguments in manually during compiled time.

More likely you’re going to get a array of
values from a network request or a database

and then you’re going to want to pass it those
in. So you might think that it would be as

simple as passing in an array after that initial
greeting. So let’s try that. We could change

list of two array of, and then after I,

we’ll pass in interesting things. Oh, unfortunately
this does not work. And if you look at the

air, the see a requires string found array
of string. So how do you actually pass in

an array of existing values to this far ARG
perimeter? Well, you can do that with the

spread operator and all the spread operator
is, is applying the asterisk before the array

variable when you pass it in as an argument
value. So now if we hit run, we’ll see that

the compiler is now accepting that array and
we are iterating over each item in that interesting

things array. So this is how you can pass
in an existing collection as a VAR ARD parameter.

Another really interesting and powerful feature
with Kotlin functions are named arguments.

Now let’s take a look at an example of what
name arguments provide to us. Let’s start

by cleaning out our main function and then
we’re going to define a new simple function

that will take a greeting and a name and then
print that up.

So now when we want to call this new Greek
person function secret person, hi, and then

I’ll use my name here. Now this is fine and
it’s very easy to understand because the ID

is helping us and showing, okay, this is the
greeting argument. This is the name argument.

However, if you are in a code review, you
might not be able to know exactly which order

these arguments are supposed to be passed
in. Also, if you wanted to modify the function

signature of Greek person down the line, you’d
have to make sure that these are in the same

order because since they share the same type,
you could mix that order up without getting

any type of compiler pair. Now what made arguments
allow us to do is specify which parameter

this argument value is going to be used for.
So what does that actually look like in practice?

Well, it looks like defining the name of the
parameter and then an equal sign. And then

here we can say main equals. And so now we’re
saying very explicitly assigned, high to greeting

and Nate. To me, the cool thing that this
allows us to do is actually mix up the order

of these arguments. So now we can actually
pass the second parameter first and the first

parameter second so that we could actually
theoretically modify the signature of Greek

person changing the order of these parameters
and it wouldn’t impact the invocations of

that function. Caitlyn allows us to take this
flexibility one step further by leveraging

default parameter values. So once again, let’s
look at our Greek person example. So here

we are now able to pass the arguments in whatever
order we want. If we’re using name arguments

in tax, but what if we wanted to pass main
first and then not even passing the greeting?

Well now we get an error because it says no
value past for perimeter greeting. So as great

persons currently defined, it must take both
arguments, even if they are in a mixed up

order. Default parameter values allow us to
change that. It allows us to tell the compiler

what the default value should be if not as
specified. So for greeting, we could provide

a default value of hello and for name we’d
get provided default value of Kotlin. You’ll

see now great person can be called by only
specifying a single argument value. And if

we run this, we’ll see. It’s going to say
hello mate. So it’s giving the default greeting

value and then it was using the value for
the name that we passed in now because both

arguments have defaults, we could actually
call this without passing any arguments in.

And if we run it now, we’ll see it’s using
both defaults and prints out.

Hello Kotlin. Now this becomes a really powerful
feature because now we can not only mix up

the order in which we pass arguments, but
we don’t even have to pass all of them in.

This actually allows us to replicate functionality
of the builder pattern without actually having

to write getters and setters and have private
constructors and all of that. We can configure

and reuse functions and objects by leveraging
these default values and the named arguments,

syntax, Wilde, Decaux parameter values, main
argument and VAR. Our parameters are really

convenient and flexible and powerful. They
do have limitations as well. So I want to

illustrate one of those limitations. So we’re
going to go back to our say hello function.

Let’s redefine our interesting things are
right. And so now if I want to invoke, say

hello and I want to pass things in order with
the greeting and then the interesting things

I can do that no problem. And if I run this,
we’ll get our three lines of output.

And so now what if we wanted to use named
arguments in techs? Well we could do that

as well. Breathing equals high. However, as
soon as I add the name argument syntax to

the first parameter, I get this air saying
mixing name and position arguments is not

allowed. So this is one of those limitations.
As soon as you use named arguments in tax

for what argument, everything that follows,
that must also be named. So in this case,

I could fix this by saying items to treat
equals and now I can run this again and I’ll

get the desired three lines of output once
again. Now I could mix these up though

and because both of them are using names,
argument syntax, there are no problems here.

And once again, we could run this and we would
get our desired output.

Now we’re going to take a look at how we can
create a simple class in Kotlin. Now up until

this point, we’ve been working within a single
main dot K T file. However, now that we’re

going to move into classes, let’s go ahead
and add a new file. So we’ll come over to

our project panel, right click source, go
to new Kotlin file or class, and we’re going

to come down and on this dropdown we’re going
to select class and then we’re going to name

this class person and then hit enter. We can
see here, then it automatically has created

a person class for us and I might notice that
this class is quite simple. So let’s take

a look at how this class actually works. To
start, we have the class keyword followed

by the class name and then really that’s it.
We could actually even optionally remove these

curly braces. Since we’re not defining any
properties or methods at this time, if we

wanted to then use this class, we could return
to our main function here. And then we can

create an instance of the class like this.
So we’ll create a variable named person equals

person. Now this syntax right here is how
you create a new instance of a class. Notice

there’s no new keyword and Caitlyn, you do
not have to explicitly call new. You can simply

specify the class name and then the constructor
and any arguments that you need to pass into.

It can may notice

that we were able to create an instance of
the person class using this empty constructor.

However, if we go back to our class definition,
we don’t have any constructor defined. This

is because when you’re defining a class in
Claplan, if you do not have any properties

defined in your primary constructor or any
arguments defined in your primary constructor,

then you can actually just omit that primary
constructor altogether. So what we see here,

class person is really a shorthand form of
this. If we wanted to explicitly define this

primary constructor, we can do so by adding
the constructor keyword and then the opening

closed parentheses. You’ll see here that it
actually gives us a message recommending that

we remove the empty primary constructor. Now
we could also modify this primary constructor

by just removing the constructor keyword and
moving the open and closed parentheses directly

after the classmate. However, we still get
that same recommendation to remove the empty

primary constructor. So let’s add a primary
constructor once again. And this time let’s

actually define a parameter that must be passed
into this constructor. So if we’re creating

a person in class, let’s pass in a first and
last name for this person. So we could say

first name string, last name string.

So now we have two unused parameters that
we pass it into the constructor. And now if

we come back here to the creation of an instance
of our person class, we’ll see that we now

have a compiler error saying no value pass
for our printers. So I’ll go ahead and I’ll

pass it in my first and last name here so
we can come back here and we’re not actually

doing anything yet with these perimeters.
So let’s change that. Let’s define our first

property on our person class. So since we’re
passing in first name and last name, let’s

define properties for first name and last
name. So we can say Val, first name street,

thou last name street. Now you notice that
both of these, now I have red areas underneath

them saying property must be initialized or
be abstract. And there’s a couple of different

ways that we can initialize these.

The first way we’ll look at is using and then
hit block can define it in a net block by

using the unit keyword and then open and close
curly braces. And a net block is a piece of

code that is run anytime. An instance of this
class is run and you can actually have multiple

admit blocks that will be processed in the
order in which they are defined within your

class body. So within this a net block we
can initialize our property values using the

parameters from our primary constructor. So
we’ll say first name equals underscore, first

name, last name equals underscore, last name.
Now we have initialized properties. But if

we look up at where those properties are declared,
we will see these little warnings saying,

can be joined with assignment. What does that
mean? Well this is the other way in which

we could initialize these values.

We could actually get rid of the NIC block
here and we could initialize these at the

point where they’re declared by saying equals
underscore first name equals underscore last

name. So now we’re passing in those parameters
to the constructor and then immediately declaring

and initializing properties on the class.
So now if we go back to our usage of this

person class, after we create the instance
of person, we can now access those properties.

Jax as the properties where you type person.
Dot and then we can access the properties

by their names directly. So we can say last
name or person dot first name. Now you noticed

that we’re not using a getter here in Kotlin.
This is known as property access syntax. You

can reference properties directly by their
name without having to worry about the getter

or the setter. So now if we go back over track
class, we could actually simplify this even

a little bit more. And to do that we’ll go
ahead and remove these properties.

And so now instead of passing in a parameter
to the constructor and then defining a separate

property that mirrors that parameter, we can
actually declare the property directly and

the primary constructor. So to do that, we’ll
come up here, we’ll remove this underscore

since this is now going to be the property
name and then we’ll add the vow keyword. And

now when we have defined a first name and
last name properties within our primary constructor

directly, and if we go back to our usage,
we see that nothing has changed here. We can

still initialize the class in the same way
and still access our last name and first properties

the same way. So far we’ve been working with
the primary constructor within our class declaration,

but it’s also possible to define what are
known as secondary constructors. Secondary

constructors can provide alternative means
for you to instantiate an instance of your

class.

So let’s work with an example. Let’s say we
want to create a secondary constructor that

takes no parameters so that we don’t have
to always pass values in what we want to create

a new person object. So to create a secondary
constructor, we’ll use the constructor keyword

and then open and close parentheses. And in
this example we’re not going to pass in any

parameters. We didn’t need to call through
to the primary constructor. To do that we

use colon and then the this keyword open and
closed parentheses. And then now we need to

satisfy any parameters that are declared in
the primary constructor. So in this case,

let’s define some default first and last name
values. So for our first name we’ll use Peter

and last name. We’ll use Parker.

Okay.

And then we can define a body for the secondary
constructor. And to just take a look at how

this works with the NetBox. Let’s go ahead
and add a print statement here that says secondary

constructor

[inaudible].

Well then add and then that block, and we’ll
put a message here that says, and that one.

And then just for fun, let’s add a second,
a net block after the secondary constructor

and we’ll print out in it too. Now let’s run
our main function and just see what happens.

[inaudible]

so in this case we’re using the primary constructor
so we can specify and explicit values for

the first and last name. So we’ll see that
the secondary constructor is never called,

but both admit box are called and log out
to the console. So now let’s remove the explicit

arguments that are being passed in. And now
let’s rerun this

[inaudible]

and now this time we’ll see that I didn’t
block one is run and Nickboch two is run and

then our secondary constructor was run

[inaudible].

So what this shows is that the admit blocks
are always going to run before the secondary

constructor. Now the Invitbox will execute
in order in which they’re defined within the

class body and the secondary constructor will
be called. Now in this example, and actually

in many practical examples when using Kotlin
on real projects, a secondary constructor

isn’t strictly necessary because of the power
of default parameter values. So in this case

we can remove all of this within our class
body and instead we can define default values

here in the primary constructor.

Okay.

Now if we go back over to our usage, we can
still use the person class as if it had this

empty primary constructor because both parameters
have default values.

Now let’s look a bit more closely at class
properties. Now we’ve already defined two

properties within our primary constructor.
Both of these are read only properties so

they have no center, but they do have a getter
available. That Gitter is how we are able

to leverage property access and tax and reference
those properties directly as we are doing

here in our main function. Let’s explore this
more fully by adding another property. Let’s

add a nickname property. In this case we’ll
use VAR because it’s not going to be set initially.

We’ll call it nickname string and we’re going
to go ahead and make this a notable string

and then we’ll go ahead and set that initially
to know. Now let’s see if we type person.

Dot. We see that we have a nickname property,
but unlike last name and first name, this

is a mutable property.

So we can actually assign a value to this.
So we can say equals. And then my nickname

growing up was shades. So assign that string
to this nickname property. So if we go back

to our person class, let’s look at this property
a bit more closely. We’ve already mentioned

that properties and Caitlyn will get getters
and setters generated for them automatically

by the compiler. So if your property is a
vow, it will have a get or generated. If it’s

a bar, it will have it getter and a setter
generated. But what if you don’t want to rely

on the default behavior of these getters and
senators? Maybe you want to do some complex

logic within that. Or maybe you want to log
something out for debugging purposes. Well,

you can override the behavior of these default
getters and setters and provide your own implementations.

So let’s log out every time a new nickname
is set.

To do that. We go to our nipping declaration
and then we’ll go to the next line and then

we’ll space over four times. And now if we
start typing set, we’ll see auto-completion

comes up with several options here. So I’m
going to choose this bottom one. So what this

essentially does is allows us to define the
function behavior for wins set is called.

Now when we do this, this will generate a
backing field for this property. So to actually

assign the new value to our nickname property,
we need to use a special keyword called field

equals value. If we didn’t make this call,
then the value of nickname would never actually

be updated. And now we are free to implement
whatever you want. So in this case we can

update this with a log message that says the
new make name is dollar value. So now if we

go back over to our main, let’s see what this
looks like. So we’re assigning one nickname,

person that nickname that. Let’s assign a
nother nickname. In this case we’ll just say

new nickname. Now if we run this, we can take
a look at the log. So you see here each time

for assigning a value to the nickname property,
our log statement is being run. Similarly,

we can override the default Gether. We do
this very much the same way. I’ll start by

saying get,

there’s no new value to set so there’s no
value being passed in. So instead we’ll just

lock this out. Say print line. The return
value is dollar field. We still have that

field backing value, which is what his storing
the actual value of nickname. And then we’re

going to return the value of field. So now
we’ll come back over to our main, we’ll use

a print statement here, person dot nickname
and if we run this, we’re seeing that our

center is being called multiple times. Then
our getter is being called and the value logged

out. And then finally our print statement
here in the main function. Now that we’ve

explored class properties, let’s take a look
at how we can add a method to our person class.

To add a method, we really just need to define
it function within our class declaration.

That’s great. A method called print info.
It’ll take no parameters

and it’s just going to print out the user’s
info. So in this case we’ll use a print statement

and then we’ll use a string template to pronounce
the first name, the nickname, and the last

name. So we go back over here to our main
class. Let’s go ahead and remove most of this.

Now if we want to call the method on our person
variable, we can type person dot and then

print info. So now if we run this, we see
Peter, no Parker. So our method worked, however,

the formatting is maybe not quite what we
would have wanted because nickname was no

like print info was called, we printed out
the word no rather than anything possibly

more useful. So let’s refactor this method
a little bit and see if we can improve that.

So that’s great. A variable called nickname
to print. And then let’s check whether or

not this is no. So we can say if nickname
does not equal no, we’ll go ahead and use

the nickname else. We’ll use this more descriptive
string of no nickname and now we can update

this implementation and instead of using nickname
directly, we’ll use this new local variable.

So now if we go over to our main again and
we run this, now we see our output is formatted

a little bit better now while the output now
looks better, this expression right here is

a little bit verbose. This type of check where
we’re comparing whether or not something is

no and then providing one of two values comes
up quite a bit and Kotlin and because of that

there’s actually a convenient syntax we can
use that simplifies this expression. So what

we can do is this like maybe question Mark
Colon, no nickname.

  Performance analysis using Systrace

The question Mark Colon is what’s known as
the Elvis operator and Caitlyn, what this

expression is saying is check what’s on the
left side of the Elvis operator. If that side

of the expression is not no, then go ahead
and return that. Otherwise return what is

ever on the right hand side of the expression.
So if we go back to Maine and run this once

again, well now see that we’re still getting
our updated output. So this case, the Elvis

operator is just a much more concise way of
doing that. If else check. Now I want to take

a minute and talk about visibility modifiers
within Kotlin. Looking at this code here,

you’ll see nowhere do we have any type of
visibility modifier specified. However, if

we go over here to our main, we’re able to
create a new instance of this class. We are

able to call the print info method and we
are able to access all of the properties.

This is because in Kotlin classes, properties,
methods, really visibility in general is public

by default. If we wanted to modify the visibility
of any of these, we can add one of for visibility

modifiers. So from the class we could add
public here. However, because it’s public

by default, this is not needed. We could add
internal. Internal means that this class is

public within the module. So in our case,
because we’re in a single module, this doesn’t

change anything. We can also make this private.

Once we make it private, we’ll now see that
it’s no longer available in our main dotK

T file and this case a private class is only
available within the file in which it’s implemented.

Now we get to apply similar rules to our nickname
property. If we make this an internal property,

nothing changes and we can still access that.
If we make this protected and go back to our

main function, we’ll now see that we’re getting
an air cannot access nickname. It is protected

in person. A protected property or method
will only be available within that class or

within any subclasses. And as you might expect,
if we make this a private property, once again,

we cannot access it from our main dot KT file.
And the same goes for our method. If we make

this private or protected, it’s not going
to be available within main bat. K T now that

we have an understanding of how classes work
in Kotlin, let’s take a look at how interfaces

work. So we’ll go back to our source directory,
go to new Kotlin file or class. This time

in the kind drop down, we’ll select the interface
and let’s go ahead and call this person info

provider and we’ll hit okay.

So now the IDE has created a person info provider
dotK T file and it’s auto generated this empty

person info provider interface for us. Now,
like with the class, because the curly braces

are empty, we can actually remove those and
this is a completely valid interface within

Kotlin. It’s MD. There’s no methods that can
be implemented and there are no properties

that can be implemented. However, this could
still be used as a marker interface, for example,

in other classes, could in fact implement
this interface. In fact, why don’t we do that

right now? Let’s create a class called the
basic info provider, the implements person,

info provider. We can actually do that within
the same file. We don’t need to have one file

per class or interface within Collin. So to
start we can say class basic info provider.

Now we want to indicate that this class is
going to implement person and vote provider.

To do that we’ll use a colon and then we’ll
type the name of the interface and just like

that, we’ve now created a new class basic
info provider that implements person info

provider. And because person info provider
does not currently have any methods or properties,

basic info provider has nothing that needs
to implement. Oh, let’s add a method to our

person. Info provider interface can do that.
We’ll come back up to the interface declaration,

we’ll add back our braces, and now we’re going
to define a function signature within this

interface. Now we don’t have to actually implement
this, we just have to define the name and

the parameters that are required by this method.
Now once we’ve added this, we’ll notice down

below now that our basic info provider class
has a compiler error saying that it does not

implement the required interfaces or add the
abstract keyword.

So let’s take a look at how we can address
this issue. Could you, so we’re going to start

off by adding a main function so that we can
play around with this class. Now what are

the ways that we could solve the compile issue
with basic info provider is by declaring it

as an abstract class. This means it doesn’t
need to implement all the methods available

on the interfaces that includes, but it also
can’t be instantiated. So if we tried to come

down here and say vow provider equals basic
info provider, we’ll get an error saying cannot

create an instance of an abstract

class. So this case we don’t want to make
this abstract cause we do want to work with

this class so we can remove the abstract class
keyword and that we want to actually implement

the required methods from person info provider.
So to do that we can start typing print info

and the IDE will recognize that. And if we
hit enter, it will generate a step down version

of that print info method.

Now let’s take a look at how this was generated.
We see that it starts by including the override

key word. This is different than in Java where
it was an override annotation. And Caitlyn,

if you remove the override keyword, it’ll
actually give you a compile error in this

case saying print info hides member of super
tight and needs the override modifier. So

it’s very specific in indicating that you
do need to include that override. And then

after that it’s simply matches the rest of
the method declaration from the interface.

So here we’re now free to define the behavior
of this interface, however we want you also

seen down below that now that we have implemented
the interface fully, we can actually create

an instance of this class. So if we implement
this right for now, just printing out print

info,

yeah,

we can come down to our main function, we
can type provider doc and then we can invoke

the print info method and we’ll pass it in
a empty instance of the person class and we’ll

see here that it executes that print info
method

[inaudible].

So that’s a very simple example of how we
can define an interface to find a method on

that interface, implement it, and then run
it on that. Implementing class. Let’s improve

upon the implementation of print info. So
here we’re going to say basic info provider

and then below that we’re actually going to
call the print info method on our person class.

So now if we run this, we’ll see that we have
that basic info provider being printed out

and then the info from the person. Now perhaps
we want to encapsulate this logic within the

interface itself. Maybe this print info method,
it should always generally work in this same

way. Well, we could actually move the implementation
that we’ve just defined right here up into

our interface C and Kotlin interfaces provide
default implementation of an interface method.

So now we can actually remove the implementation
of print info from basic info provider and

the code will still compile and run.

So now if we run this, we’re going to get
the same output. However, there’s an issue

with this. We see now in our person info provider
interface, we are including the basic info

providers string. Well, we probably don’t
want that since it is an implementation detail

of basic info provider. So here we could actually
leverage another interesting feature interfaces

in Kotlin. We can provide properties on our
interfaces as well as methods. So we’ll define

a property called provider info of type strength.
Now you might be tempted to give this a default

value, but if you do, you’ll see that we actually
get a compiler error saying property initializers

are not allowed to interfaces. So you will
in fact have to override this and any implementing

class. But now that we have this provider
info string, we could modify our print info

default implementation to print out that provider
info.

So now we’ve kind of encapsulated this logic
into the interface itself. And then the basic

info provider class can now just override
that provider info property. And we override

a property in much the same way as a method.
So we’ll use override vow provider info type

string and then we have to provide the getter.
So in this case we’ll say basic info provider.

And now if we run this once again that we’ll
see that we are picking up the overwritten

property value and then still relying on the
default implementation of print info in person

info provider. And now if we wanted to still
override print info we could absolutely do

that and we could call through to the super
implementation if we would like and then we

can print out anything else here
and if we were in this one last time we’ll

see that we are now relying on the property,
the default implementation of print info as

well as now our additional logic and the overwritten
implementation of print info. Next up, let’s

look at how we can implement multiple interfaces
with a single class. To start we’ll add a

new interface called session info provider

and then we’ll add a method to those called
get session ID and that will return a string.

And so now if we come down to basic info provider,
we want to make this class implement session

info provider as well. Well I’ll be asked
to do is to add a comma after the previous

interface declaration and now add session
info provider as well. And now once we do

that we’ll now see you basic info provider
telling us that we don’t implement the required

methods so we can come down here and implement
get session ID and we can return some session

ID. Now down here on our provider class, we
can now see that we can call get session ID

on our basic info provider instance. Now’s
a good time to talk about how type checking

and typecasting work in Kotlin. To do this
we’re going to create a new function here

called check types and we’re going to take
a parameter of type person info provider.

Now let’s say that we want to check whether
this person info provider is also an instance

of a session info provider. How about we go
about doing that? Well we can say if info

provider is session and vote provider and
then we’ll print that out. Say is a session

info provider. Otherwise print Ellen, not
a session info provider and now we will call

this check types function and we’ll pass in
our provider variable. So now if we run this

we’ll see is a session invoke provider printed
out to the console. So this conditional was

able to determine that the past in info provider
was also an instance of a session in both

provider. Now if we wanted to flip this logic
and check that it is not a session info provider,

we can add an exclamation point before that
and then we’ll just flip these print statements

here and now once again if we run this we’ll
see is a session in both providers.

So you have the flexibility there to check
that either way. Now let’s take a look at

how typecasting works. So within this else
block we’ve already checked that info provider

is a session info provider. So we can cast
it and then call methods on it as if it was

a session info provider. So we could say info
provider as session info provider. The as

is the keyword used to cast something to another
type doc, get session ID. So now we’re able

to cast info provider is that session and
from a provider and call any methods or access

any properties on it that are specific to
session info provider. Now Caitlyn also includes

what is known as smart casting, which means
that if the compiler can check a type and

validate that that type will not change, then
you don’t need to do any additional casting.

So in this case we’ve already validated that
info provider is a session info provider.

So we don’t actually need to explicitly recast
this. We could say info provider dot. Get

session info. And the compiler is performing
a smart cast for us. So here we can access

get session ID or other properties and methods
on the session info provider without having

to explicitly cast it each time.

We’ve never seen how a class can implement
multiple interfaces as an example of our basic

info provider. Let’s now take a look at how
a class can inherit from another existing

class and override methods and properties
on that base class. To start, let’s create

a new file called fancy info provider. Within
this file we’re going to create a new class

called fancy info provider. We didn’t want
this class to extend the basic info provider

that we already defined. So we can do that
by adding a colon and then typing the name

of the class that we want to inherit from
in this case basic info provider. Now as soon

as I do this, you may notice that we have
a red squiggly line here indicating an error.

The error says this type is final, so it cannot
be inherited from this is a characteristic

of classes in Kotlin by default and Caitlyn
classes are closed, meaning they cannot be

inherited from or extended. To extend this
basic info provider class, we meet to add

the open keyword by adding the open keyword,
it now means that you can inherit from this

class. So if we go back to our fancy info

provider, you’ll now see that our error has
gone away and we can now override methods

and properties in this class. Now let’s start
by overriding the provider info property.

So we’ll add the opening closed curly braces
to our class definition and then I can start

typing provider info and you’ll see that the
IDE is suggesting the property available to

us to overwrite. So I’ll hit enter and that
will go ahead and auto complete the property.

Now notice it has the override modifier indicating
that this property is being overridden and

I noticed that it automatically provides a
custom getter and you’ll see that it defaults

to deferring to the super implementation of
this. So we could actually override this just

like this by saying fancy info provider. If
we were to then come back to our main function

here and replace this with an instance of
fancy info provider and we rerun this, what

mousey is printing out fancy info provider
so that provider info is being correctly overwritten

in our new extended class.

Now let’s try overwriting the print info implementation
in our fancy info provider class. So if I

start typing print info, once again, we’ll
see the IDE suggesting the method that can

be overwritten. I’ll hit enter and again by
default this will call through to the super

implementation of print info within basic
info provider. And so I can then add another

line here that just maybe says something like
fancy info. And if I come back and run my

main function and that we’ll see the base
implementation is the basic info provider

implementation. And now this extra line added
by our implementation of fancy info provider.

Now I want to illustrate one last point in
regards to inheritance, but before we do,

let’s refactor basic info provider a little
bit. Instead of hard coding the session ID

here, let’s add a property to hold that value.
So we’ll come here and we’ll say Val and we’ll

say session IB prefix, let’s say equals session.
And now we roll return session ID prefix right

here in our implementation of GIP session
ID. So now if I come into fancy info provider,

I want to override that new session info prefix.

So to do that I might start typing session
and you’ll notice that it’s not auto suggesting

that new property that we just added. This
is because to overwrite a property and a derived

class, you have to Mark that property as open.
This is just like extending a class so we

can come here to session ID prefix and add
the open modifier as soon as we do that. If

we start typing once again, now we’ll see
it’s suggesting the option to override session

ID prefix. So just like the provider info
property, I can now override this and I can

say fancy session. So this is just one other
way in which Kotlin works to enforce immutability.

It forces you to Mark both your classes, your
properties, and your methods as being explicitly

open for extension. Now there’s a small problem
with this new session ID prefix that we’ve

added.

It’s really meant to be an implementation
detail of the class. However, if we come here

to our call site where we’re using a fancy
info provider variable, you might notice that

we can actually access that prefix directly.
This isn’t ideal because like I said, it’s

an implementation detail. Our API shouldn’t
really be exposing that property. Now the

reason it’s available is because we have defined
it as a public property. So what can we do

about this? Well, if we want it to be available
and our child classes but not to the public

API, we could add the protected modifier.
So now that property is protected down here,

when we try to access it, we get an error
saying cannot access session ID prefix. And

if we come back to fancy info provider, you’ll
see that we can still override that property

without any trouble.

Now that we’ve explored how we can extend
an existing named class, let’s look at how

we can create an instance of an anonymous
interclass using an object expression. To

do that. We’ll come over to our main function
here and now instead of instantiating an instance

of fancy info provider, we’re going to create
an anonymous interclass. So we’ll delete that.

And to start off to create our object expression,
we can type object, colon and then the name

of the class that we want to extend. In this
case it’ll be person info provider. Now within

this class we can

override any available properties or methods.
So in this case I’ll update the provider info

and just say something like new info provider.
Now notice below here that our provider dot

get session ID call is now being marked as
an error. That’s because there is no guest

session ID on person info provider. But we
could go ahead and add a new method to our

object expression here. So we can just say
fun, get session, I ID equals and then we’ll

just put in a value here. So you see you can
not only override the existing properties

and methods, but you can add to them as well.
Just like you could in any other name to class.

And now if we run this code, we’ll see new
info provider being printed out to the screen.

So an object expression allows you to create
an anonymous inter class so you don’t have

to create a new named class. So this might
be useful for things like a click listener.

If you were working in, let’s say, Android
development.

Now that we’ve explored object expressions,
we’re going to now look at companion objects.

And to do that, we’re going to create a new
file and we’re going to name that file entity

factory. Now imagine we want to create a factory
to create instances of something called entity.

So to start we might create an entity class
and maybe that class will have a single ID

property to start. Now we want to make this
a factory like we said. So what we might want

to do is change this constructor to be private.
And so now if we add a main function and we

try to create an instance of entity, we’ll
see that we have an issue here. Well notice

that there is this error saying cannot access
in it. It is private to entity. So this is

because of that private constructor. Well,
so what can we do?

This is where a companion object could come
in handy. A companion object is an object

is scoped to an instance of another class.
So within our block body here, we can type

companion object. Now we could create a create
function called fun create and we’ll have

that simply return an instance of entity.
And for now we’ll just pass it in a placeholder

ID. So now we can come back down to our main
function and we can type entity dot companion

dot create. And we can use this to create
an instance of that class. This works because

companion objects have access to private properties
and methods of that in closing class. Now

in this case, we can actually shorten this
by removing the reference to companion altogether.

That new companion is implicit and if you’re
using it from Kotlin, you can leave it off.

However, if you were using this companion
object from Java, you would have to reference

that companion object instance directly. You
can also rename your companion object. So

if we wanted to name this something like factory
to be a bit more explicit, we can then say

doc factory and reference it that way. And
so again, not needed from Kotlin but it could

be a good way to make your code more understandable
from the Java side of things. If you’re doing

a lot of Java to Kotlin interrupt, we can
also store properties within our companion

objects as well. So in this case we can create
a const thou well

ID equals IB and then we can come down here
and replace our entity and pass that in. Now

that we have this ID property added to our
companion object, we can reference it from

other calling code as if it was a static property
like we’re familiar with from Java. So we

could do that by typing entity dot. And then
we can reference that ID property directly.

Now competing objects are like any other class
and that they can also implement other interfaces

to demonstrate that we’ll create a new interface
called ID provider with a single method this

called get ID. It will return a string. Now
then come down to our companion object declaration

and we can make it implement ID provider the
same way we would with any other class. We

can then choose to implement the required
members and then here we will just return

a simple ID and so now when we create our
instance of ID, we could rely on this ID method

if we want it. So you see companion objects
can be quite flexible if you need them to.

You could use those to compose other types
of behavior, store your semi static properties

or methods and use them to create factories
by referencing private inner properties or

methods of the enclosing class. This is really
what you would want to leverage if you want

functionality similar to that of static members

and field from the world of Java. Now that
we’ve covered object expressions and companion

objects, let’s take a look at creating an
object declaration. To start, we’re going

to clean up some of this code we’ve been working
with so we will remove this implementation

of ID provider and we will go back to using
a placeholder ID. We’ll remove this reference

to entity ID and we can remove this ID provider
interface. Now what our object declarations

and object declaration is a convenient way
of creating threads saved singletons within

Kotlin. We can do this by using the object
keyword and then a class name in this case

entity factory. Now within this you can add
any types of properties or methods that you

would like. So let’s start by migrating our
create method from our companion object into

heart entity factory and now we can remove
that companion object and instead we can reference

entity factory dot create.

Now there’s one small problem with this so
far, which is that entity still has only a

private constructor. Now we’re going to remove
that private modifier for now so that we can

use that constructor. However very shortly
we will continue to refactor this code to

limit the ways in which entities can be created.
Now before we go on and continue to explore

some of these other class types in Kotlin,
let’s add to our entity class by implementing

two string so that if we print out an instance
of entity, we get some nice user readable

text. So we can start typing two string. And
then I’ll use a string template here and we’ll

say ID colon is ID. And then we will also
add in a name property here, Val name of type

string.

And then we’ll say name and then substitute
in that main property. And then here in our

create method we will just put in a generic
name. And now down here we can use a print

line statement and pass in our instance of
entity. And now we see our new two stream

texts being printed out to the console. So
this will help us going forward demonstrate

some of how these other classes are going
to work. All right, now that we can print

out useful information about an instance of
an entity, let’s refactor our create factory

method to actually differentiate instances
of entity. So to do this, we’re going to change

this and make it no longer a single expression
function. So we will add a return type of

entity and then we’ll add a return keyword.
And that will, we’ll add entity. Now the first

thing you want to do here is actually add
a proper ID value.

So here you could say Val ID equals you do
ID dot random U U ID dot two string. So this

will give us a new random identifier and then
we can pass that into our entity. But now

we have this main property. So what can we
do to pass in a name here? Well one thing

we might do is think about differentiating
between different types of entities. So in

a very basic case, maybe you want to differentiate
between easy, medium, and hard difficulties

of these entity types. So we might want to
then have some way of passing or indicating

to this factory method, what those different
types should be. So what am I, we could do,

this is with an ENM class. Now if you’re familiar
with Java and Enim class is going to be very

similar to what you’re familiar with from
[inaudible] in Java. To do that, we can start

typing email and then class. And then in this
case we might name this something like entity

type and open and closed curly braces. And
then we can iterate the different instances

of the email. So in this case we might say
easy, medium, hard. So now we can come down

here to our create method and then we can
add a type parameter of entity type.

And so now we could say vow name equals when
type. And then we are going to add in the

remaining branches. So now we have a branch
for each of our entity types. And then for

a basic name, I’m just going to map these
to a string. So say easy, medium and hard.

And so now I can pass in that name. So now
our factory method actually allows us to differentiate

and create different types of instances. So
down here we might start off by creating an

easy entity and then we’ll print that out.
And then we might say vow medium entity equals

entity, factory dot. Create entity tight medium.
And then we can print that out as well.

And if we run this well, now see that we have
a unique identifier for each entity. And then

we have the customized name based on that
entity type. So the addition of this ENM class

to represent our entity type has allowed us
to pass in different types to our factory

method and then customize the way that those
entities are created by mapping the entity

type to a name. Now in this case, we’re mapping
the name very closely to the name of the actual

class itself. So to make this a little bit
easier and more encapsulated, there’s a couple

of things we could do. So the first thing
we could do is take advantage of the name

property on an ITAM class. So to do that,
we could reference our type dot nay. So this

is referencing the name of that actual [inaudible]
class. And if we run this, we can see what

that name looks like.

So you see it’s easy all in capital letters.
This matches exactly the way that the class

name is actually defined. So this allows us
to reference the classes name directly without

having to map it manually. Now this is nice,
however, we don’t have a lot of control over

the formatting here. So another thing we could
do is actually add a new method to argue in

class. So in this case we get add fun, get
formatted name, and then we can reference

that named property.to lowercase dot capitalize.
So this will return us that preform at a name

and capitalize the first letter. So now down
here we can update our medium mapping and

type type dot get format in name. And so now
if we run this code again, we’ll see that

the first one by using the name property directly
is all capitalized. But now by using our new

format and method, we have a nicer format
similar to what we were using before. So that’s

just one example of how you can define an
Enon class and then add additional properties

and methods that class like you would any
other class.

Now let’s continue refactoring this code to
further differentiate between different types

of entities. To do that, we’re going to leverage
a sealed class seal classes allow us to define

restricted class hierarchies. What this means
is that we could define a set number of classes

all extending a base type, but those classes
will be the only ones that can extend that

base type. So one example of this could be
a loading state or results state for a network

operation. It’s either going to succeed or
fail and there aren’t really any other options.

So in the right place we’re going to create
a sealed class with an easy, medium, hard

and help entity types. To start creating our
sealed class hierarchy. We’re first going

to remove the properties from our entity class
as well as this existing override of the two

string method. The next step is to add the
sealed keyword before the class keyword in

the entity class declaration.

As soon as we do that, we’ll start getting
an error above where we tried to create an

instance of entity. This is because you can’t
instantiate based sealed class type directly.

So this is now where we will create each type
within our sealed class hierarchy. So the

first type we’re going to create is a David
class to represent easy entities. And then

we will add the properties we want in this
case the ID and name, and then we want to

make sure that we inherit from entity. So
next up we can copy that and update the name

  How to Film like a PRO with Android Smartphones

for the medium type. And now for the third
type, once again we’ll copy that, we’ll name

this hard, but now we’re going to add an additional
property. This property will be called multiplier

and we’ll be afloat and this can represent
some type of difficulty, multiple fire if

we were creating a game for example.

Now notice that all of these types within
the sealed class all extend from entity but

have different types of properties. This is
one of the key differentiators between sealed

classes and [inaudible] classes. With seal
classes, you can have different properties

and methods on each of these type and the
compiler can perform smart casting to allow

you to use these different properties and
methods as you would like. We can also use

different types of classes itself within our
sealed class. So you notice that these are

all created as data classes. However, if we
wanted to remove data from one of these, that

would be perfectly fine. We could also use
object declarations within our seal class

hierarchy. So this case will create an object
class called help to represent some type of

generic static help entity within our program.
Now because help doesn’t have a constructor

because it’s static. In this case, we can
add a class body and we could add a name and

add help directly. And in this case, more
ad ID. Since it’s a Singleton and there’s

only going to ever be one instance anyways,

now that we have our seal classes defined,
we’re going to update our factory method to

instantiate and return different types of
entity classes. So we’ll come up here to our

return statement and instead of returning
an entity directly, we’re going to use a wind

expression based on the entity type being
in class. We’ll then add all of the needed

branches. And so when we have an easy type,
we want to instantiate an instance of the

easy class. So to do that we’ll type D Z and
then we will pass an ID and name. And similarly

for media type, entity dot. Media ID, combat
name. And now for hard, once again we’ll pass

it and entity dot hard ID name. But now again
we have this additional property type and

the compiler recognizes that. So for now we’ll
just pass it in to F as our multiplier.

Now notice though that we have this help entity
being unused. So let’s update the factory

to allow us to create instances of the help
type. So we’ll come up to our entity type

Unum class and add a help type here. Now notice
as soon as we added that additional type on

the entity type in them class are when expressions
one to us that we need to add an additional

branch. So to do that, I’ll add the remaining
branch here and I’ll default to typed up get

format name. And once again below here I’ll
add the remaining branch. And in this case

I’m just going to return help directly.

Oh, notice here that help is giving us an
error. It’s saying required and to be found

entity that help. This was done to demonstrate
what happens if you do not extend from the

base entity type. So if we come down to our
entity class here and you notice our object

declaration for help, if we then add a colon
entity to extend from entity, we’ll now see

that error go away. So this is a good example
of how the compiler can help give us this

nice static type checking and all of these
things. And if we are combining even classes

was sealed classes with these, when expressions
get allows us to be sure that if we add a

new type or a new branch somewhere that we
have to handle that effectively because the

compiler will warn us or even give errors
if we’re not handling all of those different

branches. Now let’s come down to our main
function and demonstrate one of the advantages

of representing our entities as a seal class
hierarchy.

So if I remove everything, but this first
instance of creating an entity, I’m going

to specifically add a type here of entity.
And so now if we, if we come down again, we

can use a one expression and we’ll say, now
we can go down here and use a wet expression

to do some type checking about the entity
that we have just instantiated. So here we’ll

say Val, message equals when entity. And now
again we’re going to rely on the IBE to add

all the remaining branches. So there’s a few
things of interest to note here. So we’ll

see that for an easy, medium and hard, it’s
adding. This is check. So this is going to

basically tell if it’s an instance of that
class or not. But then notice for the help

class, because that’s an object declaration
and as a Singleton there’s no need to have

it is.

So in that case we can reference that class
directly. And so now here we could add whatever

message we wanted. So we could say help class,
easy class, medium class and hard class. And

then if we simply print that message out and
run the code, we can see in this case we’re

getting an easy class. And then if we change
what we pass into our factory method and rerun

this, well now see that we’re getting the
help class. So now we have static type checking

both and specifying what type of entity we
want back and and checking the type that we’re

actually getting back from that. And so we
could use this to then call any methods or

properties that are specific to that class.
And if we were operating on these types as

in a one expression here, if we ever added
a new type, that compiler would be sure to

make sure that we handled the addition of
that new type.

So now let’s return to our sealed class hierarchy
for a second and dive more deeply into what

data classes are. So you see here both easy
and medium and hard are all defined as data

classes. Data classes are cotton’s way of
providing very concise, immutable data types.

By defining a class as a data class, it means
that it is going to generate methods such

as equals hashcode into string automatically
for you. What this allows us to do is perform

a quality comparisons on instances of these
data classes and treat them as equal if the

data they contain is equal. So here’s an example.
Let’s explore what this looks like. So we

can say Val entity one equals entity factory
that create and will create an easy entity.

And then we’re going to create another version
of this. And then now we can check their equality

comparison.

So you can say if entity one equals entity
two per DeLeon, they are equal else per Delon,

they are not equal to. Now if we run this,
what will we see? They are not equal. And

that’s to the expected. That’s because if
we come back up to our factory, we’ll notice

that we are creating different unique ideas
each time. So even though that the name is

the same, the unique ID is different. So now
let’s update this and see what it looks like

if we pass the same data in. So in this case
we could create an easy directly and this

case will pass in ID comma name and then we
will duplicate this for entity two. And so

now if we run this, we’re going to expect
to see you. They are equal and of course they

are. So this is really convenient. This allows
us to represent data within our applications

and compare this data no matter where it comes
from.

And as long as those properties are all the
same, we’re going to be able to evaluate these

as true. Now another really interesting thing
that data classes give us are effective copy

constructors. So we can create an instance
of entity two by copying entity one entity,

one dot copy. And because this is a direct
copy, if we run this once again, we’re going

to see they are equal. However, we could also
use named arguments with the copy constructor

to change the value. So let’s say we only
wanted to change the BAME and you could say

name equals new name. And once again, if we
rerun this, we’re going to see they are not

equal. So you could see changing a single
property and the data class is going to impact

whether or not two instances evaluate to true
or not when compare.

Now one thing to notice is this is comparing
the value of the data themselves. If we wanted

to U S referential comparison, we hit add
a third equal sign here and this will check

whether or not it’s the exact same reference
or not. So in this case they are not equal.

However, this isn’t all that surprising since
the data was also equal. So what about if

we revert this and make this an exact copy
again? So before if we were just using two

equal sign, the data would be the same. So
it would print, they are equal. However, by

using three equal signs and using referential
equality, we see they are not equal. That’s

because it’s not the same exact reference
of the object. If we updated this to be entity

one equal equal equals entity one and run
this, now we’ll see they are equal.

So that’s just one way in which we can check
whether or not we have the exact same object

or if it’s two different objects that have
the same data. Now also keep in mind that

these equality comparisons are working off
of the generated equals and hash code methods

generated by the compiler when indicating
a data class. However, we could update this

to change how the equals or hash code is evaluated
and to do that we would do it like any other

class. We could add a class body and then
we could simply override equals and or hash

code. Now as in Java best practice, if you’re
going to override one of these, you should

really override both of them and you have
to follow the same rules, but you have that

freedom if you would like to.

Another really useful feature in Kotlin is
the ability to define extension functions

or extension properties on an existing class.
This is particularly powerful if you’re working

with classes that you can’t control but would
like to modify the way in which they’re used.

You can define your own properties and methods
and defined kind of a new API around the existing

class. So an example of this would be adding
a new method to the medium class without actually

defining that method within the definition
of the medium class. So to do that, let’s

come down here and you can start off by typing
the fun keyword. And then instead of directly

typing the method name, we can reference the
class name. Dot. And this case will type print

info.

And then we can define our function buddy.
So in this case we’ll just say medium class

with the ID and that’ll be it. And so if we
wanted to come down here and now create an

instance of entity dot medium directly, we
could do that. And then we could call that

print info method. And if we run that code,
we’ll see a medium class and then that ID

printed out. So this is great if we know that
we have that exact type that we’re working

with. And in cases where we don’t know if
we have that direct type, we could rely on

smart casting. So if we update this to you,
their factory say entity factory, create entity

type medium. Now we can say if entity two
is medium entity, now we can reference that

new print info method.

This is done because the if statement will
only evaluate to true if that cast is successful.

So anywhere within that context it will automatically
perform the smart cast for us. And like I

said before, not only can we define extension
methods, but we can also define extension

properties as well. To do that, we could start
off by saying Val or VAR. In this case we’ll

say vow and then again we’ll reference the
class type. So medium dot we’ll say info will

be this property name string equals some info.
If you do that, notice that we have this air.

If you look, it says extension property cannot
be initialized because it has no backing field.

So to actually create an extension of property
for an existing class, you need to rely on

backing fields. Thankfully the IDE can generate
this forest, convert extension property initializer

to a getter.

So once we do that and notice here that we
have still defined our property but now we’re

relying on this custom getter for that property
and so now if we come back down here within

our, if statement that’s doing our smart cast
for us, we could reference that new info property

directly. So this is how extension functions
and properties work. You could use these anytime

you want to add additional functionality to
existing class. You might notice within the

Kotlin standard library that many functions
and operations work by using extension functions

in classes be are particularly effective when
using them with template ID types

because it allows you to define the same common
functionality across any type that matches

that template. Now up until this point, we’ve
covered a lot of things. We’ve looked at the

basic type system of Kotlin, how to work with
different variable types, how to work with

basic functions and then diving into more
advanced functional topics like named arguments

and default parameter values. And then we
took a deep dive into modeling data with Kotlin.

So now I’m going to circle back to functions
and specifically take a look at higher order

functions and how to work with functional
data types. Now what are higher order functions?

Higher order functions are functions that
either return another function or that take

functions as perimeter values. Now much of
Kotlin standard library is built on top of

higher order functions and it’s what really
allows us to write highly functional code

by leveraging that standard library.

So let’s take a look at how we can write our
own higher order function. To start we have

a new Kotlin file and we’re going to define
a new function. So we’ll call this fun. And

then we’re going to call this print filtered
strengths. And now the first argument to this

is going to be a list of strings. So we’ll
call this list and then define it as list

of string. And now the next thing we’re going
to do is define a parameter which will in

fact be a function. That function will take
in a string and return a bullying. We can

then use that to filter out values in the
past collection. So to define a function parameter,

you could start off by defining the parameter
name as usual. And this case, we’ll name it

credit kit, followed by colon. And now you
have to define the type as you normally would

to define a functional type.

You can start by adding your parentheses.
This will define the parameters of the function

being passed in to your other function. So
in this case we are going to take a string.

He’ll then add the arrow, and then you want
to define the return type. So in this case,

that will be bullying. And now we’ll add the
open and closed curly braces to define our

block body. So now we have a parameter called
predicate, which will be a function that takes

in a string parameter and returns a Boolean.
Now we can implement our print filtered strings

function to make use of that predicate function
to filter out any strings in that past list.

So to implement this function, first off,
we want to iterate over each string in the

past list. So to do that, we could say list
doc for each and now we will be able to iterate

over each of those strings.

So now what we want to do is evaluate the
predicate for each stream in the collection.

So we can call the predicate function in several
different ways. So to start we’ll say if,

and then the easiest way to invoke the predicate
is to simply say predicate open and close

parentheses and pass in the parameter value.
A parameter that is a functional type can

be called as if it was a regular function.
As long as you can satisfy the required arguments.

So in this case we can say if predit kit returns
true, then we can print out that string. Now

to test this, we’ll come down here and we
will add a main function and we will say vow

list equals list of, and then we can say something
like Kotlin, Java C plus plus Java script.

And now we could call print filtered strings
pass in our list.

And now we need to pass in a function as the
second parameter to print filters, drinks.

So we can do that by specifying a Lambda,
and in this case we will say it starts with

K. so this Lambda is going to evaluate to
true if any of the past strings begins with

a K. now if we run this function, we’ll see
only Kotlin print it out to the screen. If

we were to update this to print things out,
that started with a J, well now see Java script

and Java. Now one thing to notice is it in
our invocation of print filtered strings,

we’ve passed our Lambda within the parentheses
of that function in vacation. However, this

is something that we don’t have to do. As
we mentioned earlier, we can take use of Landus

syntax, which says that if the last parameter
of a function is a function, you can specify

that as a Lambda outside the function body.
So we can restructure our function to look

like this. We can pass in the list first and
then specify or Lambda outside of the parentheses.

So this is actually very similar looking to
the for each function which we called up above.

And in fact if you look at the implementation
of for each is in fact a higher order function.

The Lambda that we specify after invoking
for each is a function which will operate

over each string and that list. Now if we
come back up here to our implementation notice

we are calling the function parameter directly
as if it was a regular function. So this works

absolutely great in most situations. However,
if we were to make this function, type a NOLA

ball type by wrapping it in parentheses and
adding new question Mark. Well now see an

error in our implementation of print filtered
strings. That error basically says that you

cannot invoke that function parameter by using
the parentheses directly. If it’s a nullable

type to get around this, we can make use of
the invoke method on that functional type

and then we can make use of the safe call
operator and now, but updating this to do

a safe invoke call on the predicate function.

We can handle this rather not the predicate
is no calling invoke will invoke the function

just as it would any other indication of a
function. So now down here nothing has changed

and how we can call print filtered strings.
However, we could also pass it in list and

now we could pass in no as a no function.
So we’ve seen how we can treat functions as

parameters to other functions and these function
parameters are really treated as tight. Just

the same as let’s say integer or string. Caitlyn
has this idea of functional types. It’s a

first-class part of the language. This means
that we could define a variable of a functional

type and then pass that variable in any time.
We needed a function parameter that matched

that function signature. So an example of
this might be something like vow credit kit

and then we will define our function type
to match that of our print filtered strings

function.

So in this case it’ll take a string and return
bullion and now we’ll define our function

the same way that we were doing it before.
By saying if the string starts with aJ , go

ahead and return true. Now instead of invoking
print filters, strings with a landed pass

to it, we can pass in our predicate variable
directly. And now if we run this, we’ll see

the same output as we would before. So this
allows us to store function as variables.

This can be really useful for things like
optional input handling. For example, maybe

you have a view on some screen and you want
to be able to specify a ClickList center for

that view. You could define that as a Lambda
property on some class and allow client code

to set that ClickList center as needed. As
we mentioned before, higher order functions

include functions which take other functions
as parameters, as well as functions that return

other functions.

So let’s define a function called get print
predicate and it’ll take no parameters, but

we defined its return type as a function which
takes a string and returns a bullion. And

now we can return that value by saying return.
And then we could pass a Lambda and say it.

That starts with J. So we’re passing essentially
the same type of Lambda that we’ve been using

in these other examples. But now we’ve wrapped
it in this other function and so now and so

then passing predicate directly or instead
of defining a new Lambda as our function parameter,

we could instead call get print predicate
as a function on its own, which will then

return a function which then can be used as
the predicate for print filtered strings.

And if we run this once again, we’ll see that
our output hasn’t changed though. So higher

order functions can work as both inputs and
outputs and Kotlin allows you to define properties

with functional types.

So through this function’s really become a
very powerful and first-class part of the

language that can start to replace a lot of
other instances. For example, you might find

yourself relying more heavily on functions
to define things like event or a ClickList

centers rather than defining concrete interfaces
for those same types of functionality. Now

this was recently mentioned. Much of the Kotlin
standard library is built around higher order

functions and especially a higher order functions
defined with generic types. So if we look

at the implementation of four each, well notice
that this is actually an extension function

as well as a higher order function. So for
each works on generic Iterable type and takes

in a function parameter that takes in that
generic type and returns unit. So this essentially

allows us to iterate over each element in
the collection and then call that action on

it and it doesn’t have to return anything.

And similarly for each index takes in a single
function parameter as well. But this one takes

in an event to represent the index as well
as the generic type. This allows us to iterate

over each element in the collection while
incrementing a counter and then passing that

counter into the function parameter as the
index. The power of generic types, extension

functions and higher order functions allows
us to write single implementations of these

methods and then reuse them over any type
that we can think of. Now this is very powerful

and can allow us to write much more functional
code without having to redefine these methods

and functions for all of our different types.
So let’s take a look at example of how we

can combine some of these different functional
operators to perform complex operations with

very little code. We’ll come into this new
main function here and we’ll start off by

defining a list of strings.

Once again. Now let’s look at some ways in
which we can chain these functional operators

together to do more interesting things. So
as we’ve seen before, we can do a simple for

each to iterate over each item in this collection
and print it out. And if we run it, we’ll

notice that we see all of the programming
language printed out to the console. Now what

if we wanted to print out only the strings
that start with J plus similar to the functions

we were working with before, we could do that
by making use of a filter operation. So we

have a lot of options to choose from. In this
case, we will just choose a generic filter

and then we will use a predicate which says
it starts with J and now if we run this was

he, he had only Java and Java script printed
out. Now, what if our collection included

some no values?

So as soon as we add, no, we see now here
in our filter operation, it’s warning us that

Hey, this value might be no, you need to add
a safe call weld in Kotlin. Oftentimes we

don’t want to work with no, we want to try
and hide no as much as possible. And so we

could make use of another functional operator
called filter not know. What this does is

immediately filter out any no values up front.
So everything past that in the functional

chain will be guaranteed to be not. No. So
as soon as we added filter, not know, we no

longer had to deal with a possible no string.
And if we run this once again, we’ll see only

Java and JavaScript printed out.

Now what if we wanted to change the type of
this? Let’s say we wanted to convert this

from a string to an integer, which represents
the length of that input string. We could

do this type of transformation using a map
function. The map function will take in whatever

the previous type is in this case string,
but it’ll allow us to return any other type

we want. So in this case, we might define
our map function as simply returning the length

of the string. As soon as we’ve done that.
Now below that in the for each, the type has

changed from string to end. And now if we
print this out, we’ll see four and 10 printed

out for representing the four characters in
Java and 10 representing the 10 characters

in Java script. Now let’s remove this mapping
and let’s remove the filter. And instead,

let’s imagine that we want to take only a
certain number of items from this collection.

So we can do that by using the take function
and passing in. Let’s say three. What that’ll

do is we’ll take the first three items from
that collection and then we’ll be printing

out each of those three names. So you see
in this case we’re getting Kotlin, Java and

C plus plus. Alternatively, if we didn’t want
to take the first three elements in the collection,

we could use take last today, the last three.
So in this case we see Java C plus plus and

Java script and it has skipped over Kotlin
since that was not one of the last three elements.

We can also do other transformations such
as associating the input values with some

other value to return a map. So let’s create
a map that essentially maps the string to

the number of characters in that string. So
to do that we could say associate, and then

in this case we could say it to it dot length.
And so now in our, for each function, instead

of iterating over strings, we’re iterating
over map entries of string and event. So in

this case we can now use a template string
and say it got value comma it dot key.

And if we print this out, we’ll see the length
comma followed by the name. This makes it

really easy to map all of the input strings
to some other value and then iterate over

that map. Now, what if we didn’t want to iterate
over the map but instead just wanted to hold

on to that in a variable? Well, instead of
using a fork each at the end, we could assign

this to a variable just like this. The continent
standard library also provides a variety of

functions to help us pull out individual elements
from a collection to demonstrate that that’s

created a variable called language. And then
we’re going to perform different operations

on our list to grab a single language string
from our list. So we could do that in a number

of ways. We could say list dot first and if
we print this out, we’ll expect to see Kotlin

as that is the first language in the list.

Alternatively, we could say we’ll start last
and in this case you’ll see that it’s actually

printing out. No, since [inaudible] was the
last value in that list. Now, if we didn’t

want to retrieve a null value from our list
and instead wanted the Alaskan non-male value,

once again, we could add the filter, not no
function, which we used previously. And now

if we rerun this, we’ll see Java script printed
out instead, since this is the last non no

value. Now what if we wanted to find a specific
item in the list? Let’s say we wanted to use

the find function and in our predicate we’ll
say it got starts with and we’ll pass in Java

as a street. So this is going to find the
first value in this list that starts with

Java. So in this case it actually returns
us Java and alternatively we could use find

last to find the last element in the collection
that matches this predicate, in which case

it’s going to return JavaScript.

Now what happens if we are searching for a
string which doesn’t match our predicate?

We can test that by looking for a string which
starts with food. If we then run this, we’ll

see no print it out to the console. This is
because there is no matching string. So fine.

Last is going to return. No. And then the
print line statement, we’ll print out. No

if it has a null value. Well what if we didn’t
want to work with no? What if instead we wanted

to use an empty string as the placeholder?
Well, strings in Kotlin have a useful function

called or empty. So we can actually chain
that directly off of find last here and call

or empty. So at this will do is return either
a nano string or a static empty string. So

now if we run this once again, instead of
no, we’re just seeing empty, we’re not printing

anything out.

So this is one way in which you could default
your collections or your strings to an empty

value as opposed to a no value. And this is
something you might want to consider doing

more and more of in Kotlin as you start to
move away from relying on null. So as we’ve

seen, Caitlyn has first-class support for
functions including functional types and higher

order functions, and the Kotlin standard library
builds upon those tools and provides a rich

set of functional operators for us to use.
This allows us to build powerful functional

chains to transform our data and make complex
workflows much simpler. All right, that’s

it for this tutorial. You now have a good
understanding of the fundamentals of Kotlin

and how to work with it, and you’re now ready
to start taking that knowledge and applying

it to other domains. Until next time, devs.

You cannot copy content of this page