0
0
Kotlinprogramming~15 mins

Collection size and emptiness checks in Kotlin - Deep Dive

Choose your learning style9 modes available
Overview - Collection size and emptiness checks
What is it?
Collection size and emptiness checks in Kotlin are ways to find out how many items are in a collection and whether it has any items at all. Collections are groups of items like lists or sets. Checking size tells you the number of items, while emptiness checks tell you if the collection is empty or not. These checks help control the flow of programs by knowing if there is data to work with.
Why it matters
Without size or emptiness checks, programs might try to use collections that have no items, causing errors or unexpected behavior. For example, trying to get the first item from an empty list would crash the program. These checks prevent such problems and make programs safer and more reliable. They also help improve performance by avoiding unnecessary work on empty collections.
Where it fits
Before learning this, you should understand what collections are and basic Kotlin syntax. After this, you can learn about filtering collections, iterating over them, and advanced collection operations like mapping or folding.
Mental Model
Core Idea
Checking a collection's size or emptiness is like asking 'How many items do you have?' or 'Do you have anything at all?' before using it.
Think of it like...
Imagine a backpack: before reaching inside, you check if it’s empty or how many things are inside. This helps you decide what to do next, like packing more or taking something out.
┌───────────────┐
│   Collection  │
│ ┌───────────┐ │
│ │ Items     │ │
│ │ [a, b, c] │ │
│ └───────────┘ │
│ Size: 3      │
│ Empty? No    │
└───────────────┘
Build-Up - 7 Steps
1
FoundationUnderstanding Collections in Kotlin
🤔
Concept: Introduce what collections are and basic types like List and Set.
In Kotlin, collections are groups of items stored together. The most common types are List (ordered, can have duplicates) and Set (unordered, no duplicates). You create a list like this: val fruits = listOf("apple", "banana", "cherry").
Result
You have a collection named fruits containing three items.
Knowing what collections are is essential before checking their size or emptiness.
2
FoundationAccessing Collection Size Property
🤔
Concept: Learn how to get the number of items in a collection using size.
Every Kotlin collection has a size property that tells how many items it contains. For example, fruits.size returns 3 because there are three fruits.
Result
fruits.size returns 3.
Understanding size helps you know how many items you have to work with.
3
IntermediateChecking If Collection Is Empty
🤔
Concept: Use isEmpty() and isNotEmpty() functions to check if a collection has no items or some items.
Instead of comparing size to zero, Kotlin provides isEmpty() which returns true if the collection has no items, and isNotEmpty() which returns true if it has one or more items. For example, fruits.isEmpty() returns false.
Result
fruits.isEmpty() returns false; fruits.isNotEmpty() returns true.
Using isEmpty() and isNotEmpty() makes code clearer and more readable than checking size == 0.
4
IntermediateUsing Size and Emptiness in Conditions
🤔Before reading on: do you think checking size == 0 and using isEmpty() behave exactly the same in all cases? Commit to your answer.
Concept: Learn how to use size and emptiness checks in if statements to control program flow.
You can write if (fruits.isEmpty()) { println("No fruits") } else { println("We have fruits") } to decide what to do based on collection content. Alternatively, if (fruits.size == 0) works but is less clear.
Result
Prints "We have fruits" because fruits is not empty.
Knowing how to use these checks in conditions helps prevent errors like accessing items in empty collections.
5
IntermediatePerformance Differences Between Checks
🤔Before reading on: do you think isEmpty() and size == 0 always have the same speed? Commit to your answer.
Concept: Understand that isEmpty() can be faster than size == 0 for some collections.
For some collections, size is stored and quick to access. But for others, size requires counting all items, which is slower. isEmpty() often just checks if there is at least one item, which can be faster. For example, a LinkedList may compute size by counting nodes.
Result
Using isEmpty() can improve performance on large or complex collections.
Choosing isEmpty() over size == 0 can make your program faster and more efficient.
6
AdvancedHandling Nullable Collections Safely
🤔Before reading on: do you think calling isEmpty() on a null collection causes an error or returns true? Commit to your answer.
Concept: Learn how to safely check size or emptiness when collections can be null.
If a collection variable can be null, calling size or isEmpty() directly causes a crash. Use safe calls like collection?.isEmpty() ?: true to treat null as empty. This avoids errors and makes code safer.
Result
If collection is null, collection?.isEmpty() ?: true returns true safely.
Handling null collections prevents crashes and improves program stability.
7
ExpertCustom Collections and Size/Empty Behavior
🤔Before reading on: do you think all collections must have a fast size property? Commit to your answer.
Concept: Explore how custom collections can define size and emptiness differently, affecting performance and behavior.
Kotlin allows creating custom collections by implementing interfaces. These can override size and isEmpty() methods. For example, a collection might compute size on demand or cache it. Understanding this helps avoid surprises when using third-party or complex collections.
Result
Custom collections may have slow or fast size checks depending on implementation.
Knowing that size and emptiness checks depend on implementation helps debug performance issues and write better code.
Under the Hood
Kotlin collections implement size as a property that returns an integer count of items. For many built-in collections, size is stored and returned instantly. The isEmpty() function usually checks if size == 0 internally, but some collections override it to optimize by checking if any item exists without counting all. Nullable collections require safe calls to avoid null pointer exceptions when checking size or emptiness.
Why designed this way?
Kotlin was designed to make collection operations simple and safe. Providing size as a property and isEmpty()/isNotEmpty() as functions improves readability and performance. The design allows collections to optimize these checks based on their internal structure. Nullable safety is a core Kotlin feature to prevent common runtime errors.
┌───────────────┐
│ Collection    │
│ ┌───────────┐ │
│ │ size      │ │
│ │ (property)│ │
│ └───────────┘ │
│     │         │
│     ▼         │
│ ┌───────────┐ │
│ │ isEmpty() │ │
│ │ (function)│ │
│ └───────────┘ │
└─────┬─────────┘
      │
      ▼
