1. Mbandhingake obyek ing basa Jawa

Ing Jawa, obyek bisa dibandhingake kanthi referensi lan nilai.

Mbandhingake referensi

Yen rong variabel nuding obyek sing padha ing memori, mula referensi sing disimpen ing variabel kasebut padha. Yen sampeyan mbandhingake variabel kasebut nggunakake operator kesetaraan ( ==), sampeyan bakal bener, lan asil kasebut bisa dimangerteni. Kabeh iku prasaja ing kene.

Kode Output konsol
Integer a = 5;
Integer b = a;
System.out.println(a == b);


true

Mbandhingake kanthi nilai

Nanging sampeyan bisa kerep nemoni kahanan ing ngendi rong variabel nuduhake rong obyek sing beda-beda sing padha. Contone, rong obyek strings beda sing ngemot teks padha.

Kanggo nemtokake manawa obyek sing beda identik, gunakake equals()metode kasebut. Tuladhane:

Kode Output konsol
String a = new String("Hello");
String b = new String("Hello");
System.out.println(a == b);
System.out.println(a.equals(b));


false
true

Cara kasebut equalsora diwatesi ing Stringkelas. Saben kelas duwe.

Malah kelas sing sampeyan tulis dhewe, lan iki sebabe.



2. Objectkelas

Kabeh kelas ing Jawa nduweni warisan Objectkelas. Para pangripta Jawa nggawe pendekatan iki.

Lan yen kelas marisi Objectkelas, banjur entuk kabeh metode kelas Object. Lan iki minangka akibat utama saka warisan.

Ing tembung liya, saben kelas duwe metode kelas Object, sanajan kode kasebut ora kasebut.

Cara sing diwarisake iki kalebu metode sing ana gandhengane karo perbandingan obyek. Iki equals()lan hashCode()cara.

Kode Ing kasunyatan, iki sing bakal kita lakoni:
class Person
{
   String name;
   int age;
}
class Person extends Object
{
   String name;
   int age;

   public boolean equals(Object obj)
   {
      return this == obj;
   }

   public int hashCode()
   {
      return address_of_object_in_memory; // This is the default implementation, but there may be a different implementation
   }
}

Ing conto ing ndhuwur, kita nggawe Personkelas prasaja kanthi jeneng lan paramèter umur, nanging ora siji cara. Nanging amarga kabeh kelas marisi Objectkelas kasebut, Personkelas kasebut kanthi otomatis duwe rong cara:

Metode Katrangan
boolean equals(Object obj)
Mbandhingake obyek saiki lan obyek liwati
int hashCode()
Ngasilake kode hash saka obyek saiki

Pranyata pancen saben obyek duwe equalsmetode, lan obyek saka macem-macem jinis bisa dibandhingake karo saben liyane. Kode kasebut bakal dikompilasi lan bisa digunakake kanthi sampurna.

Kode Output konsol
Integer a = 5;
String s = "Hello";
System.out.println(a.equals(s));
System.out.println(s.equals(a));


false
false
Object a = new Integer(5);
Object b = new Integer(5);
System.out.println(a.equals(b)) ;


true

3. equals()cara

Cara kasebut equals(), sing diwarisake saka Objectkelas, ngetrapake algoritma sing paling gampang kanggo mbandhingake obyek saiki karo obyek sing dilewati: mung mbandhingake referensi menyang obyek.

Sampeyan entuk asil sing padha yen sampeyan mung mbandhingake Personvariabel tinimbang nelpon equals()metode kasebut. Tuladha:

Kode Output konsol
Person a = new Person();
a.name = "Steve";

Person b = new Person();
b.name = "Steve";

System.out.println(a == b);
System.out.println(a.equals(b));






false
false

Nalika equalsmetode kasebut diarani a, mung mbandhingake referensi sing disimpen ing avariabel karo referensi sing disimpen ing bvariabel kasebut.

Nanging, comparison dianggo beda kanggo Stringkelas. Kenging punapa?

Amarga wong-wong sing nggawe Stringkelas kasebut nulis implementasine metode kasebut dhewe equals().

Implementasine equals()metode

Saiki ayo nulis implementasine metode sing padha ing Personkelas. Kita bakal nimbang 4 kasus utama.

