안녕하세요 골드입니다.
프로그래머스에서 알고리즘 문제를 풀다가 Map 형태에 자료구조를 사용하게 되었습니다.
그래서 오늘은 Java의 HashMap을 사용해서 배열의 값을 분류하는 방법에 대해서 글을 작성하겠습니다.
1. HashMap이란?
먼저, HashMap이란 Map 인터페이스를 구현한 하나의 클래스입니다. Map 인터페이스의 가장 큰 특징은 key값과 value값을 가진다는 것과 순서가 정해져있지 않다는 점입니다. key값은 value값을 찾기 위한 데이터인데 중복을 허용하지 않습니다. 하지만 value값은 중복을 허용합니다.
HashMap의 사용방법은 이렇습니다. HashMap에 데이터를 저장할 때, key값을 같이 저장합니다. 데이터를 사용하기 위해서는 저장된 key값으로 데이터를 검색해서 가져옵니다. key와 value는 각각 Object타입으로 저장합니다. key값에서 특히 자주 사용되는 타입으로는 String형이 있습니다.
간단히 예를 하나 들어보겠습니다. 핸드폰 번호를 key로 설정하고, 번호 주인의 이름을 value라고 하겠습니다. 번호는 고유한 값으로 중복된 값을 가질 수 없습니다. 두 사람이 하나의 번호를 공유한다면 전화를 걸었을 때, 어떤 사람한테 전화를 거는지 알 수 없기 때문입니다. 반대로 번호 주인의 이름은 동명이인이 있을 수 있습니다. 010-1111-2222의 주인이 김김김인데, 마찬가지로 010-2222-1111의 주인이 김김김일 수 있다는 말입니다.
키(Key) HashMap 내에서 유일한 값.
값(Value) 키와 달리 중복을 허용하는 값.
2. HashMap의 다양한 메서드
먼저 한 가지 말씀드리자면 HashMap 객체에 값을 추가하기 위한 put 메서드가 있습니다.
put 메서드의 첫 번째 매개변수가 key이고, 두 번째 매개변수가 value입니다. 로그인에 사용하는 아이디와 비밀번호 역시 이런 형태라고 할 수 있습니다. 아이디인 key는 고유한 값으로 중복된 값을 가질 수 없지만, 비밀번호인 value는 중복된 값이 허용됩니다.
먼저 Map은 key와 value라는 조금은 다른 형태로 저장되는 이 친구들 덕분에 Map.Entry라는 Map의 내부 인터페이스가 있습니다. 이 Map.Entry 인터페이스는 key와 value를 다루기 위해 만들어졌습니다. Map.Entry 인터페이스의 메서드들 먼저 간단히 살펴보겠습니다.
1. Map.Entry 인터페이스의 메서드
Object getKey() | Entry의 key값 반환. |
Object getValue() | Entry의 value값 반환. |
지금 당장 Map 인터페이스도 모르는데 Map.Entry 인터페이스는 또 뭐지라고 생각할 수도 있습니다. 일단 이런 메서드가 있다는 것을 알아두시고 밑에 사용법을 보신다면 이해가 빠를 것입니다.
2. HashMap에서 사용하는 메서드
boolean containsKey(Object key) | HashMap에 지정된 key가 있는지 알려줍니다. |
boolean containsValue(Object value) | HashMap에 지정된 value가 있는지 알려줍니다. |
Set entrySet() | HashMap에 저장되어 있는 키와 값을 Entry의 형태로 Set에 저장합니다. |
Object get(Object key) | 해당 key의 value를 가져옵니다. |
Object put(Object key, Object value) | HashMap에 지정된 key와 value를 저장합니다. |
Object remove(Object key) | Key로 저장되어 있던 값을 제거합니다. |
int size() | HashMap에 저장되어 있는 요소 수를 반환. |
다른 메서드는 설명을 보면 이해가 빠르게 될 것이라고 생각합니다. 한 가지 entrySet이라는 메서드를 예제와 함께 간단하게 살펴보겠습니다. Entry형태는 key와 value가 결합된 형태입니다. Set은 HashMap과 마찬가지로 컬렉션 프레임워크에 해당하는 인터페이스인데 이것보다 데이터를 저장하는 하나의 방식으로 이해하시면 됩니다. Set의 특징은 순서가 없다는 것입니다.
위에서 put메서드 설명을 위해 만들었던 코드에 entrySet을 추가하여 print해봤습니다. key와 value가 결합된 형식이 put을 한 순서와 상관없이 출력되는 것을 볼 수 있습니다.
get 메서드도 한번 사용해보겠습니다.
지정된 key가 가지고있는 value를 반환하는 것을 볼 수 있습니다.
한 가지가 더 있습니다. 바로 HashMap과 같은 컬렉션에 저장된 값에 접근하기 위해 사용하는 인터페이스인 Iterator 인터페이스입니다. Iterator를 이용해서 컬렉션의 요소를 읽어옵니다.
Object next() | 다음 요소를 가져옵니다. |
boolean hasNext() | 다음 요소가 있는지 확인합니다. |
3. 배열의 같은 값 분류하기
드디어 배열을 분류해보도록 하겠습니다. 예를 들어서 배열에 같은 값이 있다고 가정하겠습니다. 그리고 해당 배열에 같은 값이 모두 몇 개인지를 카운트한 값을 따로 저장하는 것입니다.
먼저 예제 코드를 본 다음에 설명하겠습니다.
바로 이 코드입니다.
String 1차원 배열 안에 중복된 값들이 몇 개 들어있습니다. 어떤 값이 얼마나 중복되었는지를 확인하기 위해 HashMap 객체를 하나 생성한 후 String arr의 요소를 key값으로 가지고 있는지 확인합니다. 만약 없다면 처음 본 요소이기 때문에 값을 1로 설정하고 이미 key값으로 가지고 있다면 이전 index에서 이미 key값으로 설정했다는 뜻입니다. key값은 중복을 허용하지 않기 때문에 해당 key값의 value를 +1 합니다.
Iterator의 내부에는 코드가 많이 없습니다. 그래서 더 어려운 것 같습니다. 아무튼 Iterator 인터페이스를 사용해서 map의 Entry값을 가지고 옵니다. 얼핏 보기에는 Enumeration으로 반환한다고 합니다.
entrySet에 다음 값이 있는지 확인한 후 있다면 entry에 다음 값을 저장 후 print하는 코드입니다. 뒷부분은 print를 보여주기 위해 작성했습니다.
깔끔하게 나오는 것을 볼 수 있습니다.
2차원 배열도 마찬가지 입니다. 알고리즘 테스트같은 곳에서 분명 특정 index에 정돈된 상태로 카테고리가 주어질 것입니다. 1차원과 마찬가지로 해당 요소값이 key로 저장되어 있는지 확인한 후 값을 1로 설정하거나 증가시키면 될 것입니다.
제가 필요했던 코드는 2차원 배열과 사용하는 이 코드였습니다.
Java에서 key와 value를 사용하는 자료형이 있다는 것은 알고 있었습니다. 그런데 그 내용에 대해서 제대로 알고있던 것이 아니라서 이번에 한번 더 공부를 해서 글을 작성하게 되었습니다.
여기까지 골드였습니다.
감사합니다.
참고자료 : Java api,
남궁성 Java의 정석 3판 도우출판 p614, p645
'Programming Language > Java' 카테고리의 다른 글
[Java] PriorityQueue(우선순위 큐) 사용법과 예제 (0) | 2020.11.13 |
---|---|
[Java] Char형 배열과 String 클래스 (0) | 2020.07.03 |
[Java] ArrayList와 배열(Array)의 중복 제거 (0) | 2020.07.01 |
[Java] String Class와 StringBuffer Class (0) | 2020.06.21 |
[Java] int(or long) to String(String to int) 자료형 변환과 String Split (0) | 2020.06.05 |