Պատմեք Java-ում hashCode և equals մեթոդների պայմանների մասին։
sobes.tech AI
Պատասխան AI-ից
Java-յի hashCode և equals մեթոդների պայմանագիրը սահմանում է նրանց փոխկապակցվածությունը և ապահովում է օբյեկտների ճիշտ վարքագիծը հեշ-թաբկային հավաքածուներում (օրինակ, HashSet, HashMap) օգտագործելիս:
Հիմնական կանոնները:
- Ռեֆլեկտիվություն: Ամեն մի ոչ-զրո հղումային արժեք
xհամար,x.equals(x)պետք է վերադարձնիtrue: - Սիմետրիկություն: Ամեն մի ոչ-զրո հղումային արժեք
xևyհամար,x.equals(y)պետք է վերադարձնիtrueմիայն այն դեպքում, երբy.equals(x)նույնպեսtrueէ: - Տրանզիտություն: Ամեն մի ոչ-զրո հղումային արժեք
x,yևzհամար, եթեx.equals(y)ևy.equals(z)trueեն, ապաx.equals(z)նույնպեսtrueէ: - Կոնսիստենտություն: Ամեն մի ոչ-զրո հղումային արժեք
xևyհամար, բազմակիx.equals(y)կանչերը նույն արդյունքը պետք է տալ, եթեxևyփոփոխական չեն փոխվել: - Ոչ-զրո արժեք: Ամեն մի ոչ-զրո հղումային արժեք
xհամար,x.equals(null)պետք է վերադարձնիfalse:
Եվ հիմնական կանոնը, որը կապում է hashCode և equals:
- Եթե երկու օբյեկտներ հավասար են
equals(Object)մեթոդով, ապա նրանցhashCode()մեթոդը պետք է վերադարձնի նույն ամբողջ թիվը: - հակառակը չէ ճիշտ: եթե երկու օբյեկտների հեշ-կոդը նույնն է, դա չէ նշանակում, որ նրանք հավասար են:
Կոնտակտի արժեք:
Կոտրումը պայմանագրի կարող է հանգեցնել հավաքածուների սխալ աշխատանքի: Օրինակ, եթե երկու հավասար օբյեկտներ վերադարձնեն տարբեր հեշ-կոդեր, HashMap-ը կարող է դրանք տեղադրել տարբեր "խցիկներում" (buckets) և չի կարող գտնել մեկը մյուսի միջոցով, նույնիսկ եթե նրանք տրամաբանականորեն հավասար են:
Օրինակ ճիշտ իրականացում:
// Օրինակ կլաս, որը ճիշտ է `equals` և `hashCode`-ով
public final class Point {
private final int x;
private final int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Point point = (Point) o;
return x == point.x && y == point.y;
}
@Override
public int hashCode() {
int result = 17; // Մոգական թիվ, սովորաբար պարզ
result = 31 * result + x;
result = 31 * result + y;
return result;
}
// Գеттерներ (ոչ պարտադիր `equals`/`hashCode` համար)
public int getX() {
return x;
}
public int getY() {
return y;
}
}
Օգտագործում:
- Ամեն ժամանակ վերանայեք երկու մեթոդները (
equalsևhashCode) միասին: - Հաշվարկելիս
hashCode-ը օգտագործեք նույն դաշտերը, որոնք օգտագործվում ենequals-ում: - Փորձեք ստեղծել "լավ" հեշ-ֆունկցիաներ, որոնք հավասարապես տարածում են հեշ-կոդերը, որպեսզի նվազեցնեն բախումները (երբ տարբեր օբյեկտներ ունեն նույն հեշ-կոդը) և բարելավեն հեշավորված հավաքածուների կատարողականությունը:
- Պրիմիտիվների համար օգտագործեք նրանց արժեքները: Օբյեկտների համար կանչեք
hashCode(): Մասիվների համար օգտագործեքArrays-ի մեթոդները:
Java 7+-ում խորհուրդ է տրվում օգտագործել Objects.equals(Object a, Object b) և `Objects.hash(Object... values)``:
Օրինակ Objects-ի հետ:
// Օրինակ կլաս, որը `equals` և `hashCode`-ով օգտագործում է `Objects`
import java.util.Objects;
public final class PointWithObjects {
private final int x;
private final int y;
public PointWithObjects(int x, int y) {
this.x = x;
this.y = y;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
PointWithObjects that = (PointWithObjects) o;
return x == that.x && y == that.y; // Լոգիկան մնում է նույն
}
@Override
public int hashCode() {
return Objects.hash(x, y); // Հարմար մեթոդ հեշի հաշվարկի համար
}
}