penting:
Preduli saka kelas kang overrides equalscara, iku tansah njupuk Objectobyek minangka bantahan

Skenario 1 : obyek sing padha karo equalsmetode kasebut uga diterusake menyang equalsmetode kasebut. Yen referensi saka obyek saiki lan obyek liwati padha, cara kudu bali true. Objek iku padha karo awake dhewe.

Ing kode bakal katon kaya iki:

Kode Katrangan
public boolean equals(Object obj)
{
   if (this == obj)
    return true;

   // The rest of the code of the equals method
}


Mbandhingake referensi

Skenario 2 : nullditerusake menyang equalsmetode - ora ana sing bisa dibandhingake. Objek sing equalsdiarani metode kasebut mesthi ora nol, mula kita kudu bali falseing kasus iki.

Ing kode bakal katon kaya iki:

Kode Katrangan
public boolean equals(Object obj)
{
   if (this == obj)
      return true;

   if (obj == null)
      return false;

   // The rest of the code of the equals method
}


Mbandhingake referensi


Apa obyek sing dilewati null?

Skenario 3 : referensi kanggo obyek sing dudu a Personditerusake menyang equalsmetode. Apa Personobyek padha karo non- Personobyek? Iku pitakonan kanggo pangembang kelas Personkanggo mutusake apa sing dikarepake.

Nanging biasane obyek kudu kelas sing padha kanggo dianggep padha. Mulane, yen soko liyane saka obyek saka Personkelas wis liwati kanggo kita padha metode, banjur kita bakal tansah bali false. Kepiye sampeyan bisa mriksa jinis obyek? Sing bener - kanthi nggunakake instanceofoperator.

Mangkene tampilan kode anyar kita:

Kode Katrangan
public boolean equals(Object obj)
{
   if (this == obj)
      return true;

   if (obj == null)
      return false;

   if (!(obj instanceof Person))
      return false;

   // The rest of the code of the equals method
}


Mbandhingake referensi


Apa obyek sing dilewati null?


Yen obyek liwati ora aPerson

4. Mbandhingake rong Personobyek

Apa kita mungkasi? Yen kita wis tekan pungkasan cara, kita duwe Personreferensi obyek sing ora null. Supaya kita Ngonversi menyang a Personlan mbandhingaké data internal cocog saka loro obyek. Lan iku skenario kaping papat kita .

Kode Katrangan
public boolean equals(Object obj)
{
   if (this == obj)
      return true;

   if (obj == null)
      return false;

   if (!(obj instanceof Person))
      return false;

   Person person = (Person) obj;

   // The rest of the code of the equals method
}


Mbandhingake referensi


Apa obyek sing dilewati null?


Yen obyek liwati dudu Person


Typecasting

Lan kepiye sampeyan mbandhingake rong Personobyek? Padha padha yen padha duwe jeneng padha ( name) lan umur ( age). Kode pungkasan bakal katon kaya iki:

Kode Katrangan
public boolean equals(Object obj)
{
   if (this == obj)
      return true;

   if (obj == null)
      return false;

   if (!(obj instanceof Person))
      return false;

   Person person = (Person) obj;

   return this.name == person.name && this.age == person.age;
}


Mbandhingake referensi


Apa obyek sing dilewati null?


Yen obyek liwati dudu Person


Typecasting

Nanging ora mung kuwi.

Pisanan, kolom jeneng yaiku String, dadi sampeyan kudu mbandhingake kolom jeneng kanthi nelpon equalsmetode kasebut.

this.name.equals(person.name)

Kapindho, namelapangan bisa uga null: yen ngono, sampeyan ora bisa nelpon equals. Sampeyan perlu mriksa tambahan kanggo null:

this.name != null && this.name.equals(person.name)

Sing jarene, yen kolom jeneng ana nulling loro Personobyek kasebut, mula jeneng kasebut isih padha.

Kode kanggo skenario kaping papat bisa uga katon kaya iki:

Person person = (Person) obj;

if (this.age != person.age)
   return false;

if (this.name == null)
   return person.name == null;

return this.name.equals(person.name);


Yen umur ora padha,
langsung return false

Yen this.namepadha karo null, ora ana gunane kanggo mbandhingake nggunakake equalsmetode kasebut. Ing kene, kolom kapindho namepadha karo null, utawa ora.

Mbandhingake rong kolom jeneng nggunakake equalsmetode kasebut.


5. hashCode()cara

Saliyane equalscara, kang dimaksudaké kanggo nindakake comparison rinci kabeh kothak loro obyek, ana cara liyane sing bisa digunakake kanggo comparison imprecise nanging cepet banget hashCode():.

Bayangake sampeyan ngurutake dhaptar ewonan tembung miturut abjad, lan sampeyan kudu mbandhingake pasangan tembung bola-bali. Lan tembung-tembung kasebut dawa, dumadi saka pirang-pirang huruf. Umumé, perbandingan kasebut bakal njupuk wektu sing dawa banget.

Nanging bisa akselerasi. Upamane kita duwe tembung sing diwiwiti nganggo huruf sing beda-beda - langsung jelas yen beda. Nanging yen padha diwiwiti kanthi huruf sing padha, mula kita durung bisa ngomong apa asile: tembung kasebut bisa dadi padha utawa beda.

Cara hashCode()kerjane nggunakake prinsip sing padha. Yen sampeyan nelpon ing obyek, ngasilake sawetara nomer - analog kanggo huruf pisanan ing tembung. Nomer iki nduweni sifat ing ngisor iki:

  • Objek sing padha tansah duwe kode hash sing padha
  • Objek sing beda bisa duwe kode hash sing padha, utawa kode hash bisa beda
  • Yen obyek duwe kode hash sing beda, mula obyek kasebut mesthi beda

Kanggo nggawe iki luwih cetha, ayo padha reframe properti iki ing syarat-syarat tembung:

  • Tembung sing padha tansah duwe aksara pisanan sing padha.
  • Tembung-tembung sing beda-beda bisa duwe aksara pisanan sing padha, utawa aksara pisanan bisa uga beda
  • Yen tembung duwe aksara pisanan beda, mula tembung kasebut mesthi beda

Properti pungkasan digunakake kanggo nyepetake perbandingan obyek:

Kaping pisanan, kode hash saka rong obyek kasebut diitung. Yen kode hash iki beda, mula obyek kasebut mesthi beda, lan ora perlu mbandhingake maneh.

Nanging yen kode hash padha, mula kita isih kudu mbandhingake obyek nggunakake metode sing padha.



6. Kontrak ing kode

Tindak tanduk kang wis kasebut ing ndhuwur kudu ditindakake dening kabeh kelas ing Jawa. Sajrone kompilasi, ora ana cara kanggo mriksa apa obyek dibandhingake kanthi bener.

Programer Jawa duwe persetujuan universal yen nulis implementasine dhewe saka metode sing padha () lan kanthi mangkono ngilangi implementasi standar (ing Objectkelas), dheweke uga kudu nulis implementasine metode kasebut hashCode()kanthi cara sing aturan kasebut wareg.

Pengaturan iki diarani kontrak .

Yen sampeyan mung ngleksanakake equals()utawa mung hashCode()cara ing kelas, sampeyan ana ing reged nglanggar kontrak (sampeyan wis bejat persetujuan). Aja nindakake iki.

Yen programer liyane nggunakake kode sampeyan, bisa uga ora bisa digunakake kanthi bener. Apa maneh, sampeyan bakal nggunakake kode sing gumantung marang ketaatan kontrak ing ndhuwur.

Penting!

Nalika nggoleki unsur, kabeh koleksi Java mbandhingake kode hash saka obyek, lan banjur nindakake perbandingan nggunakake equalsmetode kasebut.

Tegese yen sampeyan menehi kelas sampeyan equalsmetode nanging sampeyan ora nulis hashCode()metode sampeyan dhewe utawa sampeyan salah ngleksanakake, koleksi bisa uga ora bisa digunakake kanthi bener karo obyek sampeyan.

Contone, sampeyan bisa nambah obyek menyang dhaptar banjur nggoleki kanthi nggunakake contains()metode kasebut, nanging koleksi kasebut ora bisa nemokake obyek sampeyan.