Learn the Basics of the Kotlin Language

May 22 2024 · Kotlin 1.9, Android 14, Kotlin Playground 1.9

Lesson 04: Discover Operators

Demo

Episode complete

Play next episode

Next
Transcript

Operators are symbols that allow you to perform actions on data. Depending on the type of data, there are specific operations that can be performed on it. Unary operators operate on a single piece of data. However, most operators operate on two operands, namely the left and right operands.

Arithmetic Operators

Arithmetic or mathematical operators perform basic mathematical operations on data. Start a new Kotlin Playground session or use any Kotlin Programming environment you prefer for this demo.

Addition

The addition performs a sum of the operands. + is the addition operator:

println(12 + 4) // Two raw values as operands

In this example, 4 is added to 12. The result is printed in the console, 16.

Subtraction

The subtraction operation finds the difference between two values just like it is in basic math.

val left = 12
println(left - 4) // A variable and a raw value as operands

This performs a reduction of the left-hand side operand, 12, by the value of the right-hand side operand, 4, resulting in the final answer, 8.

Multiplication

The multiplication operator multiplies the operands. You implement this operator by the * symbol:

val left = 12
println(left * 4)

This gives us 48 in the console.

Division

The division operator divides the left operand with the right operand. The forward slash / is the symbol for the division operator.

val left = 12
println(left / 4)

When you run the program, you get 3 as the answer.

Modulos

The modulos operator returns the remainder after performing a division between the operands. It’s represented by the symbol %:

val left = 12
println(left % 5)

The remainder after dividing 12 by 5 is 2. There are two other unary operators Kotlin supports; increment and decrement.

Increment

The increment operator increases a numerical value by 1 and updates the variable containing the data.

var count = 12
println(count++)

Run the code. This prints 12. It doesn’t mean count was not incremented. It was incremented after the print statement was executed. This is post-increment. This is because the increment operator appears after the variable. Print count after the first print statement, and this time you see the updated value:

var count = 12
println(count++) // Prints 12
println(count) // Prints 13

If you want the increment to happen on the same line of code where it’s used, move the increment operator in front of the variable:

var count = 12
println(++count) // Prints 13

This is known as pre-increment.

Decrement

The decrement operator reduces a numerical value by 1 and then updates the operand. In this example, try out both post-decrement and pre-decrement, just as before:

var count = 12
println(count--) // Prints 12
println(count) // Prints 11
println(--count) // Prints 10

It’s the opposite of the increment operator you saw earlier.

Assignment Operators

Assignment operators are used to assign a value to a variable. They work by setting the value of the left operand to the evaluated expression from the right operand. To assign a value to a variable, you put the receiving variable to the left of the equals sign, val count =. Next, set the right side of the equals sign to the calculation you want to assign to the left side, 12:

val count = 12

Augmented Assignment Operators

Augmented assignment operators combine an arithmetic operator with the assignment operator.

var count = 12
count += 3
println(count)

Count is incremented and assigned in place.

Note: If you substitute “+=” for “=+”, the operation behaves like a normal assignment operator.

Logical Operators

Logical operators are used to perform logical operations. These are operations that always result in either a true or false. The logical AND is represented by &&. This operation results in a true if both operands are true:

val isWeekend = true
val hasMoney = true
val isTimeToRelax = isWeekend && hasMoney
println(isTimeToRelax)

Run the program to find out whether it’s time to relax considering that it’s a weekend and you have money :].

Kotlin’s implementation of the logical OR operator is ||. This operator results in a true if any of the operands are true. Otherwise, it’s false.

val isWeekend = true
val isHoliday = false
val isTimeToRelax = isWeekend || isHoliday
println(isTimeToRelax) // Returns true since at least one of the operands is true

With this operation, you only need one of the operands to be true, and the result will be true.

Kotlin uses ! to represent the logical NOT operator. This operator negates a true or false value.

val isWeekend = true
val isWeekday = !isWeekend
println(isWeekday) // Returns false since it negated isWeekend which is true

