본문 바로가기
JAVA

[JAVA] 컬렉션 - Map 계열

by Amy IT 2022. 6. 4.

Map 계열은 key와 value의 쌍으로 데이터를 저장하는 자료구조로서, key를 이용하여 원하는 값을 얻을 수 있습니다. key는 반드시 유일한 값이어야 하고 value는 중복이 가능합니다. 저장 순서는 유지되지 않습니다. Map 인터페이스의 하위 클래스는 대표적으로 HashMap과 Hashtable 클래스가 있으며, Hashtable의 하위 클래스로 Properties 클래스가 있습니다. HashMap은 null값을 허용하고, Hashtable은 null값을 허용하지 않습니다. 

 

 

▶ Map 인터페이스의 주요 메소드

 

메소드 설명
put(Object key, Object value)
putAll(Map m)
key와 그에 해당되는 value 객체를 저장
V get(key) key에 해당되는 value 반환
V remove(key) key에 해당되는 value 삭제
void clear() Map의 모든 객체 삭제
boolean isEmpty() Map이 비어있는지 확인
int size() Map에 저장된 객체의 개수
Set<K> keySet() Map에 저장된 모든 key를 Set에 저장해서 반환
Set<Entry<K,V>> entrySet() Map에 저장된 모든 key와 value를 Entry(key와 value의 결합) 타입으로 Set에 저장해서 반환
Collection<V> values() Map에 저장된 모든 value를 Collection으로 반환
boolean containsKey(key) Map에 지정된 key가 있는지 boolean 반환
boolean containsValue(value) Map에 지정된 value가 있는지 boolean 반환

 

 

 

▶ HashMap

 

(1) HashMap 생성 및 데이터 추가

key와 value가 모두 String 타입인 HashMap을 생성하고 데이터를 추가해 보겠습니다.

HashMap<String, String> map = new HashMap<>();
map.put("one", "홍길동");
map.put("two", "이순신");
map.put("three", "유관순");
map.put("one", null); //덮어쓰기 
map.put(null, null); //key값도 null 가능 
map.put(null, "세종"); //덮어쓰기
System.out.println(map); //{null=세종, one=null, two=이순신, three=유관순}

 

(2) HashMap 메소드 활용

System.out.println(map.get("one")); //null
System.out.println(map.get("four")); //null
System.out.println(map.get(null)); //세종
System.out.println("크기: "+map.size()); //4
System.out.println("키 포함여부: "+map.containsKey("one")); //true
System.out.println("값 포함여부: "+map.containsValue("유관순")); //true
map.replace("one", "강감찬");
System.out.println(map); //{null=세종, one=강감찬, two=이순신, three=유관순}
map.remove(null);
System.out.println(map); //{one=강감찬, two=이순신, three=유관순}
Collection<String> col =map.values();
System.out.println(col); //[강감찬, 이순신, 유관순]

 

(3) 데이터 순회

① keySet()

keySet() 메소드는 Map에 저장된 모든 key값을 Set에 저장해서 반환합니다. 얻어온 key값들로 for-each문이나 Iterator 인터페이스를 사용해서 데이터를 순회하며 각 key에 해당하는 value값을 얻을 수 있게 됩니다. 

Set<String> keys = map.keySet(); //key값만 얻기
System.out.println(keys); //[one, two, three]
//for-each문 
for (String key : keys) { //keys에서 key 하나씩 꺼내오기
	System.out.println(key+" = "+map.get(key)); //각 key에 해당하는 value값 얻기
}
//Iterator
Iterator<String> iter = keys.iterator(); //keys에 들은 데이터를 Iterator 객체에 담아서 리턴
while (iter.hasNext()) {
	String key = iter.next(); //Iterator객체에서 key 하나씩 꺼내오기
	System.out.println(key+" = "+map.get(key)); //각 key에 해당하는 value값 얻기
}

 

② entrySet()

entrySet() 메소드는 Map에 저장된 모든 key와 value를 Entry(key와 value의 결합) 타입으로 Set에 저장해서 반환합니다. Entry 인터페이스의 메소드인 getKey()와 getValue()를 통해 키와 값을 각각 얻어올 수 있습니다. 마찬가지로 for-each문 또는 Iterator를 사용해 데이터를 순회할 수 있습니다.

Set<Entry<String, String>> entrySet = map.entrySet(); //key와 value 쌍으로 Set에 저장
System.out.println(entrySet); //[one=강감찬, two=이순신, three=유관순]
//for-each문
for (Entry<String, String> entry : entrySet) { //한 쌍씩 꺼내오기 
	System.out.println(entry.getKey()+" = "+entry.getValue()); //각 Entry의 key와 value 얻어오기
}
//Iterator
Iterator<Entry<String, String>> it = entrySet.iterator(); //entrySet에 들은 데이터를 Iterator 객체에 담아서 리턴
while (it.hasNext()) {
	Entry<String, String> entry = it.next(); //Iterator객체에서 한 쌍씩 꺼내오기
	System.out.println(entry.getKey()+" = "+entry.getValue()); //각 Entry의 key와 value 얻어오기
}

 

 

 

▶ HashMap & ArrayList

 

(1) HashMap의 value 타입이 ArrayList인 경우

HashMap 안에 ArrayList를 넣을 수 있습니다. value값이 각각 해당하는 ArrayList를 참조하고 있는 경우입니다. 데이터 순회시 키를 하나씩 꺼내서 각 키에 해당하는 value값인 List를 다시 순회해야 하기 때문에 for문이 중첩되어야 합니다. 

