Menu
Coddy logo textTech

equals, hashCode, toString

Coddy'nin Kotlin Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 35 / 57.

Her sınıf toString(), equals() ve hashCode() yöntemlerini Any sınıfından devralır. Devralınan sürümler kimlik üzerinde çalışır: toString() sınıf adını ve bir karma kodunu verir, equals() ise yalnızca aynı nesne için true olur. toString() yöntemini geçersiz kılmak, nesnelere println ve dize şablonları tarafından kullanılan okunabilir bir metin verir:

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

main içinde:

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

Çıktı:

$12.50
total: $0.99

==, equals() metodunu çağırırken === iki referansın aynı nesneyi gösterip göstermediğini kontrol eder. Değere göre karşılaştırmak için equals metodunu geçersiz kıl. Parametresi Any? olduğundan önce türü kontrol eder, ardından ilgili özellikleri karşılaştırır:

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()
}

main içinde:

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

Çıktı:

true
false

Eşit olan nesnelerin karma kodları da eşit olmalıdır. HashSet ve HashMap, girdileri önce hashCode() ile bulur ve yalnızca bundan sonra equals() çağrısını yapar; bu nedenle equals metodunu hashCode olmadan geçersiz kılmak, eşit nesnelerin bunlarda farklı görünmesine neden olur. Aynı özelliklerden hesaplanacak şekilde her ikisini de her zaman geçersiz kılın:

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"
}

main içinde:

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

Çıktı:

2
true

Bir veri sınıfı, üçünü de kurucu özelliklerinden üretir. Eşitlik daha az özellik kullanmalıysa veya büyük/küçük harfi yok sayan bir e-posta adresi gibi normalleştirilmiş bir biçim kullanmalıysa bunları kendiniz yazın:

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>"
}

main içinde:

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

Çıktı:

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

Görev

Kolay

İki ürün, diğer alanların değerleri ne olursa olsun sku değerleri eşleştiğinde aynıdır. Product içinde equals() ve hashCode() işlevlerini yalnızca sku temelinde ve bir ürünün A1 tea 450 olarak yazdırılması için toString() işlevini geçersiz kılın. Ardından, özgün sıradaki her ürünün ilk oluşumunu tutan mergeCatalog(products) işlevini tamamlayın.

Sağlanan kod, ürünleri sku,name,price satırları ve aranacak bir sku değerini içeren son satır olarak okur. Tutulan her ürünü, removed: 2 ve sku değerini bir HashSet içinde arayarak A1 in catalog: true çıktısını yazdırır.

Kodunuz Product.kt ve Functions.kt dosyalarına yazılmalıdır. Main.kt sağlanan girdi/çıktı kodunu içerir ve düzenlenemez.

Kendin dene

fun main() {
    // Sağlanan girdi/çıktı kodu: olduğu gibi bırakın
    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 iconKendini test et

Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.

Nesne Yönelimli Programlama bölümündeki tüm dersler

Kendi başına pratik yap: Kotlin playground