51. Explain Collections Operations in kotlin
In Kotlin, collection operations refer to the set of functions available on collections like List, Set, and Map to filter, transform, group, and aggregate data easily and concisely.
These operations are part of Kotlin’s standard library and are highly expressive and functional in nature.
1. Filtering
val numbers = listOf(1, 2, 3, 4, 5)
val even = numbers.filter { it % 2 == 0 } // [2, 4]
2. Mapping(Transforming)
val squares = numbers.map { it * it } // [1, 4, 9, 16, 25]
3. forEach (Iteration)
numbers.forEach { println(it) }
4. find / firstOrNull
val firstEven = numbers.find { it % 2 == 0 } // 2
5. all / any / none
numbers.all { it > 0 } // true
numbers.any { it > 4 } // true
numbers.none { it < 0 } // true
6. groupBy
val grouped = numbers.groupBy { it % 2 == 0 }
// Result: {false=[1, 3, 5], true=[2, 4]}
7. associateBy
data class User(val id: Int, val name: String)
val users = listOf(User(1, "A"), User(2, "B"))
val map = users.associateBy { it.id }
// Result: {1=User(1, "A"), 2=User(2, "B")}
8. zip
val a = listOf(1, 2, 3)
val b = listOf("a", "b", "c")
val zipped = a.zip(b) // [(1, "a"), (2, "b"), (3, "c")]
9. flatten / flatMap
val nested = listOf(listOf(1, 2), listOf(3, 4))
val flat = nested.flatten() // [1, 2, 3, 4]
10. sum / average / count / reduce / fold
val sum = numbers.sum() // 15
val avg = numbers.average() // 3.0
val count = numbers.count { it > 3 } // 2
val product = numbers.reduce { acc, i -> acc * i } // 120
val total = numbers.fold(10) { acc, i -> acc + i } // 25
Conclusion:
Operation | Purpose |
---|---|
filter | Filter elements based on condition |
map | Transform elements |
forEach | Perform action on each element |
groupBy | Group elements by key |
associateBy | Map elements to a key |
reduce/fold | Aggregate values |
zip | Combine two lists |
flatMap | Flatten + map transformation |
52. What is reified Modifier in Kotlin
The reified modifier in Kotlin is used with inline functions to retain the type information at runtime — which is normally erased due to type erasure in generics.
In Kotlin (and Java), generic type parameters are erased at runtime. That means:
fun <T> myFunction(value: T) {
if (value is String) { ... } // ❌ Error: Cannot check for erased type
}
This doesn’t work because type T is unknown at runtime.
But with inline + reified, Kotlin preserves the type, so you can do things like:
Syntax
inline fun <reified T> doSomething(value: Any) {
if (value is T) {
println("Value is of type ${T::class}")
} else {
println("Not a ${T::class}")
}
}
53. Compare inline vs reified .
Feature | inline | reified |
---|---|---|
Purpose | Inline function body at callsite | Retain type info at runtime |
Use Case | Avoid lambda overhead | Work with generic types at runtime |
Requires Inline | ✅ Always | ✅ Always |
Used with | Higher-order functions | Generic functions |
JVM Limitation Solved | Function call overhead | Type erasure |
54. Concept of delegates in kotlin
In Kotlin, delegation is a powerful design pattern that allows an object to delegate certain responsibilities to another object. Kotlin supports delegation both via:
1. Class Delegation (by)
2. Property Delegation (by with Delegates)
1. 🧱 Class Delegation
You can delegate the implementation of an interface to another object using by. Example:
interface Printer {
fun printMessage()
}
class RealPrinter : Printer {
override fun printMessage() {
println("Printing from RealPrinter")
}
}
class PrinterProxy(printer: Printer) : Printer by printer
Kotlin allows delegating property access logic using the by keyword with built-in or custom delegates.
Used when a value should be initialized only once, on first access.
val name: String by lazy {
println("Computed!")
"Bind the Logic"
}
First access prints "Computed!", subsequent ones don’t.
observable
Used to observe changes to a property.
import kotlin.properties.Delegates
var counter: Int by Delegates.observable(0) { _, old, new ->
println("Counter changed from $old to $new")
}
vetoable
Allows rejecting a value change.
var age: Int by Delegates.vetoable(0) { _, _, new ->
new >= 18 // only allow age >= 18
}
You can create your own logic by implementing ReadOnlyProperty or ReadWriteProperty.
class MyDelegate {
operator fun getValue(thisRef: Any?, property: KProperty<*>): String {
return "Delegated value for '${property.name}'"
}
}
val delegatedProperty: String by MyDelegate()
55. When to Use Delegates
Use Case | Delegate Type |
---|---|
Delay initialization | lazy |
React to value changes | observable |
Validate new value | vetoable |
Avoid repeating logic | Class/interface delegation |
Custom property behavior | Custom delegate |