1. Java'da nesneleri karşılaştırma
Java'da nesneler hem referansa hem de değere göre karşılaştırılabilir.
referansları karşılaştırma
İki değişken bellekte aynı nesneyi gösteriyorsa, bu değişkenlerde depolanan referanslar eşittir. Eşitlik operatörünü ( ) kullanarak bu değişkenleri karşılaştırırsanız ==, doğru olur ve bu sonuç anlamlı olur. Burada her şey basit.
| kod | Konsol çıkışı |
|---|---|
|
|
değere göre karşılaştırma
Ancak iki değişkenin aynı olan iki farklı nesneyi ifade ettiği durumlarla sıklıkla karşılaşabilirsiniz. Örneğin, aynı metni içeren iki farklı dize nesnesi.
Farklı nesnelerin aynı olup olmadığını belirlemek için equals()yöntemi kullanın. Örneğin:
| kod | Konsol çıkışı |
|---|---|
|
|
Yöntem equals, sınıfla sınırlı değildir String. Her sınıfta var.
Kendi başınıza yazdığınız sınıflar bile ve işte nedeni.
2. Objectsınıf
Java'daki tüm sınıflar, Objectsınıfı devralır. Java'nın yaratıcıları bu yaklaşımı ortaya attı.
Ve bir sınıf, sınıfı miras alırsa Object, sınıfın tüm yöntemlerini kazanır Object. Ve bu, mirasın önemli bir sonucudur.
ObjectBaşka bir deyişle, her sınıf , kodunda onlardan bahsetmese bile, sınıfın yöntemlerine sahiptir .
Bu kalıtsal yöntemler, nesne karşılaştırmasıyla ilgili yöntemleri içerir. Bunlar equals()ve hashCode()yöntemlerdir.
| kod | Gerçekte, sahip olacağımız şey şu: |
|---|---|
|
|
Yukarıdaki örnekte, Personad ve yaş parametreleriyle basit bir sınıf oluşturduk, ancak tek bir yöntem oluşturmadık. Ancak tüm sınıflar sınıfı devraldığından Object, Personsınıfın otomatik olarak iki yöntemi vardır:
| Yöntem | Tanım |
|---|---|
|
Geçerli nesneyi ve geçirilen nesneyi karşılaştırır |
|
Geçerli nesnenin karma kodunu döndürür |
equalsKesinlikle her nesnenin bir yöntemi olduğu ve farklı türdeki nesnelerin birbirleriyle karşılaştırılabileceği ortaya çıktı . Böyle bir kod mükemmel bir şekilde derlenecek ve çalışacaktır.
| kod | Konsol çıkışı |
|---|---|
|
|
|
|
3. equals()yöntem
equals()Sınıftan devralınan yöntem , Objectgeçerli nesneyi geçirilen nesnelerle karşılaştırmak için en basit algoritmayı uygular: yalnızca nesnelere yapılan referansları karşılaştırır.
PersonYöntemi çağırmak yerine sadece değişkenleri karşılaştırırsanız aynı sonucu alırsınız equals(). Örnek:
| kod | Konsol çıkışı |
|---|---|
|
|
Yöntem equalsçağrıldığında , değişkende saklanan referansı değişkende saklanan referansla akarşılaştırır .ab
Ancak, karşılaştırma sınıf için farklı çalışır String. Neden?
Çünkü sınıfı oluşturan insanlar, Stringyöntemin kendi uygulamalarını yazdılar equals().
equals()Yöntemin uygulanması
Şimdi sınıftaki eşittir yönteminin kendi uygulamamızı yazalım Person. 4 ana vakayı ele alacağız.
equalsalır.Object
Senaryo 1 : Yöntemin çağrıldığı aynı nesne equalsde yönteme iletilir equals. Geçerli nesnenin ve iletilen nesnenin başvuruları eşitse, yöntem döndürmelidir true. Bir nesne kendisine eşittir.
Kodda şöyle görünecek:
| kod | Tanım |
|---|---|
|
Referansları karşılaştırın |
Senaryo 2 : nullyönteme geçirilir equals- karşılaştıracak hiçbir şeyimiz yok. Yöntemin çağrıldığı nesne kesinlikle null değildir, bu nedenle bu durumda equalsgeri dönmemiz gerekir .false
Kodda şöyle görünecek:
| kod | Tanım |
|---|---|
|
Referansları karşılaştır Geçilen nesne mi null? |
Senaryo 3 : a olmayan bir nesneye yapılan başvuru, Personyönteme iletilir equals. PersonNesne, nesne olmayana eşit midir Person? Bu, sınıfın geliştiricisinin Personnasıl isterse öyle karar vermesi gereken bir sorudur.
Ancak genellikle nesnelerin eşit kabul edilmesi için aynı sınıftan olması gerekir. PersonBu nedenle, equals yöntemimize sınıfın bir nesnesinden başka bir şey iletilirse, o zaman her zaman geri döneriz false. Bir nesnenin türünü nasıl kontrol edebilirsiniz? Bu doğru — operatörü kullanarak instanceof.
İşte yeni kodumuz şöyle görünüyor:
| kod | Tanım |
|---|---|
|
Referansları karşılaştır Geçilen nesne mi null? Geçirilen nesne bir Person |
Person4. İki nesneyi karşılaştırma
Sonumuz ne oldu? Metodun sonuna ulaştıysak, Personolmayan bir nesne referansımız var demektir null. Bu yüzden onu a'ya dönüştürüyoruz Personve her iki nesnenin ilgili dahili verilerini karşılaştırıyoruz. Ve bu bizim dördüncü senaryomuz .
| kod | Tanım |
|---|---|
|
Referansları karşılaştır Geçilen nesne mi null? Geçirilen nesne bir Typecasting değilse Person |
Ve iki nesneyi nasıl karşılaştırırsınız Person? nameİsimleri ( ) ve yaşları ( ) aynı ise eşittirler age. Nihai kod şöyle görünecektir:
| kod | Tanım |
|---|---|
|
Referansları karşılaştır Geçilen nesne mi null? Geçirilen nesne bir Typecasting değilse Person |
Ama hepsi bu kadar değil.
İlk olarak, ad alanı bir String, bu nedenle yöntemi çağırarak ad alanını karşılaştırmanız gerekir equals.
this.name.equals(person.name)
İkinci olarak, namealan şu şekilde olabilir : bu durumda onu nullarayamazsınız . equalsAşağıdakiler için ek bir kontrole ihtiyacınız var null:
this.name != null && this.name.equals(person.name)
Bununla birlikte, ad alanı nullher iki nesnedeyse Person, adlar yine de eşittir.
Dördüncü senaryonun kodu şöyle görünebilir:
|
Yaşlar eşit değilse, hemen return false If this.nameeşittir ise null, yöntemi kullanarak karşılaştırma yapmanın bir anlamı yoktur equals. Burada ikinci namealan eşittir nullveya değildir. Yöntemi kullanarak iki ad alanını karşılaştırın equals. |
5. hashCode()yöntem
Her iki nesnenin tüm alanlarının ayrıntılı bir şekilde karşılaştırılmasını amaçlayan yönteme ek olarak equals, kesin olmayan ancak çok hızlı bir karşılaştırma için kullanılabilecek başka bir yöntem daha vardır: hashCode().
Binlerce kelimeden oluşan bir listeyi alfabetik olarak sıraladığınızı ve kelime çiftlerini tekrar tekrar karşılaştırmanız gerektiğini hayal edin. Ve kelimeler uzun, birçok harften oluşuyor. Genel olarak konuşursak, böyle bir karşılaştırma çok uzun zaman alır.
Ama hızlandırılabilir. Diyelim ki farklı harflerle başlayan kelimelerimiz var - farklı oldukları hemen anlaşılıyor. Ancak aynı harflerle başlarlarsa, sonucun ne olacağını henüz söyleyemeyiz: kelimeler eşit veya farklı olabilir.
Yöntem hashCode(), benzer bir ilkeye göre çalışır. Bir nesne üzerinde çağırırsanız, bir kelimedeki ilk harfe benzer bir sayı döndürür. Bu sayı aşağıdaki özelliklere sahiptir:
- Özdeş nesneler her zaman aynı karma koda sahiptir
- Farklı nesneler aynı karma koda sahip olabilir veya karma kodları farklı olabilir
- Nesnelerin farklı karma kodları varsa, o zaman nesneler kesinlikle farklıdır
Bunu daha da açık hale getirmek için, bu özellikleri sözcükler açısından yeniden çerçevelendirelim:
- Özdeş sözcüklerin baş harfleri her zaman aynıdır.
- Farklı kelimelerin ilk harfleri aynı olabilir veya ilk harfleri farklı olabilir.
- Kelimelerin ilk harfleri farklıysa, kelimeler kesinlikle farklıdır
Son özellik, nesnelerin karşılaştırılmasını hızlandırmak için kullanılır:
İlk olarak, iki nesnenin karma kodları hesaplanır. Bu karma kodlar farklıysa, o zaman nesneler kesinlikle farklıdır ve bunları daha fazla karşılaştırmaya gerek yoktur.
Ancak karma kodlar aynıysa, yine de eşittir yöntemini kullanarak nesneleri karşılaştırmamız gerekir.
6. Kodlu Sözleşmeler
Yukarıda açıklanan davranış, Java'daki tüm sınıflar tarafından uygulanmalıdır. Derleme sırasında, nesnelerin doğru bir şekilde karşılaştırılıp karşılaştırılmadığını kontrol etmenin bir yolu yoktur.
Java programcıları, equals() yönteminin kendi uygulamalarını yazarlarsa ve böylece standart uygulamayı (sınıfta Object) geçersiz kılarlarsa, yöntemin kendi uygulamalarını da hashCode()yukarıda belirtilen kuralları sağlayacak şekilde yazmaları gerektiği konusunda evrensel bir anlaşmaya sahiptir. memnun.
Bu düzenlemeye sözleşme denir .
Sınıfınızda yalnızca equals()veya yalnızca yöntemi uygularsanız , sözleşmeyi büyük ölçüde ihlal etmiş olursunuz (sözleşmeyi bozmuş olursunuz). hashCode()Bunu yapma.
Diğer programcılar kodunuzu kullanırsa düzgün çalışmayabilir. Dahası, yukarıdaki sözleşmelere uymaya dayalı kod kullanacaksınız.
Bir öğe ararken, tüm Java koleksiyonları önce nesnelerin hash kodlarını karşılaştırır ve ancak bundan sonra yöntemi kullanarak bir karşılaştırma gerçekleştirir equals.
Bu, kendi sınıfınıza bir yöntem verirseniz, equalsancak kendi yönteminizi yazmazsanız hashCode()veya yanlış uygularsanız, koleksiyonlar nesnelerinizle doğru çalışmayabilir.
Örneğin, bir listeye bir nesne ekleyebilir ve ardından yöntemi kullanarak onu arayabilirsiniz contains(), ancak koleksiyon nesnenizi bulamayabilir.
GO TO FULL VERSION