CodeBlanks Logo Icon CodeBlanks

Summary - Generics

Combine generic class, functions and variance to write a Stack<T>.

Summary - Generics

In this group you learned generic class, generic function, variance, type constraint and reified. They all boost reuse and type safety.

In this summary you will write a Stack<T> generic class. Its push and pop methods use a MutableList<T>. A factory function fun <T> of(vararg values: T): Stack<T> will be added. When all parts come together you get a type-safe, reusable data structure.

Practice The Stack<T> generic class

Define a generic class class Stack<T>. Inside, add private val items: MutableList<T> = mutableListOf(). The fun push(item: T) method does items.add(item). The fun pop(): T method returns items.removeAt(items.size - 1). In main declare val s = Stack<Int>(), call s.push(1) and s.push(2), then print the last item with println(s.pop()).

Starter code

Main.kt
// Define the Stack<T> generic class
// with a mutable list named items
// push and pop methods
// instantiate with Int in main and print pop

Sample solution

Main.kt
class Stack<T> {
    private val items: MutableList<T> = mutableListOf()

    fun push(item: T) {
        items.add(item)
    }

    fun pop(): T {
        return items.removeAt(items.size - 1)
    }
}

fun main() {
    val s = Stack<Int>()
    s.push(1)
    s.push(2)
    println(s.pop())
}

Expected output

2

Practice The of factory function

Define class Stack<T> as in the previous step (items, push, pop). Also add a generic factory function fun <T> of(vararg values: T): Stack<T> whose body declares val s = Stack<T>(), does for (v in values) s.push(v), and returns s. In main declare val s = of(1, 2, 3) and print the last item with println(s.pop()).

Starter code

Main.kt
class Stack<T> {
    private val items: MutableList<T> = mutableListOf()

    fun push(item: T) {
        items.add(item)
    }

    fun pop(): T {
        return items.removeAt(items.size - 1)
    }
}

// add the of generic factory function: takes vararg values, returns Stack

fun main() {
    // build a Stack with of and print pop
}

Sample solution

Main.kt
class Stack<T> {
    private val items: MutableList<T> = mutableListOf()

    fun push(item: T) {
        items.add(item)
    }

    fun pop(): T {
        return items.removeAt(items.size - 1)
    }
}

fun <T> of(vararg values: T): Stack<T> {
    val s = Stack<T>()
    for (v in values) s.push(v)
    return s
}

fun main() {
    val s = of(1, 2, 3)
    println(s.pop())
}

Expected output

3

Questions and answers

Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.

1 Why is a <strong>Stack&lt;T&gt;</strong> generic class convenient?

  • Because it only holds Int
  • Because it requires no inheritance
  • Because it disables type safety
  • Because it avoids writing separate code for each type Correct answer

Explanation: A generic Stack<T> works for every type with one declaration; it avoids duplication.

2 Complete the generic function definition

Question
fun ____ ident(t: T): T {
    return t
}
Answer
fun <T> ident(t: T): T {
    return t
}

Explanation: fun <T> ident(t: T) is a generic function declaration.

All lessons in Intermediate