┌───────────────┐
│ Internal Data │
│ (items list)  │
└───────────────┘
Myth Busters - 4 Common Misconceptions
Quick: Does isEmpty() always run faster than size == 0? Commit to yes or no.
Common Belief:isEmpty() is always faster than checking size == 0.
Tap to reveal reality
Reality:For many collections, isEmpty() and size == 0 have the same speed because isEmpty() calls size internally. But some collections override isEmpty() for optimization, so speed depends on implementation.
Why it matters:Assuming isEmpty() is always faster can lead to premature optimization or confusion when performance differs unexpectedly.
Quick: Can you call size on a null collection safely? Commit to yes or no.
Common Belief:You can call size on any collection without checking for null.
Tap to reveal reality
Reality:Calling size on a null collection causes a runtime error (NullPointerException). You must use safe calls or null checks.
Why it matters:Ignoring null safety leads to program crashes and bugs that are hard to trace.
Quick: Does size always reflect the current number of items instantly? Commit to yes or no.
Common Belief:size always returns the current number of items immediately.
Tap to reveal reality
Reality:Some collections compute size on demand, which can be slow if the collection is large or complex. Others cache size for instant access.
Why it matters:Assuming size is always fast can cause performance problems in large or custom collections.
Quick: Does isEmpty() mean the collection has no items or that it might be null? Commit to your answer.
Common Belief:isEmpty() returns true if the collection is null or empty.
Tap to reveal reality
Reality:isEmpty() only checks if the collection has zero items. It does not handle null collections; calling it on null causes an error.
Why it matters:Confusing null with empty leads to crashes and incorrect program logic.
Expert Zone
1
Some Kotlin collections override isEmpty() to avoid counting all items, improving performance on large or lazy collections.
2
Nullable collections require careful use of safe calls or the Elvis operator to avoid runtime exceptions when checking emptiness.
3
Custom collections can implement size and isEmpty() in ways that affect iteration and performance, so understanding their internals is key for optimization.
When NOT to use
Avoid relying on size or isEmpty() for very large or infinite collections where counting items is expensive or impossible. Instead, use lazy evaluation or check for presence of elements with iterators or sequences.
Production Patterns
In real-world Kotlin code, isEmpty() and isNotEmpty() are preferred for readability and safety. Nullable collections are checked with safe calls. Performance-critical code may use custom collections with optimized size checks or avoid size queries altogether.
Connections
Null Safety in Kotlin
Builds-on
Understanding how to safely check collections for emptiness requires knowing Kotlin's null safety features to avoid crashes.
Lazy Evaluation
Opposite
Lazy collections may not have a fixed size immediately, so size and emptiness checks behave differently, teaching about deferred computation.
Inventory Management
Same pattern
Checking collection size or emptiness is like managing stock in a store, where knowing if items are available or how many helps make decisions.
Common Pitfalls
#1Calling size on a null collection causes a crash.
Wrong approach:val count = myList.size // myList is null here
Correct approach:val count = myList?.size ?: 0
Root cause:Not accounting for nullability leads to runtime exceptions.
#2Using size == 0 instead of isEmpty() reduces code clarity.
Wrong approach:if (myList.size == 0) { println("Empty") }
Correct approach:if (myList.isEmpty()) { println("Empty") }
Root cause:Not using idiomatic Kotlin functions makes code harder to read and maintain.
#3Assuming size is always fast causes performance issues.
Wrong approach:if (myLinkedList.size > 1000) { /* do something */ }
Correct approach:if (!myLinkedList.isEmpty()) { /* do something */ }
Root cause:Not knowing that some collections compute size by counting all elements.
Key Takeaways
Collection size and emptiness checks help safely control program flow by knowing if collections have items.
Use isEmpty() and isNotEmpty() for clearer and often more efficient checks than comparing size to zero.
Always handle nullable collections safely to avoid crashes when checking size or emptiness.
Performance of size and emptiness checks depends on collection implementation; some compute size on demand.
Understanding these checks deeply prevents bugs, improves readability, and helps write efficient Kotlin code.