์๋ฐ์ equals() ๋ฉ์๋๋ ๋ ๊ฐ์ฒด๊ฐ ๋
ผ๋ฆฌ์ ์ผ๋ก ๊ฐ์์ง ๋น๊ตํ ๋ ์ฌ์ฉํ๋ ๋ฉ์๋์ด๋ค. ์ด๋ โ๊ฐ๋คโ์ ๊ธฐ์ค์ ๋จ์ํ ๊ฐ์ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๋ฅผ ๊ฐ๋ฆฌํค๋์ง๋ฅผ ์๋ฏธํ๋ ๊ฒ์ด ์๋ ๊ฐ์ฒด์ ๋ด๋ถ ๊ฐ์ด ๋์ผํ์ง(๋
ผ๋ฆฌ์ ๋๋ฑ์ฑ)๋ฅผ ์๋ฏธํ๋ค.
String a = new String("BlueCool");
String b = new String("BlueCool");
System.out.println(a == b); // false (์ฐธ์กฐ๊ฐ์ด ๋ค๋ฆ)
System.out.println(a.equals(b)); // true (๋ฌธ์์ด์ด ๊ฐ์)
์ ์์์์ == ์ฐ์ฐ์๋ ๋ ๊ฐ์ฒด๊ฐ ๊ฐ์ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์(์ฐธ์กฐ)๋ฅผ ๊ฐ์ง๋์ง๋ฅผ ๋น๊ตํ๋ค. ๋ฐ๋ผ์ new ํค์๋๋ก ๊ฐ๊ฐ ์์ฑํ String ๊ฐ์ฒด๋ ์๋ก ๋ค๋ฅธ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ ์กด์ฌํ๋ฏ๋ก ๋ด์ฉ์ด ๊ฐ๋๋ผ๋ false๋ฅผ ๋ฐํํ๋ค.
๊ทธ๋ฌ๋ String ํด๋์ค๋ ์ด๋ฏธ equals() ๋ฉ์๋๋ฅผ ์ค๋ฒ๋ผ์ด๋ฉํ์ฌ ๋ฌธ์์ด์ ๋ด์ฉ์ด ๊ฐ์ผ๋ฉด true๋ฅผ ๋ฐํํ๋๋ก ์ฌ์ ์๋์ด ์๋ค.
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
return (anObject instanceof String aString)
&& (!COMPACT_STRINGS || this.coder == aString.coder)
&& StringLatin1.equals(value, aString.value);
}
์ฆ String ํด๋์ค์์๋ ์ฐธ์กฐ ๋์ผ์ฑ(==) ๋์ ๋
ผ๋ฆฌ์ ๋์ผ์ฑ์ ๊ธฐ์ค์ผ๋ก ๋๋ฑ์ฑ์ ํ๋จํ๋ค. equals() ๋ฉ์๋๋ ๋ชจ๋ ํด๋์ค์ ์ต์์ ๋ถ๋ชจ์ธ Object ํด๋์ค์ ์ ์๋์ด ์์ผ๋ฉฐ ๊ธฐ๋ณธ ๊ตฌํ์ ๋จ์ํ ์ฐธ์กฐ๊ฐ์ด ๊ฐ์์ง๋ฅผ ๋น๊ตํ๋ค.
Object blue = new Object();
Object cool = new Object();
System.out.println(blue.equals(cool)); // false
System.out.println(blue == cool); // false
// ์ค์ Object ํด๋์ค์ equals() ๊ธฐ๋ณธ ๊ตฌํ
public boolean equals(Object obj) {
return (this == obj);
}
๋ฐ๋ผ์ ์ฌ์ฉ์๊ฐ ์ง์ ์ ์ํ ํด๋์ค์์ ๊ฐ์ฒด์ ๋
ผ๋ฆฌ์ ๋๋ฑ์ฑ์ ํ๋จํ๋ ค๋ฉด ๋ค์์ ๊ท์น์ ์งํค๋ฉฐ equals() ๋ฉ์๋๋ฅผ ์ค๋ฒ๋ผ์ด๋ฉํด์ผ ํ๋ค.
x.equals(x)๋ ํญ์ true์ฌ์ผ ํ๋ค. x.equals(y)๊ฐ true๋ฉด y.equals(x)๋ true์ฌ์ผ ํ๋ค. x.equals(y)์ y.equals(z)๊ฐ true๋ฉด x.equals(z)๋ true์ฌ์ผ ํ๋ค. equals()์ ๊ฒฐ๊ณผ๋ ํญ์ ๋์ผํด์ผ ํ๋ค. x.equals(null)์ ํญ์ false๋ฅผ ๋ฐํํด์ผ ํ๋ค. hashCode()๋ ๊ฐ์ฒด๋ฅผ ์ซ์๋ก ํํํ ํด์๊ฐ์ ๋ฐํํ๋ ๋ฉ์๋์ด๋ค. ์ด ๊ฐ์ HashMap, HashSet๊ณผ ๊ฐ์ ํด์ ๊ธฐ๋ฐ ์ปฌ๋ ์
์์ ๊ฐ์ฒด๋ฅผ ๋น ๋ฅด๊ฒ ์ ์ฅํ๊ณ ํ์ํ๊ธฐ ์ํ ๋ฒํท ์ธ๋ฑ์ค ํค๋ก ์ฌ์ฉ๋๋ค.
Developer dev = new Developer("BlueCool", 12);
int hash = dev.hashCode(); // ์์: 427492637
hashCode()์ ์ญํ ์ ๋จ์ํ ์ซ์๋ฅผ ๋ง๋๋ ๊ฒ์ด ์๋๋ผ ๋๋ฑํ ๊ฐ์ฒด๋ ๋ฐ๋์ ๋์ผํ ํด์์ฝ๋๋ฅผ ๊ฐ์ ธ์ผ ํ๋ค๋ ๊ท์ฝ์ ์งํค๋๋ฐ ์๋ค.
Hash ๊ธฐ๋ฐ ์ปฌ๋ ์
์ ๋ด๋ถ์ ์ผ๋ก hashCode() ๊ฐ์ ์ด์ฉํด ์ ์ฅ ์์น(๋ฒํท)์ ๊ณ์ฐํ๊ณ ๊ฐ์ ๋ฒํท์ ์ฌ๋ฌ ๊ฐ์ฒด๊ฐ ์กด์ฌํ๋ ๊ฒฝ์ฐ equals() ๋ฉ์๋๋ฅผ ์ฌ์ฉํด ๋
ผ๋ฆฌ์ ์ผ๋ก ๊ฐ์ ๊ฐ์ฒด์ธ์ง ์ต์ข
ํ์ธํ๋ค.
๋ฐ๋ผ์ equals()๋ง ์ฌ์ ์ํ๊ณ hashCode()๋ฅผ ์ฌ์ ์ํ์ง ์์ผ๋ฉด ๋
ผ๋ฆฌ์ ์ผ๋ก ๊ฐ์ ๊ฐ์ฒด์ด๋๋ผ๋ ์๋ก ๋ค๋ฅธ ํด์๊ฐ์ ๊ฐ์ง ์ ์๊ฒ ๋์ด HashMap, HashSet ๋ฑ์ ์ปฌ๋ ์
์์ ์ค๋ณต์ผ๋ก ์ ์ฅ๋๊ฑฐ๋ ์กฐํ, ์ญ์ ์ ์คํจํ๊ฒ ๋๋ ๋ฑ ์น๋ช
์ ์ธ ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ค.
๋ฐ๋ผ์ equals()๋ฅผ ์ฌ์ ์ํ ๋๋ ๋ฐ๋์ hashCode()๋ ํจ๊ป ์ฌ์ ์ํด์ผํ๋ฉฐ hashCode ๋ฉ์๋๋ฅผ ์ฌ์ ์ ํ ๋๋ ๋ค์๊ณผ ๊ฐ์ ๊ท์ฝ์ ๋ฐ๋ฅธ๋ค.
hashCode()์ ๊ฐ์ด ๋ณํ์ง ์์์ผ ํ๋ค. x.equals(y)๊ฐ true๋ฉด ๋ฐ๋์ x.hashCode() == y.hashCode()์ฌ์ผ ํ๋ค. ์ฌ์ฉ์ ์ ์ ํด๋์ค์์ ๊ฐ์ฒด์ ๋
ผ๋ฆฌ์ ๋๋ฑ์ฑ์ ํ๋จํ๋ ค๋ฉด equals()์ hashCode()๋ฅผ ํจ๊ป ์ฌ์ ์ํด์ผ ํ๋ค. ์ผ๋ฐ์ ์ผ๋ก ๋ค์๊ณผ ๊ฐ์ ๋ฐฉ์์ผ๋ก ๊ตฌํํ๋ค.
import java.util.Objects;
class Developer {
private String name;
private int age;
public Developer(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object o) {
if (this === o) return true;
if (!(o instanceof Developer)) return false;
Developer dev = (Developer) o;
return age == dev.age && Objects.equals(name, dev.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
์ ์ฝ๋์์๋ Objects.equals()์ Objects.hash()๋ฅผ ์ฌ์ฉํ์ฌ equals()์ hashCode()๋ฅผ ๊ฐ๊ฒฐํ๊ฒ ๊ตฌํํ์๋ค.
์ด๋ ๊ฒ ๊ตฌํํ๋ฉด ๋ Developer ๊ฐ์ฒด์ name๊ณผ age ๊ฐ์ด ๋์ผํ ๊ฒฝ์ฐ ๊ฐ์ ๊ฐ์ฒด๋ก ํ๋จํ๋ฉฐ ๋์ผํ ํด์์ฝ๋๋ฅผ ๋ฐํํ๊ฒ ๋๋ค.
์ค๋ฌด์์๋ Lombok์ ์ฌ์ฉํ์ฌ equals()์ hashCode()๋ฅผ ์๋์ผ๋ก ์์ฑํ๋ ๊ฒฝ์ฐ๋ ๋ง๋ค.
import lombok.EqualsAndHashCode;
@EqualsAndHashCode
public class Developer {
private String name;
private int age;
}โ
๋๋ @Data ์ด๋
ธํ
์ด์
์ ์ฌ์ฉํ์ฌ equals(), hashCode(), getter, setter ๋ฑ์ ํจ๊ป ์๋ ์์ฑํ ์ ์๋ค.
