본문 바로가기

[Java] 으흐흐..... HashMap 쓸거야 ! HashSet 쓸거야?

@Salieri2026. 2. 4. 11:18

 

 

HashSet 은 python 의 set 이고 HashMap 은 python 의 dictionary 겟죠? ? 

 


 

 

두둥

 

 

 

#. 제1막: 백병원 (Java Heap Space)

(침대에 누워있는 심영, 눈을 뜬다)

심영: 여기가... 어디요?

의사(JVM): 아, 안심하세요. 여기는 백병원... 아니, 자바 힙 스페이스(Java Heap Space)입니다.

심영: 자바 힙...? 아, 내가 데이터를... 데이터를 너무 많이 먹어서 가비지 컬렉터(GC)한테 쫓기다가 쓰러졌는데...

의사(JVM): 데이터를 너무 많이 넣어서 메모리 누수가 왔습니다. 하마터면 OutOfMemoryError로 갈 뻔했습니다.

 

(이때, 병실 문이 거칠게 열리며 김두한과 부하들이 들어온다)

 

심영: 누, 누구시오?

김두한: 나다.

심영: 김두한 대장? 여긴 웬일이시오? 난 코딩 같은 건 안 했소! 그냥 데이터만 좀 모았을 뿐이란 말이오!

#. 제2막: 심문 (Key의 존재 유무)

김두한: (의자를 끌어당겨 앉으며) 심영이. 자네가 데이터를 모았다고 했나? 그럼 묻겠다.

 

자네는 **HashMap**인가, **HashSet**인가?

 

 

심영: 그, 그게 무슨 소리요? 난 그냥... 데이터를 담는 컬렉션(Collection)일 뿐이오!

김두한: 거짓말 하지 마! 자네가 담은 데이터에... **'이름표(Key)'**가 있나 없나를 묻고 있다!

심영: 이름표...? 그, 그런 건 없소! 난 그냥 add("데이터")만 했을 뿐이오!

김두한: (책상을 쾅 치며) 거짓말!! 이름표(Key)가 없다면 나중에 그 데이터를 어떻게 찾을 셈이지?

일일이 Iterator로 뒤질 셈인가! 그건 O(N)이야! **O(1)**의 속도를 내려면 Key가 있어야 한단 말이다!

심영: 아, 아니오! 난 정말 이름표 같은 건 모르오! 난 그저... 중복된 데이터가 싫었을 뿐이오! 똑같은 게 들어오면 다 쳐냈단 말이오! 김두한: 중복을 싫어한다...? 흐음. 그렇다면 자네는 **HashSet**이로군.

심영: 그, 그렇소! 난 HashSet이오! 그게 뭐 잘못됐소?

#. 제3막: 비극적인 진실 (내부 구현의 비밀)

김두한: 상하이, 처리해.

상하이 조: (심영에게 다가가며) 심영 동지, 잠깐 소스 코드 좀 봅시다.

심영: 뭐, 뭐요? 이보시오, 내 private 필드를 왜 건드리는 거요! 이거 Encapsulation 위반 아니오!

 

(상하이 조, 심영의 내부 구현(Source Code)을 뜯어본다)

 

상하이 조: 대장님, 여기 이 자의 내부를 보십시오.

// HashSet.java 내부 (충격적인 진실)
private transient HashMap<E,Object> map;
private static final Object PRESENT = new Object();

public boolean add(E e) {
    return map.put(e, PRESENT) == null;
}

김두한: (코드를 보며 비웃듯) 역시 그랬군. 심영이, 자네는 겉으로는 **HashSet**이라고 떠들고 다녔지만... 속은 HashMap으로 되어 있어!

 

심영: 으으... 아니, 그게 무슨 소리야! 내가... 내가 맵(Map)이라니!

 

김두한: 자네는 HashMap의 Key 자리만 차지하고, Value 자리에는 PRESENT라는 가짜 객체나 채워 넣는... 반쪽짜리 HashMap이었던 거야.

 

심영: 말도 안 돼... 말도 안 돼!!

 

 

#. 제4막: 내가 고자라니 (Key가 없다니)

김두한: 그리고 가장 중요한 건... 자네에겐 get() 메서드가 없다.

심영: 뭐요?

김두한: HashMap은 get(Key)를 써서 원하는 걸 바로 꺼낼 수 있지. 하지만 자네는... 콕 집어서 꺼낼 수 있는 기능이 없어.

 

심영: (다급하게 자신의 메서드를 확인하며) add... remove... contains... size...

(침묵) 심영: get이... 없어?

 

 

의사(JVM): 안타깝게도... HashSet 님은 데이터를 꺼낼(get) 수 있는 Key가 없습니다. 그냥 contains로 있는지 확인만 하거나, for-each 문으로 다 꺼내보는 수밖에 없어요. 다시 말해, Key 고자라 이 말입니다.

 

심영: 뭐, 뭐요? 이보시오, 의사 양반! 그게 무슨 소리요! 의사(JVM): 인덱스도 없고, 키도 없습니다. 그냥 주머니예요.

심영: 내가... 내가 Key가 없다니!! 내가!! Key가 없다니!!! (절규한다)

심영: 안 돼, 안 돼! 내가 Key가 없다니! 말도 안 돼... 김두한 이놈, 이건 말도 안 돼! 말도 안 된다고! 으허허헣허!!

#. 제5막: 결론 (정리)

김두한: (절규하는 심영을 뒤로하고) 다들 잘 들어라.

  1. HashMap: Key와 Value가 다 살아있는 멀쩡한 놈이다. 데이터를 put하고, get으로 0.1초 만에 찾아낸다. (속도 O(1))
  2. HashSet: 저 심영이 놈처럼 Key도 없고(접근 불가), 순서도 없는 놈이다. 오직 **"중복 제거"**와 **"존재 확인(contains)"**만 가능하다.

상하이 조: 대장님, 그럼 저놈은 어떡합니까?

김두한: 놔둬. 로또 번호 추첨할 때(중복 제거)나 쓰라고 해. 갑시다.

(김두한과 부하들 퇴장)

 

심영: (울부짖으며) get()을 줘... get()을 달란 말이야...!!

 

 

Salieri
@Salieri :: 살리에리의 인생살이 채널

평소에 내가 좋아하는것과 싫어하는 것들 그리고 왜 안되나 싶은 것들을 업로드 하는 블로그입니다 인생살이도 업로드 하고있어요. 제가 걸어온 길이 당신에게 있어서 도움이 되는 이정표였으면 좋겠네요. 질문은 항상 넓은 마음으로 받고있답니다. 대답하기 곤란한 질문이 아닌 이상 제에게 이메일을 써주세요 트위터 : https://twitter.com/@Salieri1845799 깃허브 : https://github.com/salieri009

공감하셨다면 ❤️ 구독도 환영합니다! 🤗

목차