Menu
CoddyTech

equals, hashCode, toString

Termasuk bagian Pemrograman Berorientasi Objek dalam perjalanan Kotlin di Coddy. Pelajaran 35 dari 57.

Setiap class mewarisi toString(), equals(), dan hashCode() dari Any. Versi yang diwarisi bekerja berdasarkan identitas: toString() memberikan nama class dan kode hash, sedangkan equals() bernilai true hanya untuk object yang sama. Dengan mengganti toString(), kamu dapat memberikan teks yang mudah dibaca pada object, yang digunakan oleh println dan template string:

class Money(val cents: Int) {
    override fun toString() = "$%d.%02d".format(cents / 100, cents % 100)
}

Di dalam main:

val price = Money(1250)
println(price)
println("total: ${Money(99)}")

Output:

$12.50
total: $0.99

== memanggil equals(), sedangkan === memeriksa apakah dua referensi menunjuk ke object yang sama. Untuk membandingkan berdasarkan nilai, timpa equals. Parameternya adalah Any?, jadi fungsi ini memeriksa tipe terlebih dahulu, lalu membandingkan property yang relevan:

class Isbn(code: String) {
    val digits = code.filter { it.isDigit() }

    override fun equals(other: Any?) = other is Isbn && other.digits == digits
    override fun hashCode() = digits.hashCode()
}

Di dalam main:

val a = Isbn("978-0-441-17271-9")
val b = Isbn("9780441172719")
println(a == b)
println(a === b)

Output:

true
false

Object yang sama harus memiliki hash code yang sama. HashSet dan HashMap mencari entri berdasarkan hashCode() terlebih dahulu, lalu memanggil equals(), jadi menimpa equals tanpa hashCode membuat object yang sama tampak berbeda di dalamnya. Selalu timpa keduanya, dengan perhitungan berdasarkan property yang sama:

class Isbn(code: String) {
    val digits = code.filter { it.isDigit() }

    override fun equals(other: Any?) = other is Isbn && other.digits == digits
    override fun hashCode() = digits.hashCode()
    override fun toString() = "ISBN $digits"
}

Di dalam main:

val shelf = hashSetOf(Isbn("978-0-441-17271-9"), Isbn("9780441172719"), Isbn("0-14-143951-3"))
println(shelf.size)
println(Isbn("9780441172719") in shelf)

Output:

2
true

Data class membuat ketiganya dari property konstruktornya. Tulis sendiri ketika kesetaraan sebaiknya menggunakan lebih sedikit property atau bentuk yang dinormalisasi, seperti alamat email yang mengabaikan perbedaan huruf besar-kecil:

class User(val email: String, val name: String) {
    private val key = email.trim().lowercase()

    override fun equals(other: Any?) = other is User && other.key == key
    override fun hashCode() = key.hashCode()
    override fun toString() = "$name <$key>"
}

Di dalam main:

val users = listOf(User("Ada@Example.com", "Ada"), User("ada@example.com ", "A. Lovelace"))
println(users.distinct())

Output:

[Ada <ada@example.com>]
challenge icon

Tantangan

Mudah

Dua produk dianggap sama jika sku-nya cocok, apa pun nilai field lainnya. Override equals() dan hashCode() di Product hanya berdasarkan sku, serta toString() agar produk dicetak sebagai A1 tea 450. Lalu lengkapi mergeCatalog(products), yang mempertahankan kemunculan pertama setiap produk sesuai urutan aslinya.

Kode yang disediakan membaca produk dari baris berformat sku,name,price dan baris terakhir berisi sku yang akan dicari. Kode tersebut mencetak setiap produk yang dipertahankan, removed: 2 dan A1 in catalog: true, dengan mencari sku di dalam HashSet.

Tulis kodemu di Product.kt dan Functions.kt. Main.kt berisi kode input/output yang disediakan dan tidak boleh diedit.

Coba sendiri

fun main() {
    // Kode input/output yang disediakan: biarkan apa adanya
    val input = generateSequence(::readLine).toList()
    val products = input.dropLast(1).map { line ->
        val (sku, name, price) = line.split(",")
        Product(sku, name, price.toInt())
    }
    val kept = mergeCatalog(products)
    for (p in kept) println(p)
    println("removed: ${products.size - kept.size}")
    val probe = Product(input.last(), "?", 0)
    println("${input.last()} in catalog: ${probe in kept.toHashSet()}")
}
quiz iconUji dirimu

Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.

Semua pelajaran di Pemrograman Berorientasi Objek

Latihan sendiri: Playground Kotlin