ArrayList<Person> list1 = new ArrayList<>();
list1.add(new Person("홍길동", 20, "서울"));
list1.add(new Person("홍길동2", 30, "서울2"));
list1.add(new Person("홍길동3", 40, "서울3"));

ArrayList<Person> list2 = new ArrayList<>();
list2.add(new Person("이순신", 20, "전라"));
list2.add(new Person("이순신2", 30, "전라2"));
list2.add(new Person("이순신3", 40, "전라3"));

HashMap<String, ArrayList<Person>> map = new HashMap<>();
map.put("one", list1);
map.put("two", list2);

//데이터 순회
Set<String> keys = map.keySet();
for (String key : keys) { 
	ArrayList<Person> list = map.get(key); //각 key에 해당하는 List꺼내기 
	for (Person p : list) { //각 List에 들어있는 Person꺼내기 
		System.out.println(p.getName()+"\t"+p.getAge());
	}
}

 

(2) ArrayList의 타입이 HashMap인 경우

반대로 ArrayList 안에 HashMap을 넣을 수도 있습니다. ArrayList의 타입이 HashMap인 경우입니다. 마찬가지로 데이터 순회시 List에 들어있는 Map을 하나씩 꺼내서 Map을 다시 순회해야 하기 때문에 for문이 중첩됩니다. 

HashMap<String, Person> map1 = new HashMap<>();
map1.put("one", new Person("홍길동", 50, "서울"));
map1.put("two", new Person("홍길동2", 60, "전라"));
map1.put("three", new Person("홍길동3", 70, "서울"));

HashMap<String, Person> map2 = new HashMap<>();
map2.put("one", new Person("이순신", 50, "서울2"));
map2.put("two", new Person("이순신2", 60, "전라2"));
map2.put("three", new Person("이순신3", 70, "서울2"));

ArrayList<HashMap<String, Person>> list = new ArrayList<>();
list.add(map1);
list.add(map2);

//데이터 순회 
for (HashMap<String, Person> map : list) { //List에서 map 하나씩 꺼내기
	Set<String> keys = map.keySet(); //map에서 key값만 전체 꺼내기
	for (String key : keys) { 
		Person p =  map.get(key); //각 key에 해당하는 Person 꺼내기
		System.out.println(p.getName()+"\t"+p.getAge());
	}
}

 

 

 

▶ Properties 

 

Properties 클래스는 Hashtable의 하위 클래스로서, key와 value가 모두 String 타입일 때 사용하는 특화된 클래스입니다. Hashtable의 하위 클래스이므로 null값 저장이 불가합니다. 

 

Properties 클래스의 주요 메소드는 다음과 같습니다.

 

메소드 설명
setProperty(String key, String value) key와 그에 해당되는 value를 저장
String getProperty(String key) key에 해당되는 value 반환
Enumeration propertyNames() 저장된 모든 key를 Enumeration에 담아 반환
Set<String> stringPropertyNames() 저장된 모든 key를 Set에 담아 반환

 

(1) Properties 생성 및 데이터 추가

Properties는 String 타입을 저장하기 위한 클래스이므로 제네릭 선언이 필요하지 않습니다. 

Properties prop = new Properties();
prop.setProperty("one", "홍길동");
prop.setProperty("two", "홍길동2");
prop.setProperty("three", "홍길동3");
//prop.setProperty("four", null); //Hashtable 속성: null 저장 불가 
prop.setProperty("four", "100");
System.out.println(prop); //{four=100, one=홍길동, two=홍길동2, three=홍길동3}
System.out.println(prop.getProperty("one")); //홍길동
System.out.println(prop.get("four")); //100

 

(2) 데이터 순회

propertyNames() 또는 stringPropertyNames() 메소드로 저장된 key값만 꺼내올 수 있습니다. propertyNames()의 경우 리턴타입이 Enumeration인데, Iterator와 같은 기능을 하는 반복처리 인터페이스입니다. 

//propertyNames()
Enumeration<?> keyEnu = prop.propertyNames(); //key만 꺼내서 Enumeration객체로 반환
while (keyEnu.hasMoreElements()) { //다음 key 존재여부 검사 
	String key = (String) keyEnu.nextElement(); //key 하나씩 꺼내기, 리턴타입 Object이므로 형변환 필요 
	System.out.println(key+" = "+prop.getProperty(key)); //key에 해당하는 value 꺼내기 
}
//stringPropertyNames()
Set<String> keySet = prop.stringPropertyNames(); //key만 꺼내서 Set에 담음
for (String key : keySet) { //key 하나씩 꺼내기
	System.out.println(key+" = "+prop.getProperty(key)); //key에 해당하는 value 꺼내기
}

 

(3) Properties를 이용한 환경변수 가져오기

Properties를 이용해서 시스템 환경변수 값을 출력할 수 있습니다. 자바 프로그램이 돌아가고 있는 환경을 key와 value로 얻어올 수 있습니다. 

Properties props = System.getProperties(); //환경변수 전체 얻기
//propertyNames()
Enumeration<?> keyEnu = props.propertyNames();
while (keyEnu.hasMoreElements()) {
	String key = (String) keyEnu.nextElement();
	System.out.println(key+" = "+props.getProperty(key));
}
//stringPropertyNames()
Set<String> keySet = props.stringPropertyNames();
for (String key : keySet) {
	System.out.println(key+" = "+props.getProperty(key));
}

 

 

이상으로 Map 계열 클래스의 기본적인 사용법에 대해 알아보았습니다. 

 

 

댓글