Tömbök összehasonlítása Java-ban

1. Áttekintés

Ebben az oktatóanyagban megnézzük különböző módon összehasonlíthatja a tömböket a Java-ban. Kitérünk a hagyományos módszerekre, és néhány példát is megnézünk lambdakifejezések.

2. Tömbök összehasonlítása

Összehasonlítjuk a Java tömböket, és mint tudjuk, ezek objektumok. Ezért frissítsünk néhány alapfogalmat:

  • Az objektumok referenciákkal és értékekkel rendelkeznek
  • Két egyenlő hivatkozásnak ugyanarra az értékre kell mutatnia
  • Két különböző értéknek eltérő hivatkozással kell rendelkeznie
  • Két egyenlő értéknek nincs feltétlenül ugyanaz a hivatkozása
  • A primitív értékeket csak értékenként lehet összehasonlítani
  • A karakterláncok csak értékenként hasonlíthatók össze

2.1. Objektum hivatkozások összehasonlítása

Ha két hivatkozásunk ugyanarra a tömbre mutat, akkor mindig eredményt kell kapnunk igaz egyenlő összehasonlításban a == operátor.

Nézzünk meg egy példát:

Karakterlánc [] síkok1 = új húr [] {"A320", "B738", "A321", "A319", "B77W", "B737", "A333", "A332"}; Húr [] sík2 = sík1;

Először létrehoztunk egy tömb síkmodellt, amelyre hivatkozunk repülőgépek1. Ezután létrehozunk repülőgépek2, amely hivatkozik repülőgépek1. Ezzel megtesszük két referenciát létrehozvaugyanarra a tömbre a memóriában. Ezért a „Sík1 == sík2” kifejezés visszatér igaz.

Tömbök esetén a egyenlő () metódus megegyezik az == operátorral. Így, sík1.egyenlő (sík2) visszatér igaz mert mindkét hivatkozás ugyanarra az objektumra vonatkozik. Általában véve, array1.eqauls (tömb2) vissza fog térni igaz csak akkor, ha a kifejezés tömb1 == tömb2 ” visszatér igaz.

Állítsuk be, ha a két hivatkozás megegyezik:

assertThat (síkok1) .isSameAs (síkok2);

Most legyünk biztosak abban, hogy a repülőgépek1 valójában megegyeznek a hivatkozottakkal repülőgépek2. Ezért megváltoztathatjuk az által hivatkozott tömböt repülőgépek2, és ellenőrizze, hogy a változtatások befolyásolják-e a repülőgépek1:

sík2 [0] = "747";

Hogy végre láthassuk ezt a munkát, tegyük meg állításainkat:

assertThat (síkok1) .isSameAs (síkok2); assertThat (síkok2 [0]). isEqualTo ("747"); assertThat (síkok1 [0]). isEqualTo ("747");

Ezzel az egységpróbával két tömböt tudtunk összehasonlítani referenciaként.

Ezt azonban csak bebizonyítottuk az egyik referencia, miután hozzárendeltük egy másik értékéhez, ugyanazt az értéket fogja hivatkozni.

Most két különböző tömböt hozunk létre ugyanazokkal az értékekkel:

Karakterlánc [] síkok1 = új húr [] {"A320", "B738", "A321", "A319", "B77W", "B737", "A333", "A332"}; Húr [] sík2 = új húr [] {"A320", "B738", "A321", "A319", "B77W", "B737", "A333", "A332"};

Mivel különböző tárgyakról van szó, pontosan tudjuk, hogy nem azonosak. Ezért összehasonlíthatjuk őket:

assertThat (síkok1) .isNotSameAs (síkok2);

Összefoglalva: ebben az esetben két tömb van a memóriában, amelyek ugyanazt tartalmazzák Húr értékek pontosan ugyanabban a sorrendben. A hivatkozott tömbök azonban nemcsak tartalmukban különböznek, hanem maguk a hivatkozások is különböznek egymástól.

2.2. A tömbhosszak összehasonlítása

A tömbök hossza ettől függetlenül összehasonlítható elemtípusaikból, vagy hogy kitöltik-e értékeiket.

Hozzunk létre két tömböt:

végső húr [] síkok1 = új húr [] {"A320", "B738", "A321", "A319", "B77W", "B737", "A333", "A332"}; végső egész szám [] mennyiségek = új egész szám [] {10, 12, 34, 45, 12, 43, 5, 2};

Ez két különböző tömb, különböző elemtípusokkal. Ebben az adatkészletben példaként regisztráljuk, hogy az egyes modellekből hány repülőgép van tárolva a raktárban. Most futtassunk rajtuk egység teszteket:

assertThat (síkok1) .hasSize (8); assertThat (mennyiségek) .hasSize (8);

Ezzel bebizonyítottuk, hogy mindkét tömbnek nyolc eleme van, és hogy a hossz tulajdonság minden tömbhöz megfelelő számú elemet ad vissza.

2.3. A tömbök összehasonlítása a Tömbök.egyenlő

Eddig csak a tömböket hasonlítottuk össze a tárgyazonosságuk alapján. Másrészről, annak ellenőrzésére, hogy két tömb tartalma tekintetében megegyezik-e, a Java biztosítja a Tömbök.egyenlő statikus módszer. Ez a módszer a tömbökön keresztül, pozíciónként párhuzamosan iterál és alkalmazza a == operátort,minden elempárra.

