도서/자바의 신

[도서/자바의 신] #24 자바랭 다음으로 많이 쓰는 애들은 컬렉션 - Part 3(Map)

yulee_to 2022. 12. 30. 20:40

자바의 신

✔️이 글은 [자바의 신 - 이상민 지음] 도서를 바탕으로 정리한 글입니다. 


Map이란?

Map은 key-value 쌍으로 이루어져 있어 중복되지 않는 key 값으로 데이터를 구분한다. 

key값은 다른데 value는 같아도 다른 것으로 간주한다. 

value 없이 key값만 저장할 수도 있지만, key 값 없이 value만 저장할 수는 없다. 

value 값은 중복되어도 상관없다.

 

Map의 주요 메소드

  • put(K key, V value ) : key-value 값을 갖는 데이터를 저장
  • putAll(Map<? extends K, ? extends V> m) : 매개변수로 넘어온 Map의 모든 데이터를 저장
  • get(Object key) : 매개변수로 넘어온 key에 해당하는 value를 넘겨줌
  • remove(Object key) : 매개 변수로 넘어온 key에 해당하는 value를 넘겨주며, 해당 key-value는 Map에서 삭제
  • keySet() : key 목록을 Set 타입으로 리턴
  • values() : value의 목록을 Collection 타입으로 리턴
  • entrySet() : Map 안에 Entry라는 타입의 Set을 리턴
  • size() : Map의 크기를 리턴
  • clear() : Map의 내용을 지움

Map을 구현한 주요 클래스들을 살펴보자

Map 인터페이스를 구현한 클래스에는 HashMap, TreeMap, LinkedHashMap, Hashtable 등이 있다.

 

Hashtable 클래스는 Map 인터페이스를 구현하긴 했지만, 일반적인 Map 인터페이스를 구현한 클래스와는 다르다.

  • Map은 컬렉션 뷰(Collection View)를 사용하지만, Hashtable은 Enumeration 객체를 통해 데이터를 처리
  • Map은 키, 값, 키-값 쌍으로 데이터를 순환하여 처리할 수 있지만, Hashtable은 이 중에서 키-값 쌍으로 데이터를 순환하여 처리할 수 없다. 
  • Map은 이터레이션을 처리하는 도중에 데이터를 삭제하는 안전한 방법을 제공하지만, Hashtable은 그런 기능이 없다.

 

HashMap과 Hashtable 클래스의 차이점

기능 HashMap Hashtable
키나 값에 null 저장 가능 여부 O X
여러 쓰레드 안전 여부  X O

 

Hashtable을 제외한 Map 인터페이스를 구현한 Map으로 끝나는 클래스들을 여러 쓰레드에서 동시에 접근하여 처리할 필요가 있을 때에는 다음과 같이 선언해 사용해야 한다.

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

 

JDK 1.0부터 제공되는 Hashtable, Vector는 쓰레드에 안전하지만, 그 외 대부분의 Collection 관련 클래스들은 위와 같이 처리해야 하거나 이름에 Concurrent가 포함되어 있어야만 쓰레드에 안전하게 사용할 수 있다. 

HashMap 클래스에 대해서 자세히 알아보자

HashMap 클래스의 상속 관계

java.lang.Object
    ㄴ java.util.AbstractMap<K,V>
        ㄴ java.util.HashMap<K,V>

 

HashMap이 구현한 인터페이스에는 Serializable, Cloneable, Map<E>가 있다.

 

HashMap 생성자

  • HashMap() : 16개의 저장공간을 갖는 객체 생성
  • HashMap(int initialCapacity) : 매개변수 만큼의 저장 공간을 갖는 객체 생성
  • HashMap(int initialCapacity, float loadFactor) : 첫번째 매개변수 만큼의 저장 공간을 갖고, 두번째 매개변수의 로드팩터를 갖는 객체 생성
  • HashMap(Map<? extends K, ? extends V> m) : 매개변수로 넘어온 Map을 구현한 객체에 있는 데이터를 갖는 HashMap 객체 생성

HashMap에 담을 데이터가 많을 경우 초기 크기를 지정해주는 것이 좋다.

 

HashMap의 key값으로는 기본 자료형, 참조 자료형 둘다 가능한데 보통은 int나 long같은 숫자나 String 클래스를 키로 많이 사용한다. 

