1. ๋ฌด์์ ๋ํด ์์๋ณด๋์? ๐ค๐ญ
์ด๋ฒ์ ์์๋ณผ ๋ด์ฉ์ Hash ํํ์ ์๋ฃ ๊ตฌ์กฐ์์ (ex - HashMap, HashSet ๋ฑ) ์ ์ฅ๋ ์๋ฃ๊ฐ์ ๋๋ฑ์ฑ์ ์ด๋ป๊ฒ ๋น๊ตํ๋์ง์ ์ด๊ฒ์ ์ฐ๋ฆฌ์ ํ๋ก์ ํธ๋ ์๊ณ ๋ฆฌ์ฆ ํ์ด์ ๋ง๊ฒ ์ฌ์ ์ ํ๋ ๋ฐฉ๋ฒ์ ๋ํด ์์๋ณด๊ฒ ๋ค.
2. ์ ์ด๊ฑธ ์์์ผ ํ์ฃ ? ๐คท๐ปโ๏ธ
๋ฌผ๋ก HashMap์ key๋ HashSet์ ๊ฐ์ผ๋ก ์์์๋ฃํ๋ง์ ์ฌ์ฉํ๋ค๋ฉด, ํด๋น ๋ด์ฉ์ ์์๋ณผ ํ์๊ฐ ์๋ค. ํ์ง๋ง ๋ง์ฝ HashMap์ key๋ก ์ฐ๋ฆฌ๊ฐ ์๋กญ๊ฒ ๋ง๋ ํด๋์ค์ ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํด์ผํ๋ ์๊ฐ์ด ์จ๋ค๋ฉด ํด๋น ๋ด์ฉ์ ์๋ ๊ฒ์ด ๊ทนํ ๋์์ด ๋๊ณ , ๋ฌธ์ ํด๊ฒฐ ์์ผ๋ฅผ ๋ํ์ค๋ค.
์๋ํ๋ฉด ๊ฐ๋ฐ์๊ฐ ์ฌ์ ์ ํด์ฃผ์ง ์๋ ์ด์ Hash ์๋ฃ๊ตฌ์กฐ๋ ๊ฐ์ฒดํ ์๋ฃ์ ๋ํ ๋๋ฑ์ฑ ๋น๊ต๋ฅผ ํ์ง ๋ชปํ๊ธฐ ๋๋ฌธ์ด๋ค.
(1) ๊ฐ์ฒดํ Key๋ก๋ ๋๋ฑ์ฑ ๋น๊ต๊ฐ ๋์ง ์๋ ์ด์
๊ฒฐ๋ก : ๊ฐ์ฒด์ ๊ฐ์ ์ฐธ์กฐํ ๋ณ์
๊ฐ์ ๋๋ฑ์ฑ์ ๋น๊ตํ ๊ฒฝ์ฐ, Hash ์๋ฃ๊ตฌ์กฐ๋ ๊ธฐ๋ณธ์ ์ผ๋ก ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๋ฅผ ์ด์ฉํด ๋น๊ตํ๋ค. ์ด๋ ๊ฐ๋ฐ์๊ฐ ์ํ๋ ์๋ฏธ์ ์ผ๋ก ๊ฐ์ ๊ฐ์ฒด๋ฅผ ๋์ผํ๋ค ํ๋จํ๊ธฐ
๋ผ๋ ์กฐ๊ฑด์ ๋ง์กฑ์ํค์ง ๋ชปํ๋ค.
ํด๋น ๊ธ์์๋ HashMap
์ ๊ธฐ์ค์ผ๋ก ๋ด์ฉ์ ์ค๋ช
ํ๊ฒ ์ง๋ง, HashSet๊ณผ ๊ฐ์ ๋ค๋ฅธ Hash ์๋ฃ๊ตฌ์กฐ์ ํต์ฉ๋๋ ๋ด์ฉ์ด๋ค.
โป HashMap์์ Key ๊ฐ์ ํด๋นํ๋ value๋ฅผ ๊บผ๋ด๋ ๊ณผ์
HashMap์ key-value Entry๋ ๋ชจ๋ Hash Bucket
์ด๋ผ๋ ์ ์ฅ์์ ๋ถ๋ฅ๋์ด ์ ์ฅ๋๋ค. ์ฌ๊ธฐ์ ๋ถ๋ฅ๋๋ ๊ธฐ์ค์ HashCode
์ด๋ค. ์ฆ, ๊ฐ์ hashCode๋ฅผ ๊ฐ์ง Key๋ค์ ๊ฐ์ hash Bucket์ ์ ์ฅ๋๋ค.
a. map.get(Key)๋ฅผ ํ๋ฉด HashMap์ ์ธ์๋ก ๋ค์ด์จ Key์ HashCode
๋ฅผ ํ์ธํ๊ณ , ๊ทธ hashCode๊ฐ ์ํ Bucket์ ์กฐํํ๋ค.
b. ๋ง์ฝ bucket์์ ๊ฐ์ด 2๊ฐ ์ด์์ด๋ฉด, Key.equals()๋ฅผ ์ด์ฉํ์ฌ ์ธ์ Key์ ๋๋ฑ
ํ Key๊ฐ์ด ์๋์ง ์ฐพ๋๋ค.
c. ๋ง์ฝ ์ธ์์ ๋๋ฑํ Key๊ฐ ์๋ค๋ฉด Null์ ์ถ๋ ฅํ๊ณ , ์๋ค๋ฉด ํด๋น key์ value๋ฅผ ๋ฐํํ๋ค.
โป ๋๋ฑ์ฑ ๋น๊ต ์๋๋ ์ด์
์์ 1,2,3 ๊ณผ์ ์ ๋ณด๋ฉด (1) hashCode๋ฅผ ํ์ฉํด ํฌ๊ฒ ํ ๋ฒ ๊ฑธ๋ฌ๋ด๊ธฐ
, (2) equals()๋ฅผ ํ์ฉํด ์ ๋ฐํ๊ฒ ๊ฐ์ ๊ฐ ์ฐพ๊ธฐ
์ ์์ผ๋ก ์งํ๋๋ ๊ฒ์ ์ ์ ์๋ค.
์ด๋ฅผ ์ํด์ 1์ฐจ๋ก Key ๊ฐ์ hashCode()๋ฅผ ๋จผ์ ํ์ฉํ๊ณ ๊ทธ ํ equals()๋ฅผ ํ์ฉํ๋ค. ์์ ์๋ฃํ์ด๋ฉด ์ด ๋ ๋ค ์ฑ๊ณต์ ์ผ๋ก ์ด๋ฃจ์ด์ง์ง๋ง, Key๋ก ์ฐธ์กฐํ์ ํ์ฉํ๋ค๋ฉด
, hashCode๋ ๊ฐ์ฒด์ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์
๋ก ๋ง๋ค์ด์ง๊ณ , equals()๋ ๋น๊ต๋๋ ๋ ๋์์ด ์ฐธ์กฐํ๋ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๊ฐ ๊ฐ์์ง๋ก ๋๋ฑ์ฑ์ ๋น๊ตํ๊ธฐ ๋๋ฌธ์, Key๋ง๋ค ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๊ฐ ๋ชจ๋ ๋ฌ๋ผ ๋๋ฑ์ฑ ๋น๊ต ์์ฒด๊ฐ ๋์ง ์๋๋ค.
๋ฐ๋ผ์ ๋ฉค๋ฒ ๋ณ์๊ฐ ๊ฐ์์ ์๋ฏธ์ ์ผ๋ก ๊ฐ์ ๊ฐ์ฒด A,B๊ฐ ์๊ณ ์ด ๋์ HashMap์ Key๋ก ์ฌ์ฉํ๋ค๋ฉด Key๋ A ๋ฐ๋ก B ๋ฐ๋ก ๋ง๋ค์ด์ง๊ณ ๊ด๋ฆฌ๋์ง, ์๋ก Value ๊ฐ์ ๊ณต์ ํ๋ฉฐ ๊ฐฑ์ ํ์ง๋ ์๋๋ค๋ ์๋ฆฌ์ด๋ค. ์ด๋ฌ๋ฉด ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๋ฅผ ๋ฐ๋ก ์ ์ฅํ์ฌ ๋์ง ์๋๋ค๋ฉด ๊ฐ์ฒด ๊ฐ์ ๊ฐ์ง Hash ์๋ฃ ๊ตฌ์กฐ๋ ํ์ฉํ์ง ๋ชปํ๋ค๋ ๊ฒฐ๋ก ์ด ๋์จ๋ค.
(2) equals()์ hashCode()์ ๊ด๊ณ
์๊น ์์์ ์ค๋ช
ํ๋ฏ์ด (1) hashCode๋ฅผ ํ์ฉํด ํฌ๊ฒ ํ ๋ฒ ๊ฑธ๋ฌ๋ด๊ธฐ
, (2) equals()๋ฅผ ํ์ฉํด ์ ๋ฐํ๊ฒ ๊ฐ์ ๊ฐ ์ฐพ๊ธฐ
๊ณผ์ ์ผ๋ก ๊ฐ๋ค.
์ด ๋ง ๋ป์,
- equals()๊ฐ true์ธ ๋ Key A,B๋ ๋ฌด์กฐ๊ฑด ๊ฐ์ HashCode๋ฅผ ๊ฐ์ง๋ค.
- ๋ Key C,D๊ฐ ๊ฐ์ hashCode๋ฅผ ๊ฐ์ง๋ค๊ณ ํด์ ๋ฌด์กฐ๊ฑด ๋๋ฑํ ๊ฐ์ฒด๋ ์๋๋ค!
๊ฐ ์ฑ๋ฆฝ๋๋ค.
3. ์ด๋ป๊ฒ ๋๋ฑ์ฑ์ ๋ง์ถฐ์ฃผ์ฃ ? ๐ฏ
๋จผ์ ๋์ผํ๋ค
์ ๋๋ฑํ๋ค
์ ์ฐจ์ด๋ฅผ ๊ตฌ๋ถํ ํ์๊ฐ ์์ ๊ฒ ๊ฐ๋ค. ์ผ์์ํ์์๋ ๋ ์ฉ์ด๋ ๋น์ทํ ๋ถ๋ฅ์ด์ง๋ง ๋ค๋ฅธ ์๋ฏธ๋ก ์ฌ์ฉ๋๋ค.
๋จผ์ ๋์ผํ๋ค
๋ ๋ ๋ฌผ์ฒด A,B๊ฐ ์์ ํ ๊ฐ๋ค.
๋ฅผ ์๋ฏธํ๋ค. ์ด๋ฅผ ์ฝ๋ฉ์ ๋์
ํด๋ณด๋ฉด, ๋ ๊ฐ์ฒด ํน์ ๋ณ์๊ฐ ๋์ผํ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๋ฅผ ๊ฐ์ง๋ค.
๋ก ํ์ดํ ์ ์๋ค. ๋์ ์์ ๊ฐ์ ๊ฒ์ด๋ ๋ป์ด๋ค. A,B๊ฐ ๋์ผํ ๊ฐ์ฒด๋ผ๋ฉด ==
์ผ๋ก ๋น๊ตํด๋ true๊ฐ ๋์จ๋ค.
๋๋ฑํ๋ค
๋ ๋ ๋ฌผ์ฒด A,B๊ฐ ๊ฐ์ ์๊ฒฉ์ ๊ฐ์ง๊ณ ์๋ค.
๋ฅผ ๋ปํ๋ค. ์ด๋ฅผ ์ฝ๋ฉ์ ๋์
ํด๋ณด๋ฉด ๋ ๊ฐ์ฒด๊ฐ ๋ค๋ฅธ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๋ฅผ ๊ฐ์ง๋๋ผ๋ ๋ด์ฉ๋ฌผ์ ์์ ํ ๊ฐ๋ค.
๋ฅผ ์๋ฏธํ๋ค. A,B๊ฐ ๋๋ฑํ ๊ฐ์ฒด๋ผ๋ฉด ==
์ผ๋ก ๋น๊ต ์ false๊ฐ ๋์ค๊ฒ ์ง๋ง, ๋ด์ฉ๋ฌผ๋ง ๋น๊ตํ ๊ฒฝ์ฐ (ex- String์ equals()) true๊ฐ ๋์จ๋ค.
(1) ์ฐ๋ฆฌ๊ฐ ๋๋ฑํ๋ค๊ณ ์๊ฐํ๋ ๊ธฐ์ค
์ฐ๋ฆฌ๊ฐ ์๊ฐํ๋ ๋ ๊ฐ์ฒด A,B๊ฐ ๊ฐ๋ค
์ ์๋ฏธ๋ A,B๊ฐ ๋์ผํ๋ค์ ์๋ฏธ๊ฐ ์๋ ๋ ๊ฐ์ฒด A,B๊ฐ ๋๋ฑํ๋ค
์ ์๋ฏธ๋ก ์ฐ์ธ๋ค.
๋ฉ๋ชจ๋ฆฌ ์ฃผ์๋ ๋ค๋ฅด๋๋ผ๋, ๋ด์ฉ๋ฌผ์ ๊ฐ๋ค๋ ๊ฒ์ด๋ค.
(2) hashCode ๋ง์ถ๊ธฐ
equals()๋ก ๋ ๊ฐ์ฒด A,B์ ๋๋ฑ์ฑ์ ํ๋จํ๋ ค๋ฉด ๋จผ์ ๋ ๊ฐ์ฒด A,B๊ฐ ๊ฐ์ Bucket์ ์กด์ฌํ๋ค.
๊ฐ ์ฑ๋ฆฝํ์ฌ์ผํ๋ค. ์๋ํ๋ฉด, Hash ์๋ฃ๊ตฌ์กฐ๋ ๋ด๋ถ์ ์ผ๋ก ๋๋ฑ์ฑ์ ํ๋จํ๊ธฐ ์ ์ hashcode ์ผ์น ์ฌ๋ถ๋ก ๋๋ฑ์ฑ ํ๋จ ๋์์ ๋๊ฑฐ ๊ฑธ๋ฌ๋ด๊ธฐ ๋๋ฌธ์ด๋ค. (์ด๊ฒ์ด Hash ์๋ฃ๊ตฌ์กฐ๊ฐ ์กฐํ์ ๋น ๋ฅธ ์ด์ ์ด๊ธฐ๋ ํ๋ค.)
๋ฐ๋ผ์ ์๋ฌด๋ฆฌ A.equals(B) == true๋ผ๊ณ ํ๋๋ผ๋ A์ B์ hashCode๊ฐ ๋ฌ๋ผ๋ฒ๋ฆฌ๋ฉด ๋ง์งฑ ๋๋ฃจ๋ฌต์ด๋ค.
๋ฐ๋ผ์ ๊ฐ์ฒด์ hashCode๋ฅผ ๋ง๋๋ hashCode()
๋ผ๋ ํจ์๋ฅผ ๊ฐ์ฒด์ ๋ด์ฉ๋ฌผ์ด ๊ฐ์ผ๋ฉด ๊ฐ์ hash bucket
์ ํฌํจ๋๋๋ก ์ฌ์ ์ ํด์ค์ผ ํ๋ค. ์ฌ์ ์ ์์๋ ๋ค์๊ณผ ๊ฐ๋ค.
Class Exam1 {
int x;
int y;
@Override
public int hashcode() {
return Objects.hash(x,y);
}
}
์์์ ์ฐ์ธ Objects.hash() ํจ์๋ ์ธ์๋ก ๋ค์ด์จ ๊ฐ์ผ๋ก hashCode๋ฅผ ๋ง๋ ๋ค. ์ธ์๊ฐ ๊ฐ์ผ๋ฉด ๋น์ฐํ ๊ฐ์ hashcode๊ฐ ๋์จ๋ค. (๋ด์ฉ๋ฌผ์ด ๊ฐ์ผ๋ฉด ๊ฐ์ hashcode๊ฐ ๋์จ๋ค.) ๋ค์์ Objects.hash(Object... values)
์ ๋ด๋ถ์ธ๋ฐ ๊ถ๊ธํ์ ๋ถ์ ์ฐธ๊ณ ํ๋ผ.
public static int hash(Object... values) { // ์ธ์์ ๊ฐ์๊ฐ ์ ํด์ ธ์๊ธฐ ์๊ธฐ์ ๋ช๊ฐ๋ ์๊ด ์๋ค.
return Arrays.hashCode(values);
}
public static int hashCode(Object a[]) { // hashcode๋ฅผ ๋ง๋๋ ๋ก์ง
if (a == null)
return 0;
int result = 1;
for (Object element : a)
result = 31 * result + (element == null ? 0 : element.hashCode());
return result;
}
(3) equals() ๋ง์ถ๊ธฐ
์ด์ ๋ด์ฉ๋ฌผ์ด ๊ฐ์ ๊ฐ๋ค์ ๋ชจ๋ ๊ฐ์ hash Bucket์ ์ง์ด๋ฃ๊ธฐ
๊น์ง๋ ์ฑ๊ณตํ์ผ๋ฏ๋ก ๋ด์ฉ๋ฌผ์ด ๊ฐ๋ค๋ฉด ๋๋ฑํ๋ค ํ๋จํ๊ธฐ
๋ง ๋จ์๋ค.
๋๋ฑ์ฑ ํ๋จ์ ์ํด์๋ equals()๋ฅผ ์ฌ์ ์ ํด์ค์ผ ํ๋ค. ์์๋ ๋ค์๊ณผ ๊ฐ๋ค
Class Exam {
int x;
int y;
@OVerride
public boolean equals(Object obj) {
if(this == obj) return true; // ์ธ์์ ๋น๊ต๋๋ ๊ฐ์ด `๋์ผ`ํ๋ค๋ฉด true๋ฅผ ๋ฐ๋ก ๋ฐํํ์ฌ ๋ถํ์ํ ๊ณ์ฐ ์ค์ด๊ธฐ
if(obj == null || this.getClass() != obj.getClass()) return false; // ์ธ์๊ฐ null ์ด๊ฑฐ๋, ๋น๊ต๋์๊ณผ ํ์
์ด ๋์ผํ์ง ์๋ค๋ฉด false ๋ฐํ
Exam opponent = (Exam) obj;
return (this.x == opponent.x && this.y == opponent.y);
}
}
4. ํ์ด๋ณด๋ฉด ์ข์ ๋ฌธ์ ๐
https://school.programmers.co.kr/learn/courses/30/lessons/340211
ํด๋น๋ฌธ์ ๋ ์์์ ๋ฐฐ์ด ๋ด์ฉ์ ํ์ฉํ๋ฉด ์ญ๋ถ ์ฝ๊ฒ ํ ์ ์๋ ๋ฌธ์ ์ด๋ค.