Putting It Together: Designing a Small Kotlin Data Model
A wrap-up lesson combining data classes, null safety, and collections into one design.
What you'll learn
- Combine data classes, null safety, and collection operations into a single small design
- Recognize how the features from this course compose together in realistic code
- Prepare to apply these concepts in this course's capstone project
Explanation
This final lesson combines several features from across the course into one small, realistic design: a simple note-taking data model, the same domain you'll extend in this course's capstone project.
A Note is naturally a data class (value-holding, benefits from generated equals/toString/copy): data class Note(val id: Int, val title: String, val body: String, val completed: Boolean = false) -- note the default value for completed, so callers creating a new note don't need to specify it.
A collection of notes is a List<Note> (or MutableList<Note> if notes are added/removed at runtime), and finding one by id naturally returns a nullable result, since the id might not exist: fun findNote(notes: List<Note>, id: Int): Note? = notes.find { it.id == id } -- the find function itself already returns null if nothing matches, so the function's return type must honestly be Note?, and callers must handle that with ?./?: rather than assuming a note is always found.
Marking a note complete without mutating the original (since Note's fields could be val) uses copy: val completed = note.copy(completed = true).
Guided lab
Guided edit: From an unsafe find to a null-safe one
Follow each step to see how the design becomes null-safe and immutable-friendly.
Step 1 of 2
Start with a data class and a naive find function that assumes a match always exists (unsafe -- would crash if not found).
data class Note(val id: Int, val title: String, val completed: Boolean = false)
fun main() {
val notes = listOf(Note(1, "Buy milk"), Note(2, "Write report"))
val found = notes.find { it.id == 1 }!!
println(found.title)
}Stuck? Get a hint.
Common mistakes
- Declaring a find-by-id function's return type as non-nullable Note when the underlying search can genuinely fail to find a match.
- Using a regular class instead of a data class for a simple value-holding type like Note, missing out on generated equals/toString/copy for free.
- Mutating a note in place with var fields when copy() (with val fields) would better express 'this produces a new state, not an in-place edit'.
Knowledge check
Takeaway
A realistic small Kotlin design naturally combines data classes, honestly-nullable search results, and copy()-based updates rather than in-place mutation.
Summary
This wrap-up combines data classes, null-safe search, and copy-based updates into one design pattern, directly preparing for the course capstone project.
References
Your notes
Notes save automatically.
Finished this lesson?
Mark it complete to track your progress and schedule a future review.
AI tutor
The optional AI tutor isn't enabled in this deployment. All lessons, exercises, quizzes, and search work fully without it.