클래스를 직접 만들어 그 클래스를 key값으로 사용할 때에는 그 클래스에 Object 클래스의 equals()와 hashCode()메소드를 Overriding해줘야 한다. 

 

HashMap에 객체가 들어가면 hashCode() 메소드의 결과 값에 따른 버켓(bucket)이라는 목록 형태의 바구니가 만들어진다. 

서로 다른 키가 저장된 객체인데 hashCode() 결과가 동일하다면 같은 버켓 안에 여러개의 데이터가 들어간다. 

get() 메소드가 호출되면, 키 값의 hashCode() 메소드 결과를 확인하고 그 결과값에 따른 버켓 안의 데이터를 equals() 메소드를 통해 동일한 값을 찾아낸다.

HashMap 객체에 값을 넣고 확인해보자

Map에서는 데이터를 "추가"한다고 안하고 데이터를 "넣는다"라고 표현한다. 그래서 데이터를 넣는 메소드의 이름이 put()이다.

put() 메소드로 이미 존재하는 key로 값을 넣을 때는 기존의 값을 새로운 값으로 대치해주는 수정의 역할도 한다. 

 

get() 메소드를 통해 매개변수로 넘겨준 key에 해당하는 데이터를 찾을 때 해당 Map에 존재하지 않는 key라면 null을 리턴해준다.

HashMap 객체의 값을 확인하는 다른 방법들을 알아보자

keySet()이라는 메소드로 어떤 key들이 저장되었는지 확인할 수 있다.

keySet()은 리턴 타입이 Set이라 키 값의 제네릭 타입과 동일하게 Set 제네릭 타입을 지정해 값을 받아오면 된다. 

 

키에 매핑된 value값을 가져올 때에는 values()라는 메소드를 사용한다.

values()의 리턴 타입은 Collection 타입으로 Collection의 제네릭 타입을 value이 제네릭 타입과 동일하게 지정해주면 된다.

 

entrySet()은 Set<Map.Entry<K,V>> 타입으로 리턴된다는 점을 주의해야 한다. 

key-value 쌍을 다루기 위해 Map 인터페이스 안에는 내부 인터페이스로 Entry가 선언되어 있는데 getKey(), getValue(),setValue(), equals(), hashCode() 등의 메소드를 가진다. Map인터페이스를 구현하는 클래스에서 Map.Entry 인터페이스도 같이 구현해줘야 한다.

정렬된 키의 목록을 원한다면 TreeMap을 사용하자

HashMap 객체의 키를 정렬하는 방법에는 두가지 방법이 있다.

  • Arrays 클래스 사용, 불필요한 객체가 생긴다는 단점이 있다.
  • TreeMap 클래스 사용, Arrays의 단점을 보완하지만 느림

TreeMap 클래스는 저장하면서, 키를 정렬하는데 기본적인 문자열이 저장될 때는 숫자>알파벳대문자>알파벳소문자>한글 순서로 정렬해준다. 객체나 숫자가 저장될때는 정렬 순서가 달라진다.

 

TreeMap의 상속 관계

java.lang.Object
    ㄴ java.util.AbstractMap<K,V>
        ㄴ java.util.TreeMap<K,V>

 

TreeMap이 구현한 인터페이스에는 Serializable, Cloneable, Map<K,V>, NavigableMap<K,V>, SortedMap<K,V>가 있다. 

SortedMap 인터페이스로 구현한 클래스는 키가 모두 정렬되어 있어야만 한다는 특징이 있기 때문에 TreeMap이 키가 정렬되는 특징을 갖게 된 것이다.

 

TreeMap의 메소드

  • firstKey() : 가장 앞 key값 리턴
  • lastKey() : 가장 뒤 key값 리턴
  • higherKey(K key) : 특정 키 뒤에 있는 key값 리턴
  • lowerKey(K key) : 특정 키 앞에 있는 key값 리턴

Map을 구현한 Properties 클래스는 알아두면 편하다

Hashtable을 확장한 Properties 클래스는 시스템 속성을 다룰 때 사용하는 클래스로 객체에 시스템 속성을 저장하거나, 애플리케이션에서 사용할 여러 속성값들을 넣고, 빼고, 저장하고, 읽어들일 수 있다. 

