Kezdőoldal » Számítástechnika » Programozás » Javaban ezt hogyan lehet...

Javaban ezt hogyan lehet megoldani?

Figyelt kérdés

Legyen adott egy osztály, pl:

public class Test{

int a;

int b;

int c;

}


és én azt mondom, hogy két ilyen egyezzen meg - feltéve, hogy test1 és test2 Test típusú objektumok - ha test1.a == test2.a.


Hogyan tudnám ezt a program számára is "megmondani". Mármint arra értem, hogyha pl van egy HashSet<Test> objektumom, akkor ha már a test1 benne van, akkor a test2 ne kerüljön bele?


2016. dec. 26. 13:50
1 2
 1/15 anonim ***** válasza:
Felül kell definiálni az equals metódust.
2016. dec. 26. 13:57
Hasznos számodra ez a válasz?
 2/15 A kérdező kommentje:
Ebben kérhetek segítséget, hogy kellene?
2016. dec. 26. 14:02
 3/15 anonim ***** válasza:
100%

Erre a java.lang.Object-ből örökölt boolean equals(Object o) és int hashCode() lesz jó.


Az equals összehasonlítja a this példányt a paraméterként kapott o példánnyal, és true értéket ad eredményül, ha a két objektum állapota (azaz a mezői [magyarul, a benne lévő változók]) megegyezik. Ez igazából egy négylépéses metódus:

1) Megnézzük, hogy a paraméterként kapott objektum nem null-e. Ekkor ugye a valamit a semmivel hasonlítjuk össze, ami nyilván nem ugyanaz, tehát az eredményünk false.

2) Megnézzük, hogy a paraméterként kapott objektum a mi osztályunknak a példánya-e - amennyiben nem, az eredmény false lesz. Ez azért szükséges, mert hiába hasonlítunk össze egy almát egy fluxuskondenzátorral, az nyilván nem fog megegyezni.

3) Most, hogy már tudjuk, hogy a paraméterként kapott objektum a mi osztályunknak a példánya, így nyugodtan típuskényszeríthetünk, hogy hozzáférjünk az objektumunk állapotához.

4) Ha a this és a paraméterként kapott objektum állapota megegyezik, az eredmény true, különben false.


Példa:


public class Test {

public int a;

public int b;


@Override

public boolean equals(Object o) {

.. //1. lépés:

.. if (o == null)

.. .. return false;


.. //2. lépés:

.. if (!(o instanceof Test))

.. .. return false;


.. //3. lépés:

.. Test obj = (Test)o;


.. //4. lépés:

.. return this.a == obj.a && this.b == obj.b;

}

}


És ez így fog működni, hogy:

Test a = new Test(4, 3);

Test b = new Test(4, 3);

Test c = new Test(5, 2);

[Közben lett egy konstruktor is benne.]

if (a.equals(b)) //Az eredmény true

.. Az "a" példány állapota megegyezik a "b" példány állapotával.


if (a.equals(c)) ...; //Ennek pedig false lesz az eredménye

else ...; //Tehát az else ág hajtódik majd végre


Viszont, ha override-oltad az equals-t, akkor illik a hashCode-ot is. Ez a hashCode pedig azt fogja csinálni, hogy az objektum állapotából egy egész számot állít elő. A technika az lesz, hogy választasz egy prímszámot (van ajánlás rá, hogy milyet érdemes, de ezt én most nem tudom IQ-ból), és ezt fogod szépen felszorozgatni/növelni a mezőid/változóid értéke alapján.


class Test {

public int a;

public int b;

public String c;


@Override

public int hashCode() {

.. return 7 * this.a * this.b * c.hashCode();

}

}


Amennyiben információim helyesek, Java-ban ezt a hashCode-ot használja a HashMap és a HashSet is.

2016. dec. 26. 14:13
Hasznos számodra ez a válasz?
 4/15 A kérdező kommentje:
Nagyon szépen köszönöm a részletes választ!!
2016. dec. 26. 14:21
 5/15 anonim ***** válasza:

Még annyit hozzátennék, hogy ha equals-szel hasonlítasz össze két objektumot, akkor mindig azt vedd előre, amiben 100%-ig biztos vagy, hogy nem null. Ez azért kell, mert így elég hatásos módon meg fogsz úszni egy NullReferenceException-t.


Például:

String szoveg = "sajt";

if (szoveg.equals("sajt"))

.. System.out.println("A szoveg értéke tényleg sajt.");


Ezzel akkor lesz gond, ha a szoveg értéke null:

String szoveg = null; //Valamilyen metódushívás egy null értékű (azaz nem létező) String-et adott eredményül

if (szoveg.equals("sajt")) //Amint ez kiértékelődik, rögtön NullReferenceException kivétellel lehal a programod

.. System.out.println("A szoveg értéke tényleg sajt.");


Tehát ezt érdemesebb így:

String szoveg = null;

if ("sajt".equals(szoveg)) //A "sajt"-ot vesszük előre, mert az 100%, hogy létezik, így az equals első lépése garantálja, hogy ne kapjunk NullReferenceException-t.

.. System.out.println("A szoveg értéke tényleg sajt.");

2016. dec. 26. 14:24
Hasznos számodra ez a válasz?
 6/15 Piert ***** válasza:
Annyit helyesbítenék a második válaszon, hogy az equalsban nem szükséges a paramétert külön nullra is ellenőrizni, mivel ezt az instanceof operátor is megteszi és null esetén hamisat ad vissza. Egyébként korrektnek tűnik.
2016. dec. 26. 17:06
Hasznos számodra ez a válasz?
 7/15 anonim ***** válasza:

Ezzel csak annyi gond van, hogy ezt nem mindenki tudja. Tegyük fel, ha valaki átjön mondjuk a Python-os vagy a C#-pos világból, ránéz a kódra, nem fog leesni neki, hogy az instanceof az null esetén false-t ad vissza ahelyett, hogy kivételt dobna. Vannak dolgok a programozás világában, amiket jobb, ha leírunk, minthogy valamilyen ismeretet elvárjunk.


Fú de le leszek ezért pontozva...

2016. dec. 26. 17:14
Hasznos számodra ez a válasz?
 8/15 anonim ***** válasza:

Legtöbb normális IDE támogatja hogy legenerálja neked az equals és hashCode metódusokat, keress rá hogy a saját fejlesztő környezetedben hogy lehet.


Gyakori hiba hogy valaki override-olja az equals-t, de hashCode-ot nem. Ezek párban járnak, ha egyiket megváltoztatod, a másikat is meg kell.

2016. dec. 26. 18:45
Hasznos számodra ez a válasz?
 9/15 A kérdező kommentje:
Értem, ezt megfogadom! De miért kell?
2016. dec. 26. 21:31
 10/15 anonim ***** válasza:

Java dokumentációja szerint:


"If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result."


Ez egy előírás (azaz ha két objektum egyenlő akkor a hashkódjaik is legyen egyenlőek). A HashSet pl. csak akkor működik helyesen ha ez teljesül. A HashCode alapján számolja ki hogy az objektum melyik "vödörbe" kerüljön a memóriában, és vödrön belül alkalmazza az equals-t. Ettől olyan gyors. Ebből következik ha nem egyeznek a hashkódjai két egyenlő objektumnak, akkor csak véletlenszerű az, hogy egy vödörbe kerülnek e, és észreveszi e a program hogy az objektumot már egyszer beraktuk a Setbe. Az is véletlenszerű hogy a contains() metódus mit fog visszaadni.

2016. dec. 26. 22:50
Hasznos számodra ez a válasz?
1 2

Kapcsolódó kérdések:




Minden jog fenntartva © 2025, www.gyakorikerdesek.hu
GYIK | Szabályzat | Jogi nyilatkozat | Adatvédelem | Cookie beállítások | WebMinute Kft. | Facebook | Kapcsolat: info(kukac)gyakorikerdesek.hu

A weboldalon megjelenő anyagok nem minősülnek szerkesztői tartalomnak, előzetes ellenőrzésen nem esnek át, az üzemeltető véleményét nem tükrözik.
Ha kifogással szeretne élni valamely tartalommal kapcsolatban, kérjük jelezze e-mailes elérhetőségünkön!