Kotlin Operators: Arithmetic, Relational, Logical, Elvis ?:, Safe Call ?. & Precedence

1. What are Arithmetic, Relational, Logical, and Assignment Operators in Kotlin?

Arithmetic Operators: Perform mathematical operations on numeric types.

Relational Operators: Compare values and return Boolean.

Logical Operators: Combine boolean expressions.

Assignment Operators: Assign values, often combining arithmetic.

Use Case: Calculations, comparisons, and updating variables.

Example: Arithmetic, Relational, Logical, and Assignment Operators

// Arithmetic, relational, logical, and assignment operators
fun main() {
    val a = 10
    val b = 3

    // Arithmetic
    val sum = a + b
    val product = a * b
    val remainder = a % b

    // Relational
    val isGreater = a > b
    val isEqual = a == b

    // Logical
    val condition = a > 5 && b < 5

    // Assignment
    var total = 0
    total += sum
    total *= 2

    println("Arithmetic: Sum=$sum, Product=$product, Remainder=$remainder")
    println("Relational: a > b = $isGreater, a == b = $isEqual")
    println("Logical: a > 5 && b < 5 = $condition")
    println("Assignment: total after operations = $total")
}
Output: Arithmetic: Sum=13, Product=30, Remainder=1 Relational: a > b = true, a == b = false Logical: a > 5 && b < 5 = true Assignment: total after operations = 26

Note: Arithmetic operators work with Int, Double, etc. Relational operators return Boolean. Assignment operators modify the variable in place.

2. What are Increment and Decrement Operators in Kotlin?

Increment (++): Increases a variable's value by 1.

Decrement (--): Decreases a variable's value by 1.

Use Case: Loop counters or value adjustments.

Note: Only for numeric types (Int, Long, etc.); not for Double or Float.

Example: Increment/Decrement Operators

// Increment/decrement operators
fun main() {
    var counter = 5

    // Pre-increment
    val preInc = ++counter
    println("Pre-increment: ++counter = $preInc, counter = $counter")

    // Post-increment
    val postInc = counter++
    println("Post-increment: counter++ = $postInc, counter = $counter")

    // Pre-decrement
    val preDec = --counter
    println("Pre-decrement: --counter = $preDec, counter = $counter")

    // Post-decrement
    val postDec = counter--
    println("Post-decrement: counter-- = $postDec, counter = $counter")
}
Output: Pre-increment: ++counter = 6, counter = 6 Post-increment: counter++ = 6, counter = 7 Pre-decrement: --counter = 6, counter = 6 Post-decrement: counter-- = 6, counter = 5

Note: Pre- operators modify the value before use; post- modify after. Useful in loops or counters.

3. What is Operator Precedence in Kotlin?

Operator Precedence: Determines the order of evaluation when multiple operators are present in an expression.

Common Precedence Order:

Use Case: Ensuring correct expression evaluation (use parentheses for clarity).

Example: Operator Precedence

// Operator precedence example
fun main() {
    val a = 10
    val b = 3
    val c = 2

    // Precedence: * before +, left-to-right
    val result1 = a + b * c  // 10 + (3 * 2) = 16
    val result2 = (a + b) * c  // (10 + 3) * 2 = 26

    // Precedence: ++ postfix after use
    var x = 5
    val y = x++ + 2  // 5 + 2 = 7, then x = 6
    val z = ++x + 2  // x = 7, then 7 + 2 = 9

    println("Result1 (* before +): $result1")
    println("Result2 ((+ before *)): $result2")
    println("y (post-increment): $y, x after: $x")
    println("z (pre-increment): $z")
}
Output: Result1 (* before +): 16 Result2 ((+ before *)): 26 y (post-increment): 7, x after: 6 z (pre-increment): 9

Note: * has higher precedence than +. Postfix ++ uses the current value before incrementing. Use parentheses to override precedence.

4. What are the Elvis Operator (?:) and Safe Call Operator (?.) in Kotlin?

Safe Call Operator (?.): Accesses a property or method only if the object is not null; returns null otherwise.

Elvis Operator (?:): Provides a default value if an expression is null.

Combined: obj?.property ?: "Default".

Note: Kotlin's null safety is a key feature, unlike Java's nullable handling.

Example: Elvis and Safe Call Operators

// Elvis operator and safe call operator
fun main() {
    val nullableString: String? = null
    val nonNullString = "Hello"

    // Safe call operator
    val safeLength1 = nullableString?.length  // null
    val safeLength2 = nonNullString?.length   // 5

    // Elvis operator
    val default1 = nullableString ?: "Default"  // "Default"
    val default2 = nonNullString ?: "Default"  // "Hello"

    // Combined
    val combined = nullableString?.length ?: 0  // 0

    println("Safe Length (null): $safeLength1")
    println("Safe Length (non-null): $safeLength2")
    println("Elvis (null): '$default1'")
    println("Elvis (non-null): '$default2'")
    println("Combined: $combined")
}
Output: Safe Length (null): null Safe Length (non-null): 5 Elvis (null): 'Default' Elvis (non-null): 'Hello' Combined: 0

Note: ?. prevents crashes on null objects. ?: provides defaults for null results. Combined usage is common for null-safe defaults.

5. Comprehensive Example Combining All Operators

This example combines all operator categories in a single Kotlin program.

// Comprehensive Kotlin operators example
fun main() {
    val a = 10
    val b = 3
    var c = 5
    val name = "Kotlin"

    // Arithmetic operators
    val sum = a + b
    val product = a * b
    val remainder = a % b
    println("Arithmetic: Sum=$sum, Product=$product, Remainder=$remainder")

    // Relational operators
    val isGreater = a > b
    val isEqual = a == b
    println("Relational: a > b = $isGreater, a == b = $isEqual")

    // Logical operators
    val condition = a > 5 && b < 5
    println("Logical: a > 5 && b < 5 = $condition")

    // Assignment operators
    c += 2  // c = c + 2
    c *= 3  // c = c * 3
    println("Assignment: c after operations = $c")

    // Increment/decrement operators
    val preInc = ++c
    val postDec = c--
    println("Increment/Decrement: preInc=$preInc, postDec=$postDec, c=$c")

    // Operator precedence
    val result1 = a + b * c  // * before +
    val result2 = (a + b) * c
    println("Precedence: a + b * c = $result1, (a + b) * c = $result2")

    // Elvis and safe call operators
    val nullableInt: Int? = null
    val nonNullInt = 42
    val safeValue1 = nullableInt ?: 0
    val safeValue2 = nonNullInt ?: 0
    println("Elvis: nullable ?: 0 = $safeValue1")
    println("Elvis: non-null ?: 0 = $safeValue2")
}
Output: Arithmetic: Sum=13, Product=30, Remainder=1 Relational: a > b = true, a == b = false Logical: a > 5 && b < 5 = true Assignment: c after operations = 21 Increment/Decrement: preInc=22, postDec=22, c=21 Precedence: a + b * c = 73, (a + b) * c = 39 Elvis: nullable ?: 0 = 0 Elvis: non-null ?: 0 = 42

Description:

6. Common Mistakes and Best Practices

Common Mistakes:

Best Practices: