Porovnávání objektů
-
Test na rovnost/nerovnost lze použít na porovnávání primitivních hodnot i objektů:
==
,!=
-
Na objekty nelze použít operátory porovnání "dle velikosti", tzn.
<
,<=
,>=
,>
— ani to nelze dodefinovat jako vC++
.
Jak chápat rovnost objektů
Warning
|
|
Porovnávání objektů pomocí ==
Použití ==
na objekty:
-
Porovnáme-li dva objekty (tzn. odkazy na objekty) prostřednictvím operátoru
==
dostaneme rovnost jen v případě, jedná-li se o dva odkazy na tentýž objekt — tj. dva totožné objekty. -
Jedná-li se o dva obsahově stejné objekty, ale existující samostatně, pak
==
vrátífalse
.
Porovnávání objektů dle obsahu
-
Chceme-li (intuitivně) chápat rovnost objektů podle obsahu, tj.
-
dva objekty jsou rovné (rovnocenné, nikoli totožné), mají-li stejný obsah, pak
-
musíme pro danou třídu překrýt metodu
equals
, která musí vrátittrue
, právě když se obsah výchozího a srovnávaného objektu rovná. -
Fungování
equals
lze srovnat s porovnáváním dvou databázových záznamů podle primárního klíče. -
Nepřekryjeme-li
equals
, funguje původníequals
přísným způsobem, tj. rovné si budou jen totožné objekty .
Příklad porovnávání objektů
Objekt třídy Person
nese informace o člověku.
Zde dva objekty položíme stejné (rovnocenné),
nesou-li stejná příjmení.
public class Person { private String firstname; private String surname; public Person (String j, String p) { firstname = j; surname = p; } public boolean equals(Object o) { if (o instanceof Person) { Person c = (Person)o; // dva lidé se rovnají, mají-li stejná příjmení return surname.equals(c.surname); } else { // porovnáváme-li osobu s ne-osobou... return false; } } }
Metoda hashCode
-
S překrytím metody
equals
vyvstává jeden dosud nezaznamenaný problém. -
Jakmile u třídy překryjeme metodu
equals
, měli bychom současně překrýt i metoduhashCode
. Tato metoda vrací celé číslo (int
) co nejlépe charakterizující obsah objektu tak, aby:-
pro dva stejné (dle
equals
) objekty musí vždy vrátit stejnou hodnotu. -
Pro dva obsahově různé objekty by
hashCode
naopak měla vracet různé hodnoty, což ale není stoprocentně nezbytné a ani nemůže být vždy splněno.
-
Note
|
Metoda |
Příklad hashCode
-
V těle
hashCode
námi definované třídy s oblibou delegujeme řešení na voláníhashCode
jednotlivých složek našeho objektu -
a to těch, které figurují v
equals
. Rozšíříme minulý příklad.public class Person { private String firstname; private String surname; public Person (String firstname, String surname) { this.firstname = firstname; this.surname = surname; } public boolean equals(Object o) { // zde zůstává porovnání příjmení } // nyní ale doplňujeme překrytí hashCode public int hashCode() { // které využívá volání hashCode na příjmení, // protože jedině příjmení využíváme v equals return surname.hashCode(); } }