๐ ์ฃผ์
HashSet์ ๋ด๋ถ ๋์ ๋ฐฉ์๊ณผ ์ค๋ณต ์ ๊ฑฐ ๋ฉ์ปค๋์ฆ์ ์ค๋ช ํ๊ณ , HashSet์ด ํจ์จ์ ์ธ ์ค๋ณต ์ฒดํฌ๋ฅผ ํ ์ ์๋ ์ด์ ๋ฅผ ์ค๋ช ํด์ฃผ์ธ์.
์ด ๊ธ์์๋ HashSet์ ์์๋ฅผ ์ฝ์ ํ๋ ์๋ฆฌ๋ฅผ ์ดํด๋ณธ๋ค.
HashSet
import java.util.HashSet;
HashSet<Integer> set = new HashSet<>();
HashSet์ ํน์ง
- ์ค๋ณต์ ํ์ฉํ์ง ์๊ณ , ๊ณ ์ ํ ๊ฐ๋ง ์ ์ฅํ๋ค.
- null ๊ฐ์ ํ์ฉํ๋ค.
- ์์์ ์์๊ฐ ์ ์ง๋์ง ์๋๋ค.
- Java Collectios Framework ์ค Set ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ๋ค.
- ํด์ ํ ์ด๋ธ ๊ตฌ์กฐ๋ฅผ ๋ฐ๋ฅธ๋ค.
โ๏ธ ๋ด๋ถ ๋์ ๋ฐฉ์
HashSet์ HashMap์ผ๋ก ๊ตฌํ๋๋ค
HashSet ํด๋์ค๋ฅผ ๋ค์ฌ๋ค๋ณด๋ฉด ์์ฑ์์์ HashMap์ ์์ฑํ๊ณ ์๋ค.
HashSet.java
public class HashSet<E>
extends AbstractSet<E>
implements Set<E>, Cloneable, java.io.Serializable {
...
public HashSet() {
map = new HashMap<>();
}
...
}
HashSet์ ์ด HashMap ๊ฐ์ฒด์ ๋ฉ์๋๋ฅผ ์ด์ฉํด ๊ตฌํ๋๋ค.
Set์ ์์๋ฅผ ๋ํ๋ add()
๋ฉ์๋์์๋ HashMap์ put()
๋ฉ์๋๋ฅผ ํธ์ถํ๋ ๋ฐฉ์์ด๋ค.
HashSet์ ์ฝ์
ํ๋ ๊ฐ(e)์ ๋งต ๊ฐ์ฒด์ key ์ญํ ์ ํ๋ฉฐ, value์๋ ์์๋ฅผ ๋์
ํ๋ค.(-> ๋ชจ๋ ์์์ value ๊ฐ์ด ๊ฐ๋ค.)
HashSet.java
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
HashMap์์ key๋ ์ค๋ณต ๋ถ๊ฐ๋ฅํ ๊ณ ์ ์๋ณ์์ด๋ค.
HashMap์ put(key, value)
๋ฉ์๋๋
- ์ด๋ฏธ key๊ฐ ์๋ค๋ฉด ์ด์ value ๊ฐ์ ๋ฐํํ๋ค.
- key๊ฐ ์์๋ค๋ฉด, null์ ๋ฐํํ๋ค.
public class Main {
public static void main(String[] args) {
Map<Integer, Integer> map = new HashMap<>();
System.out.println(map.put(1,1));
System.out.println(map.put(1,2));
}
}
-------------------------------
์ถ๋ ฅ ๊ฒฐ๊ณผ
null
1
HashSet์ add()
์์๋ HashMap์ put()
๋ฉ์๋์ ๋ฐํ๊ฐ์ด null์ด๋ฉด ์ฐธ์, null์ด ์๋๋ฉด ๊ฑฐ์ง์ ๋ฐํํ๋ฏ๋ก HashSet์ add()๋ ๋ค์๊ณผ ๊ฐ์ด ๋์ํ๋ค.
- ์ฝ์
์ฑ๊ณต -> HashMap์
put()
์์ null ๋ฐํ -> HashSet์add()
์์ true ๋ฐํ - ์ฝ์
์คํจ -> HashMap์
put()
์์ ์ด์ value ๋ฐํ -> HashSet์add()
์์ false ๋ฐํ
โ๏ธ ์ค๋ณต ์ ๊ฑฐ ๋ฐฉ์
HashMap์์ ์ค๋ณต์ ์ ๊ฑฐํ๋ค
์ฆ, HashSet์์ ์ค๋ณต์ ์ ๊ฑฐํ๋ ๊ฒ์ HashMap์์ ์ฒ๋ฆฌํ๋ค๋ ๋ป์ด๋ค.
๊ทธ๋ ๋ค๋ฉด HashMap์์๋ ์ด๋ป๊ฒ ์ค๋ณต์ธ์ง ๊ตฌ๋ณํ ๊น?
์ด๋ hashCode()
์ equals()
๋ ๋ฉ์๋๋ฅผ ํ์ฉํ๋ค.
hashCode()
HashMap.java
public final int hashCode() {
return Objects.hashCode(key) ^ Objects.hashCode(value);
}
hashCode()
๋ฉ์๋๋ก ๊ฐ์ฒด๋ฅผ ์ ์ ํํ๋ก ๋ณํํ๋ค. ์ด ๊ณผ์ ์ ํด์ฑ์ด๋ผ๊ณ ํ๋ค.
ํด์ ์๊ณ ๋ฆฌ์ฆ์ ์์ ๊ธธ์ด์ ๋ฉ์ธ์ง๋ฅผ ์ผ์ ํ ๊ณ ์ ๊ธธ์ด์ ํด์ ๊ฐ์ผ๋ก ๋ณํ์ํจ๋ค. ์ด๋ ํด์ ๊ฐ์ ๊ตฌํ๋ ํจ์๋ฅผ ํด์ ํจ์๋ผ๊ณ ํ๋ค. Java์์ hashCode()
๋ ๊ฐ ๊ฐ์ฒด์ ์ฃผ์๊ฐ์ ๋ณํํ์ฌ ๊ฐ์ฒด๋ง๋ค ๊ณ ์ ํ ๊ฐ์ ์ป๋๋ค.
๊ฐ์ ๊ฐ์ฒด์ ํด์ ์ฝ๋๋ ์ธ์ ๋ ๋์ผํ๋ค.
๊ทธ๋ฌ๋ ์ญ์ ์ฑ๋ฆฝํ์ง ์๋๋ค. ํด์ ํจ์์ ๋ฐ๋ผ ๋ค๋ฅธ ์ ๋ ฅ๊ฐ์ด์ด๋ ๊ฐ์ ์ถ๋ ฅ๊ฐ์ด ๋์ฌ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค. ํด์ ์ฝ๋๊ฐ ๊ฐ๋ค๊ณ ๋ฐ๋์ ๊ฐ์ ๊ฐ์ฒด๋ ์๋๋ค.
equals()
HashMap.java
public final boolean equals(Object o) {
if (o == this)
return true;
return o instanceof Map.Entry<?, ?> e
&& Objects.equals(key, e.getKey())
&& Objects.equals(value, e.getValue());
}
์ด ๋ฉ์๋๋ ๋ ๊ฐ์ฒด๊ฐ ๊ฐ์์ง ์๋์ง๋ฅผ ํ์ธํ์ฌ boolean์ผ๋ก ๋ฐํํ๋ค.
์ฝ๋๋ฅผ ๋ณด๋ฉด HashMap์ equals()
๋ฉ์๋์์๋ ๋ ๊ฐ์ง ๋ฐฉ์์ผ๋ก ๊ฐ์ฒด๋ฅผ ๋น๊ตํ๋ค.
- == ์ฐ์ฐ์: ๋ ๊ฐ์ฒด์ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๊ฐ์ ๋น๊ตํ๋ค. ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๊ฐ์ด ๊ฐ์ผ๋ฉด ๋ ๊ฐ์ฒด๋ ๋น์ฐํ ๊ฐ์ ์กด์ฌ์ด๋ค.
equals()
์ &&: ์ค๋ธ์ ํธ๊ฐ Map.Entry์ด๊ณ , ๋ ๊ฐ์ฒด์ key๊ฐ ๊ฐ๊ณ , ๋ ๊ฐ์ฒด์ value๊ฐ ๊ฐ์์ง ํ์ธํ๋ค. ์ฆ ๋ ๊ฐ์ฒด์ ๋ด์ฉ์ด ๊ฐ์์ง ๋ณธ๋ค.
equals()
๋ ๋ ๊ฐ์ฒด์ ๋
ผ๋ฆฌ์ ๋๋ฑ์ฑ์ ํ์ธํ๋ค.
๋ ๊ฐ์ฒด์ ๋ด์ฉ์ด ๊ฐ์ผ๋ฉด ์ฃผ์๊ฐ ๋ฌ๋ผ๋ ๊ฐ์ ๊ฐ์ฒด๋ก ๋ณธ๋ค.
์์๋ฅผ ๋ณด์. equals()
๋ ๋ฌธ์์ด์ ๋น๊ตํ ๋ ๋ง์ด ์จ๋ดค์ ๊ฒ์ด๋ค.
Main.java
public static void main(String[] args) {
String str1 = new String("Hello World");
String str2 = new String("Hello World");
String str3 = new String("hello world");
System.out.println(str1==str2); // str1๊ณผ str2์ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๋ ๋ค๋ฆ
System.out.println(str1.equals(str2)); // ๊ทธ๋ฌ๋ ๋ด์ฉ์ ๊ฐ์
System.out.println(str1.equals(str3)); // str1๊ณผ str3๋ ์ฃผ์์ ๋ด์ฉ ๋ชจ๋ ๋ค๋ฆ
}
---------------------
์ถ๋ ฅ ๊ฒฐ๊ณผ
false
true
false
str1๊ณผ str2์ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๋ ๋ค๋ฅด๋ฏ๋ก "==" ์ฐ์ฐ์๋ก ๋น๊ตํ๋ฉด ๋ค๋ฅธ ๊ฐ์ฒด๋ก ๋ณธ๋ค.
๊ทธ๋ฌ๋ equals()
๋ก ๋น๊ตํ๋ฉด true์ด๋ค.
String.java
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 ํด๋์ค์์๋ ๊ฐ์ ๋น๊ตํ ๋ value ์ฆ ์ ์ฅ๋ ๋ฌธ์์ด์ ํ์ธํ๊ธฐ ๋๋ฌธ์ด๋ค.
์ด์ฒ๋ผ HashMap์์๋ ํ ์ํธ๋ฆฌ์์ key์ value์ ๋ด์ฉ์ด ๊ฐ์์ง ๋น๊ตํ๊ณ , HashSet์์๋ value๋ ์์๋ก ๋ชจ๋ ๊ฐ์ผ๋ฏ๋ก key, HashSet์ ์์๋ค์ด ๋ด์ฉ์ด ๊ฐ์์ง ํ์ธํ์ฌ ์ค๋ณต์ ํผํ๋ค.
equals()์ hashCode()์ ๊ด๊ณ
equals()
๋ก ๊ฐ์ฒด๊ฐ ๊ฐ์์ง ๋น๊ตํ ์ ์๊ณ , hashCode()
๋ก ๊ฐ ๊ฐ์ฒด๋ง๋ค ๊ณ ์ ํ ๊ฐ์ ์ค ์ ์๋ค๋ฉด ์ ๋ ๋ฉ์๋ ์ค ํ๋๋ง ์ฐ์ง ์๊ณ , ํจ๊ป ์ธ๊น?
HashSet, HashMap์ด ํด์ ํ
์ด๋ธ ๊ตฌ์กฐ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๊ตฌํ๋ ํด๋์ค์ด๊ธฐ ๋๋ฌธ์ด๋ค.
๊ฒฐ๋ก ์ ๋จผ์ ๋งํ์๋ฉด, hashCode๋ก ๋ค๋ฅธ ๊ฐ์ฒด์ธ์ง ์๋์ง๋ ๋นจ๋ฆฌ ์ ์ ์์ง๋ง, ํด์ ์ถฉ๋์ด ์ผ์ด๋ ๊ฒฝ์ฐ์๋ equals๋ก ์ ๋ง๋ก ๊ฐ์ ๊ฐ์ฒด์ธ์ง ํ์ธํ๋ค.
ํด์ ํ ์ด๋ธ ๊ตฌ์กฐ์์ ๊ฐ ํค(HashMap์ ํค, HashSet์ ์์)๋ ํด์์ฝ๋๋ฅผ ๋ถ์ฌ ๋ฐ๋ ํด์ฑ ํ๋ก์ธ์ค๋ฅผ ๊ฑฐ์ณ ๊ฐ(value)์ ํ ์ด๋ธ์ ์ด๋ ์ธ๋ฑ์ค์ ์ ์ฅ๋ ์ง ๊ฒฐ์ ๋๋ค. ์ฌ๊ธฐ์ ์ค์ ๋ก ๊ฐ์ด ์ ์ฅ๋๋ ์ฅ์๋ฅผ ๋ฒํท์ด๋ผ๊ณ ๋ถ๋ฅธ๋ค.
๋น์ฐํ ํ๋์ ๋ฒํท์ ํ๋์ ๋ฐ์ดํฐ๋ง ์ ์ฅ๋๋ ๊ฒ์ ์๋๋ค.
๋ฒํท์ ๊ฐ์๋ ์ ํํ๊ณ ๋ง์ฝ ๋ค๋ฅธ ๋ ๊ฐ์ฒด์ ํด์ ํจ์ ์ถ๋ ฅ๊ฐ์ด ๋์ผํ๋ค๋ฉด, ํด์ ํ
์ด๋ธ์ ๊ฐ์ ์ธ๋ฑ์ค ์ฆ, ๊ฐ์ ๋ฒํท์ ์ ์ฅ๋๋ค.
์ ๊ทธ๋ฆผ์์๋ '15'์ '8'์ด ๊ฐ์ ํด์ ๊ฐ์ ๊ฐ์ง๊ณ ์์ด(ํด์ ์ถฉ๋) ๊ฐ์ ๋ฒํท์ ์ ์ฅ๋์๋ค. (๊ฐ์ ๋ฒํท ๋ด์์๋ ์๋ก ์ฐ๊ฒฐ๋๋๋ฐ ์ด๊ฒ์ ์ฒด์ด๋์ด๋ผ ํ๋ค.) ๊ฐ์ ๊ฐ์ฒด๋ ๋ฐ๋์ ๊ฐ์ ํด์ ๊ฐ์ ๊ฐ์ง์ง๋ง, ๊ฐ์ ํด์ ๊ฐ์ ๊ฐ์ง๋ค๊ณ ๊ฐ์ ๊ฐ์ฒด๋ผ๊ณ ๋ณผ ์๋ ์๋ค.
๊ฒฝ์ฐ 1
๋ง์ฝ ์ด ํ
์ด๋ธ์์ '11'๊ณผ '15'๊ฐ ๊ฐ์์ง ๋น๊ตํ๊ณ ์ ํ๋ค๋ฉด
๊ฐ์์ ๋ฒํท์ผ๋ก ๊ฐ์ ๋ด์ฉ์ ์ง์ ํ์ธํ๊ธฐ๋ ์ ์ ํด์ ์ฝ๋๊ฐ ๋ค๋ฅด๋ฏ๋ก
๊ฒฐ๊ณผ๋ false์ด๋ค.
๊ฒฝ์ฐ 2
๋ง์ฝ ์ด ํ
์ด๋ธ์์ '15'์ '8'์ ๋น๊ตํ๊ณ ์ ํ๋ฉด
๋ ๊ฐ์ฒด๋ ํด์ ๊ฐ์ด 1๋ก ๊ฐ๋ค. ์ด์ ๋ ๋ด์ฉ์ ๋น๊ตํด๋ด์ผ ํ๋ค.
๋ฒํท 1๋ก ๊ฐ์ '15'์ '8'์ด ๊ฐ์ ๋ด์ฉ์ธ์ง equals๋ฅผ ํ์ธํ๋ค.
๊ฒฐ๊ณผ๋ false์ด๋ค.
์ด์ฒ๋ผ ํด์ ๊ตฌ์กฐ์์ ๋ ๊ฐ์ฒด๋ฅผ ๋น๊ตํ ๋๋
ํ
์ด๋ธ์ ๋ชจ๋ ๊ฐ์ฒด์ ์ผ์ผ์ด ๋น๊ตํ์ง ์๊ณ hashCode()
๋ก ๋ฒํท์ ์ฐพ์ ๋ฐ์ดํฐ๋ฅผ ํ์ํ๊ณ ,
๊ฐ์ ๋ฒํท์ ์ฌ๋ฌ ๊ฐ์ฒด๊ฐ ์๋ ๊ฒฝ์ฐ์๋ equals()
๋ก ์ค์ ๋ก ๋๋ฑํ ๊ฐ์ฒด๊ฐ ์๋์ง ํ์ธํ๋ค.
Java์์ ํด์ ๊ตฌ์กฐ์์์ ํ์ ๊ท์น์ ๋ค์๊ณผ ๊ฐ๋ค.
- equals()๊ฐ true๋ผ๋ฉด hashCode()๋ ๋ฐ๋์ ๊ฐ๊ณ , ๋ ๊ฐ์ฒด๋ ๊ฐ๋ค.
- equals()๊ฐ false๋ผ๋ฉด hashCode()๋ ๊ฐ์ ์๋, ๋ค๋ฅผ ์๋ ์๋ค. ๊ฐ์ฒด๋ ์๋ก ๋ค๋ฅด๋ค.
โ ํจ์จ์ ์ธ ํด์ ํ ์ด๋ธ ๊ตฌ์กฐ
์ ํด์ ๊ตฌ์กฐ๋ฅผ ์ฌ์ฉํ ๊น?
ํด์ ๊ฐ์ ์ฌ์ฉํ์ฌ ๋ฐ์ดํฐ๊ฐ ์ ์ฅ๋ ๋ฒํท์ ๋น ๋ฅด๊ฒ ์ฐพ๊ธฐ ๋๋ฌธ์ด๋ค.
๋ง์ฝ Sam Doe๋ฅผ ๊ฒ์ํ๊ณ ์ถ๋ค๋ฉด ํด์ ์ฝ๋๋ฅผ ๊ณ์ฐํ๊ณ ๊ทธ ๋ฒํท์ ์ ๊ทผํ๋ค.
๋ฒํท 254์๋ ๊ฐ์ฒด๊ฐ Sam Doe ํ๋๋ง ์์ผ๋ฏ๋ก ๋ฐ๋ก ์ฐพ์๋ค.
๋ง์ฝ Sandra Dee๋ฅผ ๊ฒ์ํ๊ณ ์ถ๋ค๋ฉด ๋ฒํท 152์ ์ ๊ทผํ๋ค.
๋ฒํท์์ ๊ฐ์ฒด๋ค์ด ๋งํฌ๋ ๋ฆฌ์คํธ๋ก ์ฐ๊ฒฐ๋์ด ์๋๋ฐ Sandra Dee๋ ๋ฃจํธ ๋
ธ๋๊ฐ ์๋๋ค. Sandra Dee๊ฐ ๋์ฌ ๋๊น์ง ๋ค์ ๋
ธ๋๋ฅผ ์ํํ๋ค.
ํ๊ท ์ ์ผ๋ก, ํด์ ์ฝ๋๊ฐ ๊ฒน์น์ง ์๋๋ค๋ฉด ๊ฐ์ฒด๋ฅผ ๋ฐ๋ก ์ฐพ์ ์ ์์ผ๋ฏ๋ก O(1)์ ์ฐพ์ ์ ์๋ค. ์์คํธ ์ผ์ด์ค์๋ ํ ๋ฒํท์ ๊ฐ์ฒด๊ฐ ์ฌ๋ฟ ์๊ณ , ์ฐพ์ผ๋ ค๋ ๊ฐ์ฒด๊ฐ ๋งํฌ๋ ๋ฆฌ์คํธ์ ๋ง์ง๋ง์ ์๋ ๊ฒฝ์ฐ๋ก O(n)์ด๋ค.
ํด์ ํจ์๋ฅผ ์ ์ ์ํ๋ค๋ฉด ๋๋ถ๋ถ์ ๊ฒฝ์ฐ์ O(1)๋ก ๊ฐ์ฒด๋ฅผ ๋ฐ๋ก ์ฐพ์ ์ ์์ผ๋ฏ๋ก
ํจ์จ์ ์ผ๋ก ์ค๋ณต์ ์ฒดํฌํ ์ ์๋ค.
๐ ํ ์ค ์์ฝ
HashSet์ ๋ด๋ถ์ ์ผ๋ก HashMap์ผ๋ก ๋์ํ๊ณ ,
ํด์ ๊ตฌ์กฐ์์ hashCode()
์ equals()
๋ก ๊ฐ์ฒด๋ฅผ ๋น ๋ฅด๊ฒ ์ฐพ๊ณ ๋น๊ตํ์ฌ
์ค๋ณต์ ํจ์จ์ ์ผ๋ก ์ฒดํฌํ ์ ์๋ค!
๐ ์ฐธ๊ณ ์๋ฃ
์ถ์ฒ โ
Internal working of Set/HashSet in Java
Java HashSet
HashSet In Java: Features, Hierarchy, Constructors, Methods, and More
[JAVA] HashSet์ด๋? & ์ฌ์ฉ๋ฒ ์ ๋ฆฌ
Hashing in Data Structure
์๋ฐ์์ equals()์ ==์ ์ฐจ์ด
์ด๋ฏธ์ง ์ถ์ฒ
Hash Table Data Structure
Hash Buckets
'๐บ ์ธ์ด > โJava' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Java] ์คํธ๋ฆผ Stream ๊ฐ๋ ๊ณผ Stream API ์ด์ ๋ฆฌ (2) | 2025.02.13 |
---|---|
[Java] ๋น ๋ฅธ ์ ๋ ฅ๊ณผ ์ถ๋ ฅ: BufferedReader์ BufferedWriter + Buffer (with ๋ฐฑ์ค15552) (0) | 2025.02.12 |