Preconditions (require, check, error) in Kotlin - Time & Space Complexity
We want to understand how the time cost changes when using precondition checks like require, check, and error in Kotlin.
How does adding these checks affect the program's running time as input grows?
Analyze the time complexity of the following code snippet.
fun processList(numbers: List<Int>) {
require(numbers.isNotEmpty()) { "List cannot be empty" }
for (number in numbers) {
check(number > 0) { "Number must be positive" }
println(number)
}
if (numbers.size > 1000) {
error("List too large to process")
}
}
This code checks conditions before and during processing a list of numbers, printing each number if all checks pass.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: The for-loop that goes through each number in the list.
- How many times: Once for each item in the list (n times).
The checks outside the loop run once, but the loop runs once per item, so the total work grows as the list gets bigger.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 checks and prints |
| 100 | About 100 checks and prints |
| 1000 | About 1000 checks and prints |
Pattern observation: The time grows directly with the number of items in the list.
Time Complexity: O(n)
This means the time to run the code grows in a straight line with the size of the input list.
[X] Wrong: "Precondition checks like require or check add a lot of extra time for every item."
[OK] Correct: These checks run once per item inside the loop, just like any other simple operation, so they add a small constant time per item, not extra loops or nested work.
Understanding how precondition checks affect time helps you write safe code without worrying about slowing down your program too much as inputs grow.
"What if we moved the check(number > 0) outside the loop to run once for the whole list? How would the time complexity change?"
Practice
require function in Kotlin?Solution
Step 1: Understand
requireusagerequireis used to check if the inputs to a function are valid before proceeding.Step 2: Differentiate from other preconditions
checkis for program state, anderrorstops the program immediately.requireis specifically for argument validation.Final Answer:
To check if function arguments meet certain conditions -> Option DQuick Check:
require = argument check [OK]
- Confusing require with check for program state
- Thinking error is for argument validation
- Assuming require stops program immediately
check in Kotlin to verify a condition with a lazy message?Solution
Step 1: Recall
checkfunction signaturechecktakes a Boolean condition and a lambda returning a message string if false.Step 2: Match syntax with options
check(value > 0) { "Value must be positive" } usescheck(condition) { "message" }which is correct Kotlin syntax.Final Answer:
check(value > 0) { "Value must be positive" } -> Option CQuick Check:
check syntax = condition + lambda message [OK]
- Passing message as second argument instead of lambda
- Using comma inside lambda incorrectly
- Omitting braces for message lambda
fun test(x: Int) {
require(x > 0) { "x must be positive" }
check(x < 10) { "x must be less than 10" }
println("x is valid: $x")
}
test(15)Solution
Step 1: Evaluate
Since 15 > 0,require(x > 0)requirepasses without exception.Step 2: Evaluate
15 is not less than 10, socheck(x < 10)checkthrowsIllegalStateExceptionwith message "x must be less than 10".Final Answer:
IllegalStateException: x must be less than 10 -> Option AQuick Check:
require passes, check fails with IllegalStateException [OK]
- Thinking require throws error for x=15
- Assuming println runs after failed check
- Confusing exception types thrown by require and check
fun validate(name: String) {
require(name.isNotEmpty(), "Name cannot be empty")
check(name.length > 3) { "Name too short" }
}Solution
Step 1: Review
Bothrequiresyntaxrequire(condition, "message")(eager message) andrequire(condition) { "message" }(lazy message) are valid overloads.Step 2: Review
The lambda syntax for check is also valid. The code compiles and works as expected.checksyntaxFinal Answer:
No error, code is correct -> Option BQuick Check:
Both eager and lazy messages valid [OK]
- Thinking comma message is invalid for require
- Confusing require syntax with only lambda support
- Forgetting that multiple overloads exist
fun criticalCheck(flag: Boolean) {
// Your code here
}Solution
Step 1: Understand
errorfunction purposeerrorimmediately throws anIllegalStateExceptionwith the given message and stops the program.Step 2: Apply
Useerrorfor critical failureif (!flag) error("Critical failure")to stop execution immediately when condition fails.Final Answer:
Useerror("Critical failure")if flag is false -> Option AQuick Check:
error stops program immediately with message [OK]
- Using require or check which throw exceptions but may be caught
- Printing message without stopping program
- Not stopping program on critical failure
Ready to prove it?
Pass the test and this pattern moves unknown
