JavaRush /Blog Jawa /Random-JV /Ngopi #168. Napa nolak cara sing padha lan kode hash ing ...

Ngopi #168. Napa nolak cara sing padha lan kode hash ing Jawa?

Diterbitake ing grup

Napa nolak cara sing padha lan kode hash ing Jawa?

Sumber: Sedheng Artikel iki fokus ing rong cara sing raket banget: padha () lan kode hash () . Sampeyan bakal sinau carane padha sesambungan karo saben liyane lan carane ngatasi kanthi bener. Ngopi #168.  Napa nolak cara sing padha lan kode hash ing Jawa?  - 1

Apa kita ngalahake cara padha ()?

Ing Jawa, kita ora bisa kakehan prilaku operator kaya == , += , -+ . Dheweke kerja miturut proses tartamtu. Contone, nimbang operasi operator == .

Kepiye cara kerja operator ==?

Iku mriksa apa loro referensi sing dibandhingake nuduhake conto sing padha ing memori. Operator == mung bakal ngevaluasi bener yen loro referensi kasebut minangka conto sing padha ing memori. Ayo ndeleng kode sampel:
public class Person {
      private Integer age;
      private String name;

      ..getters, setters, constructors
      }
Contone, ing program sampeyan wis nggawe rong obyek Person ing macem-macem panggonan lan pengin mbandhingake.
Person person1 = new Person("Mike", 34);
Person person2 = new Person("Mike", 34);
System.out.println( person1 == person2 ); --> will print false!
Saka perspektif bisnis, loro katon padha, ta? Nanging kanggo JVM padha ora padha. Amarga loro-lorone digawe nggunakake tembung kunci anyar , kedadeyan kasebut ana ing bagean memori sing beda. Mulane operator == bakal ngasilake false . Nanging yen kita ora bisa ngalahake operator == , banjur kepiye carane kita ngandhani JVM yen kita pengin loro obyek kasebut dianggep padha? Iki ngendi .equals () cara teka menyang muter . Sampeyan bisa override witjaksono () kanggo mriksa yen sawetara obyek duwe nilai padha kanggo lapangan tartamtu supaya nimbang padha. Sampeyan bisa milih kolom kanggo mbandhingake. Yen kita ngomong yen rong obyek Wong bakal padha mung yen padha umur lan jeneng sing padha, banjur IDE bakal generate kaya iki kanggo otomatis nggawe padha () :
@Override
public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return age == person.age &&
                name.equals(person.name);
    }
Ayo bali menyang conto sadurunge.
Person person1 = new Person("Mike", 34);
Person person2 = new Person("Mike", 34);
System.out.println ( person1 == person2 ); --> will print false!
System.out.println ( person1.equals(person2) ); --> will print true!
Ya, kita ora bisa kakehan operator == kanggo mbandhingake obyek kanthi cara sing dikarepake, nanging Jawa menehi cara liya - cara sing padha () , sing bisa diganti kaya sing dikarepake. Tetep wonten ing pikiran sing yen kita ora nyedhiyani versi adat saka .equals () (uga dikenal minangka override) ing kelas kita, banjur .equals () saka kelas Obyek lan operator == bakal nindakake padha. Default equals() method , diwarisake saka Object , bakal mriksa yen loro kedadean dibandhingake padha ing memori!

Napa kita overriding metode hashCode ()?

