JAVA Map

김개발세발바닥·2024년 4월 8일

JAVA

목록 보기
7/12

Map.

Map은 java.util 패키지의 Map이라는 이름의 인터페이스로 선언되어 있고.

특징.

  • 모든 데이터는 키와 값이 존재한다.
  • 키가 없이 값만 저장될 수는 없다.
  • 값 없이 키만 저장할 수 없다.
  • 키는 해당 Map에서 고유해야만 한다.
  • 값은 Map에서 중복되어도 전혀 상관 없다.

Map을 구현한 주요 클래스들.

Map 인터페이스를 구현한 클래스들은 매우 다양하고 많다. (HashMap, TreeMap, LinkedHashMap) 등.. 그리고 HashTable이라는 클래스도 있다.
HashTable 클래스는 Map 인터페이스를 구현하기는 했지만 일반적인 Map 인터페이스를 구현한 클래스들과는 다르다.

HashMap 클래스와 HashTable 클래스.

HashMap은 키나 값에 null 저장이 가능하지만 HashTable은 불가능하다.
HashMap은 thread safe하지 않지만 HashTable은 thread safe 하다.
따라서 Map으로 끝나는 클래스들을 여러 쓰레드에서 동시에 접근하여 처리할 필요가 있을 때에는

Map m = Collections.synchronizedMap(new HashMap())

이렇게 사용해야 한다. 또는 ConcurrentHashMap을 사용하여 쓰레드에 안전하게 사용할 수 있다.

HashMap 클래스.

대부분 HashMap 객체를 생성할 때에는 매개 변수가 없는 생성자를 사용한다.
하지만 HashMap에 담을 데이터의 개수가 많은 경우에는 초기 크기를 지정해 주는 것을 권장한다.
추가로 HashMap에 저장하는 키가 되는 객체를 직접 만들었을 때에는 유의해야 하는 것이 있다.
HashMap의 키는 기본 자료형과 참보 자료형 모두 될 수 있다. 그래서 보통 int나 long과 같은 숫자나 String 클래스를 키로 많이 사용한다.
하지만 직접 어떤 클래스를 만들어 그 클래스를 키로 사용할 때에는 Object 클래스의 hashCode() 메소드와 equals() 메소드를 잘 구현해 놓아야만 한다.
HashMap에 객체가 들어가면 hashCode() 메소드의 결과 값에 따른 버켓이라는 목록형태의 바구니가 만들어진다.
만약 서로 다른 키가 저장되었는데, hashCode() 메소드의 결과가 동일하다면, 이 버켓에 여러 개의 값이 들어갈 수 있다. 따라서 get() 메소드가 호출되면 hashCode()의 결과를 확인하고, 버켓에 들어간 목록에 데이터가 여러 개일 경우 equals() 메소드를 호출하여 동일한 값을 찾게 된다.
따라서 키가 되는 객체를 직접 작성할 때에는 꼭 hashCode()와 equals() 메소드를 구현해 놓아야 한다.

HashMap의 내부 구조.


HashMap은 기본적으로 bucket 배열을 16으로 설정한다.

bucket이란 HashTable에 데이터를 담는 공간.

이 용량은 설정해 놓은 LOAD_FACTOR 기준에 다다르면 자동으로 2배씩 증가한다. (Set과 동일!)
용량을 적게 설정한 이유는 hashCode는 정수 범위의 값을 리턴하는데, 이 범위 전체의 배열을 만드려면 OutOfMemoryError가 발생할 수 있기 때문이다.

Collision.

Collision이 일어나면 Separate chaining방식을 이용한다.
이는 버킷에 노드들이 위 사진과 같이 LinkedList로 연결되어있는 형태다.

최근 이미지 해싱할 때 Collision이 충돌한게 생각이 난다...

0개의 댓글