2020-12-25
우선 Map이란 컬렉션은 key와 value를(key와 value는 모두 객체이다.) 구성된 entry 객체를 저장하는 자료구조이다. 예를 들자면 [ Map <String, Integer> map =... ]와 같은 코드가 작성되어 있다면 Map이라는 컬렉션에 키는 String이며, 값으로 Integer 타입의 객체가 들어가고 변수의 이름은 map이라고 해석할 수 있다.
그중에서 HashMap은 Map 컬렉션을 구현하는 대표적 인터페이스이다. 다만 HashMap은 hashcode와 equals 메서드를 재정의 하여 동등 객체의 처리 조건을 재정의 해야 한다. 그러면 사용법을 알아보자.
package mMap;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class main {
public static void main(String[] args) {
Map<String, Integer> map = new HashMap<>();
map.put("a", 111);
map.put("b", 222);
map.put("c", 333);
map.put("d", 444);
map.put("f", 555);
}
}
선언 방법은 위와 같이 간단하다. Map 컬렉션에 키는 String / 값은 Integer로 주었으며, new 연산자를 통해 HashMap객체를 만들어주면 된다. 이후 해당 객체에 데이터를 입력 시 put 메서드를 통해 키와 값을 입력해주면 된다.
다만 여기서 궁금증이 생길 수 있다. 위에서 HashMap은 hashcode와 equals 메서드를 재정의 해야 한다고 했는데, 위의 코드에서는 해당 부분을 확인할 수 없다. 그 이유는 이미 String은 해당 두 메서드가 재정의 되어 있기 때문이다. 그래서 HashMap을 사용할 때에는 키 값을 String으로 사용하는 경우가 많이 있다.
이제 넣어둔 데이터를 출력하는 코드를 알아보자.
package mMap;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class main {
public static void main(String[] args) {
Map<String, Integer> map = new HashMap<>();
map.put("a", 111);
map.put("b", 222);
map.put("c", 333);
map.put("d", 444);
map.put("f", 555);
Set<String> keySet = map.keySet();
//전체 키를 Set으로 받아서 넣는다.
Iterator<String> it = keySet.iterator();
//반복해서 키를 꺼내기 위해 Iterator에 해당 키를 다시 담는다.
while(it.hasNext()) {
String key = it.next();
//해당 키값을 변수에 담음
Integer value = map.get(key);
//키 값은 get에 넣어 해당 값을 찾음
System.out.println(key + " = " + value);
//두가지 모두 출력
}
Set<Map.Entry<String, Integer>> entrySet = map.entrySet();
//set에 map.entry 객체를 모두 담음
Iterator<Map.Entry<String, Integer>> entryIt= entrySet.iterator();
//마찬가지로 반복해서 키를 꺼내기 위해 Iterator에 해당 키를 다시 담는다.
while(entryIt.hasNext()) {
System.out.println(entryIt.next());
//반복자에 이미 키와 값이 모두 들어가 있어 next 메서드로 꺼내면된다.
}
}
}
전체 데이터를 출력하는 방법은 위와 같이 기본 Set 컬렉션에 키의 타입을 넣어준 후 반복자로 꺼내 주는 방법과 처음부터 map.entry 객체를 Set에 담아 출력하는 방법이 있다. 둘 중 아무거나 사용해도 상관없다. 출력 값은 아래와 같다.
그러면 이제 클래스를 키값으로 받는 HashMap 은 어떻게 사용하는지 알아보자. 예제로 사용할 클래스 Human은 아래와 같은 코드를 정의되어 있다.
package mMap;
public class Human {
private String name;
private String age;
public Human(String name, String age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
@Override
public boolean equals(Object obj) {
if(obj instanceof Human) {
Human human = (Human) obj;
return human.name.equals(name) && human.age.equals(age);
}else {
return false;
}
}
@Override
public int hashCode() {
return name.hashCode() + age.hashCode();
}
}
해당 코드를 보면 앞서 말했듯이 hashcode와 equals 메서드가 재정의 된 것을 알 수 있다. equals의 경우 클래스 생성자로 들어온 값이 클래스의 인스턴스인지 확인한 후 맞다면 해당 클래스 타입으로 강제 변환한다. 이후 각 필드 값 역시 equals로 체크 후 true 값을 리턴한다.
hashcode는 클래스의 필드 값 두 개를 hashcode로 리턴하도록 재정의 하였다.
이제 메인 클래스의 실행 코드를 살펴보자.
package mMap;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class main {
public static void main(String[] args) {
Map<Human, Integer> map = new HashMap<>();
map.put(new Human("aaa", "25"), 1);
map.put(new Human("bbb", "25"), 2);
map.put(new Human("ccc", "30"), 3);
map.put(new Human("ddd", "30"), 4);
map.put(new Human("fff", "40"), 5);
Set<Human> key1 = map.keySet();
//전체 키를 Set으로 받아서 넣는다.
Iterator<Human> it1 = key1.iterator();
//반복해서 키를 꺼내기 위해 Iterator에 해당 키를 다시 담는다.
while(it1.hasNext()) {
Human h = it1.next();
int v = map.get(h);
System.out.println(h.getAge() + " " + h.getName() + " " + v);
//이후 get메서드를 통해 필드값들을 출력한다.
}
System.out.println("______________________________________________________________________________");
Set<Map.Entry<Human, Integer>> key = map.entrySet();
//맵에 구성요소 전체로 셋의 매개값으로 받아 변수에 저장
Iterator<Map.Entry<Human, Integer>> it = key.iterator();
//반복해서 하나씩 꺼내기 위해서 Iterator 변수에 다시 담아줌
while(it.hasNext()) {
//값이 있나 우선적 확인
Map.Entry<Human, Integer> entry = it.next();
//맵 엔트리 변수에 순서대로 하나씩 담아 초기화
Human h = entry.getKey();
//키 클래스의 변수에 키값 저장
System.out.println(h.getAge() + " " +h.getName() + " " + entry.getValue());
}
}
}
실행코드는 기존에 String을 사용한 코드와 크게 다르지 않아 설명은 생략하도록 하겠다. 주석으로 자세한 설명을 적어 두었으니, 이클립스 또는 인텔리제이에 해당 코드르 복사 후 컴파일해보면 금방 이해가 될 것이다.