Sawetara struktur data ing Jawa, kayata HashSet lan HashMap , nyimpen unsur-unsur kasebut adhedhasar fungsi hash sing ditrapake kanggo unsur kasebut. Fungsi hash yaiku hashCode() . Yen kita duwe pilihan ing overriding .equals () cara , banjur kita uga kudu pilihan ing overriding hashCode () cara . Ana alesan kanggo iki. Sawise kabeh, implementasine standar saka hashCode () , sing diwarisake saka Obyek , nganggep kabeh obyek ing memori unik! Nanging ayo bali menyang struktur data hash iki. Ana aturan kanggo struktur data kasebut. HashSet ora bisa ngemot nilai duplikat lan HashMap ora bisa ngemot kunci duplikat. HashSet diimplementasikake nggunakake HashMap kanthi cara supaya saben nilai HashSet disimpen minangka kunci ing HashMap . Kepiye cara HashMap ? HashMap minangka array asli kanthi pirang-pirang segmen. Saben segmen nduweni daftar sing disambung ( linkedList ). Dhaptar sing disambung iki nyimpen kunci kita. HashMap nemokake linkedList sing bener kanggo saben tombol nggunakake metode hashCode () , lan banjur ngulang kabeh unsur linkedList kasebut lan nggunakake metode sing padha () kanggo saben unsur kasebut kanggo mriksa manawa unsur kasebut ana ing kono. Duplikat tombol ora diijini. Ngopi #168.  Napa nolak cara sing padha lan kode hash ing Jawa?  - 2Nalika kita sijine soko ing HashMap a , tombol disimpen ing salah siji saka dhaptar pranala iki. Daftar sing disambungake tombol iki bakal disimpen ditampilake kanthi asil metode hashCode () kanggo tombol kasebut. Sing, yen key1.hashCode () asil ing 4, banjur key1 bakal disimpen ing bagean 4th saka Uploaded ing LinkedList ana . Kanthi gawan, metode hashCode () ngasilake asil sing beda kanggo saben conto. Yen kita duwe standar padha () sing tumindak kaya == , nambani kabeh kedadean ing memori minangka obyek beda, banjur ora ana masalah. Kaya sing sampeyan kelingan, ing conto sadurunge kita ujar manawa kita pengin conto Wong dianggep padha yen umur lan jenenge padha.
Person person1 = new Person("Mike", 34);
    Person person2 = new Person("Mike", 34);
    System.out.println ( person1.equals(person2) );  --> will print true!
Saiki ayo nggawe peta kanggo nyimpen kedadeyan kasebut minangka kunci kanthi senar tartamtu minangka pasangan nilai.
Map<Person, String> map = new HashMap();
map.put(person1, "1");
map.put(person2, "2");
Ing kelas Person , kita wis ora overridden metode hashCode , nanging kita duwe overridden equals method . Wiwit hashCode standar menehi asil beda kanggo kedadean Jawa beda person1.hashCode () lan person2.hashCode () , ana kemungkinan dhuwur kanggo njupuk asil beda. Peta kita bisa mungkasi karo wong sing beda-beda ing dhaptar sing digandhengake. Ngopi #168.  Napa nolak cara sing padha lan kode hash ing Jawa?  - 3Iki nglawan logika HashMap . Sawise kabeh, HashMap ora bisa duwe sawetara tombol sing padha! Titik iku hashCode standar () sing diwarisake saka kelas Obyek ora cukup. Malah sawise kita ngilangi cara padha () saka kelas Person . Pramila kita kudu ngilangi metode hashCode () sawise ngilangi metode sing padha . Saiki ayo ndandani iki. Kita kudu ngilangi metode hashCode () supaya nganggep kolom sing padha karo equals() , yaiku umur lan jeneng .
public class Person {
      private Integer age;
      private String name;

      ..getters, setters, constructors
@Override
public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return age == person.age &&
                name.equals(person.name);
    }
@Override
public int hashCode() {
        int prime = 31;
        return prime*Objects.hash(name, age);
    }
Ing metode hashCode () digunakake nilai prasaja (sampeyan bisa nggunakake sembarang nilai liyane). Nanging, disaranake nggunakake nomer prima kanggo nggawe masalah sing luwih sithik. Coba simpen maneh kunci kasebut ing HashMap :
Map<Person, String> map = new HashMap();
map.put(person1, "1");
map.put(person2, "2");
person1.hashCode () lan person2.hashCode () bakal padha. Ayo dadi 0. HashMap bakal pindhah menyang segmen 0 lan ing LinkedList bakal nyimpen person1 minangka kunci kanthi nilai "1". Ing kasus kapindho, nalika HashMap pindhah menyang ember 0 maneh kanggo nyimpen tombol person2 kanthi nilai "2", bakal weruh yen tombol liyane sing padha karo sing wis ana. Kanthi cara iki bakal nimpa tombol sadurunge. Lan mung wong2 kunci sing bakal ana ing HashMap kita . Mangkene carane kita sinau carane aturan HashMap bisa digunakake , sing nyatakake yen sampeyan ora bisa nggunakake macem-macem tombol sing padha! Nanging, elinga yen kedadeyan sing ora padha bisa duwe kode hash sing padha, lan conto sing padha kudu ngasilake kode hash sing padha.Ngopi #168.  Napa nolak cara sing padha lan kode hash ing Jawa?  - 4
Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION