Usporedba nizova u Javi
1. Pregled
U ovom uputstvu ćemo pogledati različiti načini za usporedbu nizova u Javi. Obradit ćemo uobičajene metode, a vidjet ćemo i neke primjere korištenja lambdaizrazi.
2. Usporedba nizova
Usporedit ćemo nizove u Javi, a kao što znamo, to su objekti. Stoga, osvježimo neke osnovne pojmove:
- Objekti imaju reference i vrijednosti
- Dvije jednake reference trebale bi ukazivati na istu vrijednost
- Dvije različite vrijednosti trebale bi imati različite reference
- Dvije jednake vrijednosti ne moraju nužno imati iste reference
- Primitivne vrijednosti uspoređuju se samo po vrijednosti
- String literali uspoređuju se samo po vrijednosti
2.1. Usporedba referenci predmeta
Ako imamo dvije reference koje upućuju na isti niz, uvijek bismo trebali dobiti rezultat pravi u jednakoj usporedbi s == operater.
Pogledajmo primjer:
Niz [] ravnine1 = novi niz [] {"A320", "B738", "A321", "A319", "B77W", "B737", "A333", "A332"}; Niz [] ravnine2 = ravnine1;
Prvo smo stvorili niz ravninskih modela na koje se poziva avioni1. Tada stvaramo avioni2, koje reference avioni1. Čineći ovo, mi smo stvaranje dvije referencena isti niz u memoriji. Stoga je “Ravnine1 == ravnine2” izraz će se vratiti pravi.
Za nizove, jednako () metoda je ista kao i operater ==. Tako, ravnine1.jednake (ravnine2) vraća se pravi jer se obje reference odnose na isti objekt. Općenito govoreći, niz1.eqauls (niz2) će se vratiti pravi ako i samo ako je izraz “niz1 == niz2 ″ vraća se pravi.
Utvrdimo jesu li dvije reference iste:
assertThat (planes1) .isSameAs (planes2);
Budimo sada sigurni da vrijednosti na koje upućuje avioni1 su zapravo isti kao oni na koje se poziva avioni2. Stoga možemo promijeniti niz na koji se poziva avioni2, i provjerite imaju li promjene utjecaja na niz na koji se poziva avioni1:
avioni2 [0] = "747";
Da bismo konačno vidjeli kako ovo djeluje, iznesite svoje tvrdnje:
assertThat (planes1) .isSameAs (planes2); assertThat (ravnine2 [0]). isEqualTo ("747"); assertThat (ravnine1 [0]). isEqualTo ("747");
Ovim jedinstvenim testom uspjeli smo usporediti dva niza referencom.
Međutim, to smo samo dokazali jedna referenca, jednom dodijeljena vrijednosti druge, referencirat će istu vrijednost.
Sada ćemo stvoriti dva različita niza s istim vrijednostima:
Niz [] ravnine1 = novi niz [] {"A320", "B738", "A321", "A319", "B77W", "B737", "A333", "A332"}; Niz [] ravnine2 = novi niz [] {"A320", "B738", "A321", "A319", "B77W", "B737", "A333", "A332"};
Budući da se radi o različitim objektima, pouzdano znamo da nisu isti. Stoga ih možemo usporediti:
assertThat (planes1) .isNotSameAs (planes2);
Da rezimiramo, u ovom slučaju imamo dva polja u memoriji koja sadrže iste Niz vrijednosti u potpuno istom redoslijedu. Međutim, ne samo da se referentni nizovi razlikuju u sadržaju, već su i same reference različite.
2.2. Usporedba duljina niza
Duljina nizova mogu se usporediti bez obzira njihovih vrsta elemenata ili jesu li njihove vrijednosti popunjene ili ne.
Stvorimo dva niza:
završni niz [] ravnine1 = novi niz [] {"A320", "B738", "A321", "A319", "B77W", "B737", "A333", "A332"}; konačni Integer [] količine = novi Integer [] {10, 12, 34, 45, 12, 43, 5, 2};
To su dva različita niza s različitim vrstama elemenata. U ovom skupu podataka, kao primjer, registriramo koliko je zrakoplova pojedinog modela pohranjeno u skladištu. Pokrenimo sada jedinstvene testove na njima:
assertThat (planes1) .hasSize (8); assertThat (količine) .hasSize (8);
Ovim smo dokazali da oba niza imaju osam elemenata i da duljina svojstvo vraća točan broj elemenata za svaki niz.
2.3. Uspoređujući nizove s Nizovi.jednak
Do sada smo uspoređivali samo nizove na temelju njihovih identiteta objekata. S druge strane, kako bi provjerila jesu li dva niza po svom sadržaju jednaka, Java nudi Nizovi.jednak statička metoda. Ova metoda će se paralelno itirirati kroz nizove, po položaju, i primijeniti operator ==,za svaki par elemenata.
Stvorimo dva različita niza s istim Niz literali u potpuno istom redoslijedu:
Niz [] ravnine1 = novi niz [] {"A320", "B738", "A321", "A319", "B77W", "B737", "A333", "A332"}; Niz [] ravnine2 = novi niz [] {"A320", "B738", "A321", "A319", "B77W", "B737", "A333", "A332"};
A sada, ustvrdimo da su jednaki:
assertThat (Nizovi.equals (ravnine1, ravnine2)). isTee ();
Ako promijenimo redoslijed vrijednosti drugog polja:
Niz [] ravnine1 = novi niz [] {"A320", "B738", "A321", "A319", "B77W", "B737", "A333", "A332"}; Niz [] ravnine2 = novi niz [] {"B738", "A320", "A321", "A319", "B77W", "B737", "A333", "A332"};
Dobit ćemo drugačiji rezultat:
assertThat (Nizovi.equals (ravnine1, ravnine2)). isFalse ();
2.4. Uspoređujući nizove s Nizovi.deepEquals
Koristiti == Operator je jednostavan ako u Java koristimo jednostavne vrste. To bi mogli biti primitivni tipovi ili Niz doslovce. Usporedba nizova od Objekts mogu biti kompliciraniji. Razlog tome je u potpunosti objašnjen u našem Nizovi.deepEquals članak. Pogledajmo primjer.
Prvo, krenimo s a Avion razred:
javna klasa Avion {privatni konačni naziv niza; privatni konačni niz stringova; // geteri i postavljači}
I, provedimo hashCode i jednako metode:
@Override public boolean equals (Object o) if (this == o) return true; if (o == null @Override public int hashCode () {return Objects.hash (ime, model);}
Kao drugo, kreirajmo sljedeće nizove od dva elementa:
Ravan [] [] avioni1 = nova avion [] [] {nova avion [] {nova avion ("avion 1", "A320")}, novi avion [] {novi avion ("avion 2", "B738") }}; Avion [] [] avioni2 = novi avion [] [] {novi avion [] {novi avion ("avion 1", "A320")}, novi avion [] {novi avion ("avion 2", "B738") }};
Pogledajmo sada jesu li to istiniti, duboko jednaki nizovi:
assertThat (Arrays.deepEquals (ravnine1, ravnine2)). isTrue ();
Da bismo bili sigurni da naša usporedba radi kako se očekivalo, promijenimo redoslijed našeg posljednjeg niza:
Ravan [] [] avioni1 = nova avion [] [] {nova avion [] {nova avion ("avion 1", "A320")}, novi avion [] {novi avion ("avion 2", "B738") }}; Avion [] [] avioni2 = novi avion [] [] {novi avion [] {novi avion ("avion 2", "B738")}, novi avion [] {novi avion ("avion 1", "A320") }};
Na kraju, testirajmo jesu li doista više jednaki:
assertThat (Arrays.deepEquals (ravnine1, ravnine2)). isFalse ();
2.5. Usporedba nizova s različitim redoslijedom elemenata
Da bismo provjerili jesu li nizovi jednaki, bez obzira na redoslijed elemenata, moramo definirati što čini jedan primjer našeg Avion jedinstven. Za naš je slučaj dovoljan drugačiji naziv ili model da se utvrdi da se jedna ravnina razlikuje od druge. To smo utvrdili već implementirajući oboje hashCode i jednako metode. To implicira da bismo ih prije nego što možemo usporediti svoje nizove trebali razvrstati. Za to nam treba Usporednik:
Usporednik planeComparator = (o1, o2) -> {if (o1.getName (). Je jednako (o2.getName ())) {return o2.getModel (). CompareTo (o1.getModel ()); } return o2.getName (). compareTo (o1.getName ()); };
U ovome Usporednik, prednost dajemo imenu. Ako su imena jednaka, dvosmislenost rješavamo promatranjem modela. Nizove uspoređujemo pomoću usporediTo metoda tipa Niz.
Želimo biti u mogućnosti pronaći jesu li nizovi jednaki bez obzira na redoslijed sortiranja. Da bismo to učinili, razvrstajmo sada naše nizove:
Nizovi.sort (ravnine1 [0], planeComparator); Nizovi.sort (planes2 [0], planeComparator);
I na kraju, testirajmo ih:
assertThat (Arrays.deepEquals (ravnine1, ravnine2)). isTrue ();
Nakon što smo prvo sortirali nizove istim redoslijedom, dopuštamo deepEquals metoda za utvrđivanje jesu li ova dva niza jednaka.
3. Zaključak
U ovom uputstvu vidjeli smo različite načine usporedbe nizova. Drugo, vidjeli smo razliku između usporedbe referenci i vrijednosti. Osim toga, pogledali smo kako možemo duboko usporediti nizove. Konačno, vidjeli smo razliku između normalne usporedbe i duboke usporedbe pomoću jednako i deepEquals, odnosno.
Kao i uvijek, puni izvorni kod za primjere dostupan je na GitHubu.