Map 인터페이스에서 제공하는 모든 메소드 사용이 가능하다.

 

시스템 주요 속성

  • user.language : 사용자의 사용 언어
  • user.dir : 현재 사용중인 기본 디렉터리
  • user.home : 사용자 계정의 홈 디렉터리
  • java.io.tmpdir : 자바에서 사용하는 임시 디렉터리
  • file.encoding : 파일의 기본 인코딩
  • sun.io.unicode.encoding : 유니코드 인코딩
  • path.separator : 경로 구분자
  • file.separator : 파일 구분자
  • line.separator : 줄(line) 구분자

Properties가 추가적으로 제공하는 메소드

  • load(InputStream inStream), load(Reader reader) : 파일에서 속성을 읽음
  • loadFromXML(InputStream in) : XML로 되어 있는 속성을 읽음
  • store(OutputStream out, String comments), store(Writer writer, String comments) : 파일에 속성 저장, comments는 주석
  • storeToXML(OutputStrema os, String comment), storeToXML(OutputStream os, String comment, String encoding) : XML로 구성되는 속성 파일 생성, comment는 <comments> 태그 내에 저장되는 주석
XML은 eXtensible Markup Language에서 따온 약어로 태그로 구성되어 있는 텍스트 문서로 서로 데이터를 주고 받을 때 표준을 정하기 쉽다. 어떤 데이터를 정해져있는 XML 형태로 요청하면, 그 형식에 맞는 XML로 데이터를 받을 수 있는 기능을 제공한다.

 

System 클래스절에 Properties 부분 참고 

 

[도서/자바의 신] #20 가장 많이 쓰는 패키지는 자바랭

✔️이 글은 [자바의 신 - 이상민 지음] 도서를 바탕으로 정리한 글입니다. java.lang 패키지는 특별하죠 java.lang은 import를 안해도 그 안의 클래스들을 사용할 수 있는 유일한 패키지로 자바에 꼭 필

yulee.tistory.com

 

.properties로 끝나는 확장자 파일들에는 키는 등호 왼쪽에, 값은 등호 오른쪽에 써져있고, #이 붙은 문장은 주석처리된다. 

 

자바의 자료 구조를 정리해보자

  • Collection
    • List : 목록을 처리, 데이터 중복 O, 순서 O
      • ArrayList, LinkedList
    • Set : 목록을 처리, 데이터 중복 X, 순서 X
      • HashSet, TreeSet, LinkedHashSet
    • Queue : FIFO, 데이터 중복 O, 순서 O
      • LinkedList, PriorityQueue
  • Map : key-value 쌍 데이터 저장, key값 중복 X, value값 중복 O, 순서 X
    • HashMap, TreeMap, LinkedHashMap

Collection의 데이터를 처리하기 위해서 for 루프나 iterator() 메소드를 통해 Iterator 객체를 얻어 각 데이터를 처리할 수 있다. 

 


직접해 봅시다

1. Map 형태의 자료 구조는 무엇과 무엇으로 구성되어 있나요?

key-value

2. Map에서 데이터를 저장하는 메소드는?

put()

3. Map에서 특정 키에 할당된 값을 가져오는 메소드는?

get()

4. Map에서 특정 키와 관련된 키와 데이터를 지우는 메소드는?

remove()

5. Map에서 키의 목록을 가져오는 메소드는?

keySet()

6. Map에 저장되어 있는 데이터의 크기를 가져오는 메소드는?

size()

7. HashMap과 HashTable 중에서 키나 값에 null을 저장할 수 있는 것은?

HashMap

8. HashMap과 Hashtable 중에서 여러 쓰레드에서 동시에 접근해도 문제가 없는 것은?

Hashtable

9. HashMap에서 특정 키가 존재하는지 확인하는 메소드는?

containsKey()

10. 이 장에서 살펴본 클래스 중, 키가 저장되면서 정렬되는 Map에는 어떤 것이 있나요?

TreeMap

11. Properties 클래스는 어떤 클래스를 확장한 것인가요?

Hashtable

12. Properties 클래스의 객체에 있는 데이터를 파일로 저장할 때에는 어떤 메소드들을 사용하면 되나요?

store()

728x90