PDA

View Full Version : سوال: راهنمایی متد ()hashcode() equals



hamidhtc
پنج شنبه 20 آذر 1393, 05:08 صبح
1. متد hsashcode و equals چه کاری انجام میدن؟
2. تو این کلاس ساده ی مستطیل چرا از این دو متد استفاده کرده؟
تو فیلمی که میدیدم گفت این دو متد خیلی خیلی مهم هستند. (ولی بقیشو نفهمیدم! انگلیسیم خوب نیست.)


public class Rectangle {

private final int width, height;

public Rectangle(int width, int height) {
this.width = width;
this.height = height;
}

public int getWidth() {
return width;
}

public Rectangle copyWithWidth(int width) {
return new Rectangle(width, this.height);
}

public int getHeight() {
return height;
}

public Rectangle copyWithHeight(int height) {
return new Rectangle(this.width, height);
}

public int getArea() {
return width * height;
}

public int getPerimeter() {
return 2 * (width + height);
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + height;
result = prime * result + width;
return result;
}

@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (!(obj instanceof Rectangle))
return false;
Rectangle other = (Rectangle) obj;
if (height != other.height)
return false;
if (width != other.width)
return false;
return true;
}
}

ahmad.mo74
پنج شنبه 20 آذر 1393, 20:21 عصر
سلام، این متدها برای مقایسه کردن آبجکت ها خیلی خیلی مهم هستن به خصوص وقتی توی collection بریزی، چون تقریبا همشون برای مقایسه آبجکت ها از این متدها به خصوص equals استفاده میکنن.

از hashCode هم مثلا توی HashSet, HashMap, HashTable استفاده میشه، اون Hash اول اسمشون هم به خاطر همینه...

مثلا ما یه کلاس MyClass داریم، اگر یه آبجکت ازش بسازیم و چاپش کنیم یه چیز عجیب و غریبی چاپ میشه :


public class MyClass {


public static void main(String[] args) {
MyClass object = new MyClass();
System.out.println(object);
}


}


خروجی :

MyClass@77556fd

خب MyClass اش که معلومه ولی اون عدد بعدش چیه؟

حالا میایم متد hashCode رو اورراید میکنیم :


@Override
public int hashCode() {
return 1;
}


دوباره چاپ میکنیم :


MyClass@1


اوکی؟ پس اگر hashCode رو اورراید نکنیم بای دیفالت خود jvm براساس فیلدهای کلاس و یه الگوریتم خاصی یه hashcode براش میسازه.

متدهای hashCode و equals به هم وابسته هستن، طبق داکیومنتی که براشون نوشته شده موقعی که داریم این دوتا متد رو اورراید میکنیم باید حواسمون باشه که همیشه موقعی که a.equals(b); اونوقت حتما حتما باید a.hashCode() == b.hashCode() باشه.

یه مثال کاربردی دیگه :

قبل از اورراید کردن hashCode و equals :


public class MyClass {


private long id;
private String name;


public MyClass(long id, String name) {
this.id = id;
this.name = name;
}


public long getId() {
return id;
}


public void setId(long id) {
this.id = id;
}


public String getName() {
return name;
}


public void setName(String name) {
this.name = name;
}


@Override
public String toString() {
return "MyClass{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}


public static void main(String[] args) {
Set<MyClass> set = new HashSet<>();
set.add(new MyClass(1, "a"));
set.add(new MyClass(2, "b"));
set.add(new MyClass(3, "c"));
set.add(new MyClass(1, "d"));
System.out.println(set);
}


}


خروجی :


[MyClass{id=3, name='c'}, MyClass{id=1, name='a'}, MyClass{id=2, name='b'}, MyClass{id=1, name='d'}]


بعد از اورراید کردن hashCode و equals :


public class MyClass {


private long id;
private String name;


public MyClass(long id, String name) {
this.id = id;
this.name = name;
}


public long getId() {
return id;
}


public void setId(long id) {
this.id = id;
}


public String getName() {
return name;
}


public void setName(String name) {
this.name = name;
}


@Override
public int hashCode() {
return Objects.hashCode(id);
}


@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (!(obj instanceof MyClass))
return false;
MyClass other = (MyClass) obj;
return Objects.equals(id, other.getId());
}


@Override
public String toString() {
return "MyClass{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}


public static void main(String[] args) {
Set<MyClass> set = new HashSet<>();
set.add(new MyClass(1, "a"));
set.add(new MyClass(2, "b"));
set.add(new MyClass(3, "c"));
set.add(new MyClass(1, "d"));
System.out.println(set);
}


}


خروجی :


[MyClass{id=1, name='a'}, MyClass{id=2, name='b'}, MyClass{id=3, name='c'}]


یکی دیگه :


public class MyClass {


private long id;
private String name;


public MyClass(long id, String name) {
this.id = id;
this.name = name;
}


public long getId() {
return id;
}


public void setId(long id) {
this.id = id;
}


public String getName() {
return name;
}


public void setName(String name) {
this.name = name;
}


@Override
public int hashCode() {
return Objects.hashCode(id);
}


@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (!(obj instanceof MyClass))
return false;
MyClass other = (MyClass) obj;
return Objects.equals(id, other.getId());
}


@Override
public String toString() {
return "MyClass{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}


public static void main(String[] args) {
List<MyClass> list = new ArrayList<>();
list.add(new MyClass(1, "a"));
list.add(new MyClass(2, "b"));
list.add(new MyClass(3, "c"));
System.out.println(list);
System.out.println(list.contains(new MyClass(1, null)));
}


}


خروجی :


[MyClass{id=1, name='a'}, MyClass{id=2, name='b'}, MyClass{id=3, name='c'}]
true


اگر equals و hashCode رو اورراید نکرده بودیم false برمیگردوند.