Hozzunk létre két különböző tömböt ugyanazzal Húr literálok pontosan ugyanabban a sorrendben:

Húr [] síkok1 = új húr [] {"A320", "B738", "A321", "A319", "B77W", "B737", "A333", "A332"}; Karakterlánc [] sík2 = új húr [] {"A320", "B738", "A321", "A319", "B77W", "B737", "A333", "A332"};

Most pedig állítsuk, hogy egyenlőek:

assertThat (Tömbök.egyenlő (síkok1, síkok2)). isTrue ();

Ha megváltoztatjuk a második tömb értékeinek sorrendjét:

Karakterlánc [] síkok1 = új húr [] {"A320", "B738", "A321", "A319", "B77W", "B737", "A333", "A332"}; Karakterlánc [] sík2 = új húr [] {"B738", "A320", "A321", "A319", "B77W", "B737", "A333", "A332"}; 

Más eredményt kapunk:

assertThat (Tömbök.egyenlő (síkok1, síkok2)). isFalse ();

2.4. A tömbök összehasonlítása a Arrays.deepEquals

Használni a == operátor egyszerű, ha egyszerű típusokat használunk a Java-ban. Ezek lehetnek primitív típusok vagy Húr literálok. A tömbök összehasonlítása Tárgys bonyolultabb lehet. Ennek hátterében az ok maradéktalanul meg van magyarázva Arrays.deepEquals cikk. Lássunk egy példát.

Először kezdjük a Repülőgép osztály:

public class Plane {private final String name; privát végleges String modell; // szerelők és beállítók}

És hajtsuk végre a hash kód és egyenlő mód:

@Orride public boolean egyenlő (Object o) if (ez == o) return true; if (o == null @ Nyilvános int hashCode felülbírálása () {return Objects.hash (név, modell);}

Másodsorban hozzuk létre a következő két elemű tömböket:

Sík [] [] sík1 = új Sík [] [] {új Sík [] {új Sík ("Sík 1", "A320")}, új Sík [] {új Sík ("Sík 2", "B738") }}; Sík [] [] sík2 = új Sík [] [] {új Sík [] {új Sík ("Sík 1", "A320")}, új Sík [] {új Sík ("Sík 2", "B738") }}; 

Most nézzük meg, hogy igazak-e, mélyen egyenlő tömbök:

assertThat (Tömbök.deepEquals (síkok1, síkok2)). isTrue ();

Annak érdekében, hogy összehasonlításunk a várt módon működjön, változtassuk meg az utolsó tömb sorrendjét:

Sík [] [] sík1 = új Sík [] [] {új Sík [] {új Sík ("Sík 1", "A320")}, új Sík [] {új Sík ("Sík 2", "B738") }}; Sík [] [] sík2 = új Sík [] [] {új Sík [] {új Sík ("Sík 2", "B738")}, új Sík [] {új Sík ("Sík 1", "A320") }};

Végül teszteljük, hogy valóban nem egyenlők-e már:

assertThat (Tömbök.deepEquals (síkok1, síkok2)). isFalse ();

2.5. A tömbök összehasonlítása az elemek különböző sorrendjeivel

Annak ellenőrzéséhez, hogy a tömbök egyenlőek-e, függetlenül az elemek sorrendjétől, meg kell határoznunk mi teszi az egyik példányunkat Repülőgép egyedi. Esetünkben egy másik név vagy modell elegendő annak megállapításához, hogy az egyik sík különbözik a másiktól. Ezt úgy állapítottuk meg, hogy mindkettőt már megvalósítottuk hash kód és egyenlő mód. Ez azt jelenti, hogy mielőtt összehasonlíthatnánk tömbjeinket, válogatnunk kell őket. Ehhez szükségünk van a Összehasonlító:

Összehasonlító sík: Összehasonlító = (o1, o2) -> {if (o1.getName (). Egyenlő (o2.getName ())) {return o2.getModel (). CompareTo (o1.getModel ()); } return o2.getName (). CompareTo (o1.getName ()); };

Ebben Összehasonlító, elsőbbséget adunk a névnek. Ha a nevek megegyeznek, akkor a modell megnézésével oldjuk meg a kétértelműséget. A karakterláncokat a összehasonlítani típusú módszer Húr.

Azt akarjuk tudni, hogy a tömbök a rendezési sorrendtől függetlenül megegyezzenek-e. Ehhez válasszuk most tömbjeinket:

Tömbök.rendezés (síkok1 [0], síkKomparátor); Tömbök.rendezés (síkok2 [0], síkKomparátor);

És végül teszteljük őket:

assertThat (Tömbök.deepEquals (síkok1, síkok2)). isTrue ();

Miután a tömböket először ugyanabban a sorrendben rendeztük, megengedjük a deepEquals módszer annak megállapítására, hogy ez a két tömb egyenlő-e.

3. Következtetés

Ebben az oktatóanyagban a tömbök összehasonlításának különböző módjait láthattuk. Másodszor, láttuk a különbséget a referenciák és az értékek összehasonlítása között. Ezenkívül megvizsgáltuk, hogyan lehet mélyen összehasonlítani a tömböket. Végül láttuk a különbséget a normál összehasonlítás és a mély összehasonlítás között egyenlő és deepEqualsill.

Mint mindig, a példák teljes forráskódja elérhető a GitHubon.