&&, ||, ! - logical ‘and’, ‘or’, ‘not’ operators, for bitwise operations, use the corresponding infix functions instead.

Equality Operators

To compare two values, Kotlin has the equality operator ==. This compares operands by their values:

val banana = 12
val coconut = 7
val pawpaw = 5
println(banana == coconut + pawpaw) // Returns true since the values are the same on both sides of the operator

This returns true since the number of bananas is equal to the sum of coconuts and pawpaws.

Referential Equality Operators

This compares data by their memory addresses other than the values:

val pet = "Chameleon"
val reptile = "Chameleon"
val amphibian = "Axolotl"
val newPet = amphibian

println(pet === reptile)
println(newPet === amphibian)

A pet is referentially equal to an amphibian because both strings share the same memory address. And the same is true for newPet and amphibian.

Comparison Operators

Kotlin’s comparison operators compare two values. > is the greater than operator. < is the lesser than operator. >= is the greater than or equal to operator, and <= is the lesser than or equal to operator.

val banana = 12
val coconut = 7
val pawpaw = 8

println(coconut < pawpaw)
println(banana >= coconut)
println(pawpaw.compareTo(banana))

There are more pawpaws than coconuts, at least the same amount of bananas as coconuts, and no, pawpaws don’t “compare to” bananas. -1 for pawpaw.compareTo(banana) means, there are fewer pawpaws than bananas and not the opposite. In other words, it’s a false statement to say pawpaws compare to bananas.

The ? operator

This operator marks a variable or object as nullable.

val items: Int? = null
println(items)

The output is null, as expected. Omitting the question mark makes items non-nullable. Thus initializing it with null will result in an error.

The Elvis operator

This Kotlin operator assigns a variable the value to its left if it’s not null, or the value to its right if it is.

val items = null
val amount = items ?: 0
println("Amount to pay: $amount")

From the displayed output it confirms that items was null, hence amount was initialized with 0. If it wasn’t, it’d have been assigned the value of items.

The ?. operator

Just a reminder about null values. If you call a method on a null object, it will result in an error. To avoid this, you can use an if statement to check if the variable is null before calling the method. If it’s null, that portion of the code will not be executed.

val apple: Int? = null
val orange: Int = 5

val total = apple?.plus(orange)
println(total)

Run the code, and you get null. Since apple was null, it wasn’t added to the number of oranges.

The !! Operator

This operator asserts that an expression isn’t null. This then allows you to call methods on the variable as though it were non-nullable.

This is how to use it:

var fruit: String? = null
fruit = "Sugarcane"
println(fruit!!.uppercase())

Take note that you should do your best to avoid using this operator as much as possible; it fights against the null-safety mechanisms Kotlin offers.

The in Operator

The in operator is used to check if an operand contains another operand. This operator works on sequences and collection. The operation searches through the operand on the right for the value of the operand on the left.

Run the following few examples:

val bucketList = arrayOf("Kotlin", "Android", "iOS", "Flutter", "Kodeco")
if ("Kotlin" in bucketList){
   println("Yes! Kotlin is in my bucket list.")
}

The print statement gets executed because indeed, Kotlin is in your bucket list.

The following operators work with collections, sequences, and ranges.

Indexed Access Operator

This is represented by two square brackets []. It’s used to access elements in a collection. Used with a key-value-based type, it receives a value within the square brackets that corresponds with the key.

val romanNumerals = mapOf("IX" to 9)
println(romanNumerals["IX"])

For collections, the indexing is zero-based. Starting from 0, you can access the first item in the collection to the last item:

val romanNumerals = arrayOf("I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X")
println(romanNumerals[5])

As expected, fifth index returns the sixth item.

The Range Operator

The range operator is defined by two dots ... Kotlin creates a range when .. is used between two values. The range of values is the whole set of numbers between and including the left and right operands.

The following example creates a range from 1 to 10:

for (i in 1 .. 5){
   println(i)
}

That’s all for this demo. See you in the next segment.

See forum comments
Cinema mode Download course materials from Github
Previous: Instruction 3 Next: Conclusion