์ด๋ฒ ๊ธ์์๋ ์ง๊ธ๊น์ง์ ๋ด์ฉ์ ์ข ํฉํด์ ์์ง์ equals ๋ฉ์๋ ๊ตฌํ ๋ฐฉ๋ฒ๊ณผ ์ฃผ์ ์ฌํญ์ ๋ํด์ ์์๋ณด๊ณ ์ ํ๋ค.
1. equals ๊ตฌํ ๋ฐฉ๋ฒ
- == ์ฐ์ฐ์๋ฅผ ์ฌ์ฉํด ์ ๋ ฅ์ด ์๊ธฐ ์์ ์ ์ฐธ์กฐ์ธ์ง ํ์ธํ๋ค.
- instanceof ์ฐ์ฐ์๋ก ์ ๋ ฅ์ด ์ฌ๋ฐ๋ฅธ ํ์ ์ธ์ง ํ์ธํ๋ค.
- ์ ๋ ฅ์ ์ฌ๋ฐ๋ฅธ ํ์ ์ผ๋ก ํ๋ณํํ๋ค.
- ์
๋ ฅ ๊ฐ์ฒด์ ์๊ธฐ ์์ ์ ๋์๋๋ 'ํต์ฌ' ํ๋๋ค์ด ๋ชจ๋ ์ผ์นํ๋์ง ํ๋์ฉ ๊ฒ์ฌํ๋ค.
float์ double์ ์ ์ธํ ๊ธฐ๋ณธ ํ์ ํ๋๋ == ์ฐ์ฐ์๋ก ๋น๊ตํ๊ณ , ์ฐธ์กฐ ํ์ ํ๋๋ ๊ฐ๊ฐ์ equals ๋ฉ์๋๋ก, float๊ณผ double ํ๋๋ ๊ฐ๊ฐ ์ ์ ๋ฉ์๋์ธ Float.compare(float, float)์ Double.compare(double, double)๋ก ๋น๊ตํ๋ค. (float์ double์ ํน๋ณ ์ทจ๊ธํ๋ ์ด์ ๋ Float.NaN, -0.0f, ํน์ํ ๋ถ๋์์ ๊ฐ ๋ฑ์ ๋ค๋ค์ผ ํ๊ธฐ ๋๋ฌธ์ด๋ค.)
public 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) {
// 1. == ์ฐ์ฐ์๋ฅผ ์ฌ์ฉํด ์
๋ ฅ์ด ์๊ธฐ ์์ ์ ์ฐธ์กฐ์ธ์ง ํ์ธํ๋ค.
if(this == o) {
return true;
}
// 2. instanceof ์ฐ์ฐ์๋ก ์
๋ ฅ์ด ์ฌ๋ฐ๋ฅธ ํ์
์ธ์ง ํ์ธํ๋ค.
if(!(o.instanceof Point))
return false;
// 3. ์
๋ ฅ์ ์ฌ๋ฐ๋ฅธ ํ์
์ผ๋ก ํ๋ณํํ๋ค.
Point p = (Point)o;
// 4. ์
๋ ฅ ๊ฐ์ฒด์ ์๊ธฐ ์์ ์ ๋์๋๋ 'ํต์ฌ' ํ๋๋ค์ด ๋ชจ๋ ์ผ์นํ๋์ง ํ๋์ฉ ๊ฒ์ฌํ๋ค.
return p.x == x && p.y == y;
}
// ์์ดํ
11 ์ฐธ์กฐ
@Override public int hashCode() {
return 31 * x + y;
}
}
๋ฌธ์ ๋... ์ด๋ฐ ๊ท์ฝ์ ๋ฐ๋ฅด๋ฉด์ ๊ตฌํํ๊ธฐ๊ฐ ๋งค์ฐ ์ด๋ ต๋ค๋ ๊ฒ์ด๋ค. ๊ทธ๋์ ํด์ ์ด๋ค. 4๊ฐ์ง ํด์ ์๊ฐํ๊ฒ ๋ค.
1. @AutoValue
@AutoValue
abstract class Point {
static Point create(int x, int y) {
return new AutoValue_Point(x, y);
}
abstract int x();
abstract int y();
}
2. Lombok์ @EqualsAndHashCode์ @ToString
@EqualsAndHashCode
@ToString
public class Point {
private final int x;
private final int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
}
3. ์๋ฐ์ Record
public record Point(int x, int y){ }
4. IntelliJ์์ Generator์ 'equals() and hashCode()'
ํด๋น ๋ฐฉ๋ฒ์๋ 2๊ฐ์ง ๋จ์ ์ด ์๋ค.
- ์ฝ๋๊ฐ ์ง์ ๋ถํด์ง๋ค.(์์์ ์ด๋ ธํ ์ด์ ๊ณผ record๋ก ๊ฐ๋จํ๊ฒ ๊ตฌํํ ๊ฒ๊ณผ ๋น๊ตํด๋ณด๋ฉด ์ ์ ์๋ค.)
- ํ๋๊ฐ ์์ ๋ ๋๋ง๋ค 'equals() and hashCode()'๋ก ์์ฑ๋ ์ฝ๋๋ฅผ ์ง์ฐ๊ณ ๋ค์ ๋ง๋ค์ด์ผ ํ๋ค. (์ด๋ ธํ ์ด์ ์ผ๋ก ๊ตฌํํ ๊ฒฝ์ฐ ์ปดํ์ผํ ๋ ์๋์ผ๋ก ์ฒ๋ฆฌ๋๋๋ค๋ ๊ฒ๊ณผ ๋น๊ตํ๋ฉด ์ถฉ๋ถํ ์ดํดํ ์ ์๋ค.)
2. ์ฃผ์ ์ฌํญ
- equals๋ฅผ ์ฌ์ ์ ํ ๋ hashCode๋ ๋ฐ๋์ ์ฌ์ ์ํ์. (์์ดํ 11์์ ๋ค๋ฃฐ ์์ )
- ๋๋ฌด ๋ณต์กํ๊ฒ ํด๊ฒฐํ์ง ๋ง์ (์ด์ ๊ธ์์ URL ์์๋ฅผ ๋ ์ฌ๋ ค ๋ณด์.)
- Object๊ฐ ์๋ ํ์ ์ ๋งค๊ฐ๋ณ์๋ฅผ ๋ฐ๋ equals ๋ฉ์๋๋ ์ ์ธํ์ง ๋ง์. (ํ์ ์ ๋งค๊ฐ๋ณ์๋ฅผ ๋ฐ๋ equals ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ฉด, ํด๋น ํด๋์ค๋ฅผ List๋ Set์ ๋ฃ์ ๊ฒฝ์ฐ Object์ equals๋ก ๋น๊ตํ๊ฒ ๋๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ค.)
// ๋ง๋ ํํ
@Override public boolean equals(Object o) {
if(this == o) {
return true;
}
if(!(o.instanceof Point))
return false;
Point p = (Point)o;
return p.x == x && p.y == y;
}
// ํ๋ฆฐ ํํ
// ์ด๊ฒ์ '์ค๋ฒ๋ผ์ด๋ฉ'ํ ๊ฒ์ด ์๋๋ผ '์ค๋ฒ๋ก๋ฉ'ํ ๊ฒ์ด๋ค.
public boolean equals(Point o) {
if(this == o) {
return true;
}
if(!(o.instanceof Point))
return false;
Point p = (Point)o;
return p.x == x && p.y == y;
}
ํด๋น ๊ธ์ ๋ฐฑ๊ธฐ์ ๋์ '์ดํํฐ๋ธ ์๋ฐ ์๋ฒฝ ๊ณต๋ต'์ ์๊ฐํ๊ณ ์์ฑํ ๊ฒ์ ๋๋ค.