평범한 연구소

[JAVA] Map<E,K> - HashMap, LinkedHashMap, Hashtable, TreeMap, Properties 본문

JAVA/기본 개념

[JAVA] Map<E,K> - HashMap, LinkedHashMap, Hashtable, TreeMap, Properties

soyeonisgood 2022. 8. 6. 23:17

java.util.Map<K, V> 인터페이스

  • 키(key)를 값(value)에 매핑하는 객체
  • 각 키에 하나의 값만 매핑됨
  • Map 구현한 HashMap, TreeMap, LinkedHashMap의 3개의 범용 Map의 동작과 성능은, Set의 HashSet, TreeSet, LinkedHashSet 과 유사
  • 주요 구현 클래스: Hashtable<K,V>, HashMap<K,V>, LinkedHashMap<K,V>, TreeMap<K,V>, LinkedHashMap<K,V>, Properties

 

java.util.Entry<K, V> 인터페이스

  • 맵의 엔트리(key-value pair)
  • Map은 내부적으로 Map.Entry<K,V> 인터페이스 구현한 Entry<K,V> 클래스의 객체를 배열로 저장하는 구조
  • 키와 값은 서로 관련된 값이므로 각각의 배열로 선언X, Entry라는 내부 클래스를 정의하고 Entry타입의 배열 선언하여 저장
  • 주요 메소드: getKey(), getValue(), setValue()

 

java.util.HashMap<K, V> 클래스

  • 키(key)를 값(value)에 매핑하여 저장
  • 키는 중복 허용X, 값은 다른 키로 중복적인 요소 저장 가능
  • 키나 값에 null 저장 가능. 키는 하나의 null만 추가
  • 요소의 저장 순서 유지 X
  • 멀티스레드 환경에서 동기화 X

 

java.util.LinkedHashMap<K, V> 클래스

  • HashMap<> 클래스 상속 받은 클래스
  • 해시테이블과 링크드 리스트 구현한 맵
  • 키(key)를 값(value)에 매핑하여 저장
  • 삽입 순서대로 저장
  • 멀티스레드 환경에서 동기화 X

 

java.util.Hashtable<K, V> 클래스

  • 키를 값에 매핑하여 저장
  • 키는 중복 허용X, 값은 중복 요소 저장 가능
  • 키나 값에 null 사용하면 런타임 오류
  • 요소의 저장 순서 유지 X
  • 멀티스레드 환경에서 동기화

 

java.util.TreeMap<K, V> 클래스

  • SortedMap 인터페이스 구현한 클래스
  • 키 기준으로 정렬되어 저장
  • 멀티스레드 환경에서 동기화 X
  • TreeMap의 키는 Comparable인터페이스의 compareTo() 또는 Comparator인터페이스의 compare() 메소드를 사용해 모든 요소 비교. 그렇지 않으면 ClassCastException 런타임 오류

 

java.util.Properties 클래스

  • Hashtable 클래스의 하위클래스
  • 키와 값 모두 String으로 제한한 Map
  • 파일 입출력 지원
    • 프로퍼티 파일 ( .properties)
    • 한글은 UTF-8로 저장
    • 키1=값1, 키2=값2
    • 설정 정보, DB 연결 정보, 다국어 정보 등
  • Hashtable를 상속 받은 Properties 객체는 put()이나 putAll() 메소드 사용할 수 있지만 권장 X. 이러한 메소드 사용하면 키 또는 값이 String이 아닌 엔트리를 삽입할 수 있으며 String 이외의 키 또는 값을 Properties 객체로 store() 또는 save()메소드 호출하면, 그 호출은 실패
  • setProperty(): put() 호출
  • getProperty(): 지정된 키 갖는 프로퍼티를 프로퍼티 리스트로부터 찾음
  • store(): 프로퍼티 리스트(key,value pair)를 load()로 프로퍼티 테이블에 로드하는데 적절한 포맷으로 출력스트림 기입
  • load(): 입력 스트림으로부터 프로퍼티 리스트에 읽어들임 
  • storeToXML(): 프로퍼티 리스트를 XML 문서로 출력 스트림에 기입
  • loadFromXML(): 지정된 입력 스트림 상의 XML 문서에 의해 나타내지는 모든 프로퍼티를 프로퍼티 테이블에 로드

 

HashMap 예제

package ch12.unit5;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class Ex01 {

	public static void main(String[] args) {
		// <키, 값>
		Map<String, Integer> map = new HashMap<>();
		
		// map에 값 저장(키, 값)
		map.put("서울", 1000);
		map.put("부산", 350);
		map.put("대구", 250);
		map.put("인천", 300);
		map.put("광주", 150);
		map.put("대전", 150);
		map.put("울산", 110);
		map.put("세종", 20);
		map.put("서울", 950); // 키가 같으면 기존 값을 덮는다.
		System.out.println(map);
		
		// map에서 키의 값 가져오기
		int n = map.get("서울");
		System.out.println("서울: "+n);
		
		// Map에는 Iterator이 없으며, 향상된 for문도 사용 불가능
		// Map의 키에서 Set 객체를얻고 이 키에 대한 Set 객체로 처음부터 끝까지 순회할 수 있다
		Set<String> set = map.keySet(); // 키에 대한 Set 객체
		Iterator<String> it = set.iterator(); // 키에 대한 반복자
		
		while(it.hasNext()) {
			String key = it.next(); // 키
			Integer a = map.get(key); // 키에 대한 값
			System.out.println(key + " => "+a);
		}
		System.out.println();
		
		System.out.println("키에 서울 존재? "+map.containsKey("서울"));
		System.out.println("키에 경기 존재? "+map.containsKey("경기"));
		System.out.println("값에 350 존재? "+map.containsValue(350));
		
		System.out.println("전체 개수: "+map.size());
		
		map.remove("세종"); // 키가 세종인 데이터 삭제
		System.out.println(map);
		
		
		
	}

}
package ch12.unit5;

import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class Ex02 {

	public static void main(String[] args) {
		Map<String, Integer> map = new HashMap<>();
		map.put("자바", 95);
		map.put("오라클", 100);
		map.put("빅데이터", 90);
		map.put("서블릿", 90);
		map.put("스프링", 95);

		System.out.println(map);
		
		Set<String> set = map.keySet(); // 키에 대한 Set 객체
		System.out.println(set);
		
		// map의 값을 List로
		List<Integer> list = new LinkedList<>(map.values());
		System.out.println(list);
		
		System.out.println("\n전체 가져오는 방법 1.");
		Iterator<String> it = map.keySet().iterator();
		while(it.hasNext()) {
			String key = it.next();
			Integer n = map.get(key);
			System.out.println(key + " : "+n);
		}
		
		System.out.println("\n전체 가져오는 방법 2.");
		for(String s : map.keySet()) {
			Integer n = map.get(s);
			System.out.println(s + " : "+n);
		}
		
		// 값을 Collection
		System.out.println("\n전체 가져오는 방법 3.");
		Collection<Integer> col = map.values();
		Iterator<Integer> it2 = col.iterator();
		while(it.hasNext()) {
			int n = it2.next();
			System.out.print(n + " ");
		}
		System.out.println();
		
		System.out.println("최고값: "+Collections.max(col));
		System.out.println("최저값: "+Collections.min(col));
		
	}

}

 

 

Entry 예제

	public static void main(String[] args) {
		Map<String, Integer> map = new HashMap<>();
		map.put("자바", 95);
		map.put("오라클", 100);
		map.put("빅데이터", 90);
		map.put("서블릿", 90);
		map.put("스프링", 95);
		map.put("HTML", 100);
		
		// entry: 키와 값을 set 형태로 저장. key와 value를 묶어주기위해 사용
		// Map.Entry: 맵의 엔트리
		Set<Map.Entry<String, Integer>> set1 = map.entrySet();
		Iterator<Map.Entry<String, Integer>> it1 = set1.iterator();
		while(it1.hasNext()) {
			Map.Entry<String, Integer> e = it1.next();
			String s = e.getKey();
			Integer n = e.getValue();
			System.out.println(s + " ->" + n);
		}
	}

 

HashMap 요소 처음~마지막 요소까지 반복

  • 방법 1
    • Map에는 Iterator이 없으며, 향상된 for문도 사용 불가능
    • Map의 키에서 Set 객체를얻고 이 키에 대한 Set 객체로 처음부터 끝까지 순회할 수 있다
    • HashMap<>
Set<String> set = map.keySet(); // 키에 대한 Set 객체
System.out.println("\n전체 가져오는 방법 1.");
Iterator<String> it = map.keySet().iterator();
while(it.hasNext()) {
	String key = it.next(); // 키
	Integer n = map.get(key); // 키에 대한 값
	System.out.println(key + " : "+n);
}
  • 방법 2
Set<String> set = map.keySet(); // 키에 대한 Set 객체
System.out.println("\n전체 가져오는 방법 2.");
for(String s : map.keySet()) {
	Integer n = map.get(s);
	System.out.println(s + " : "+n);
}
  • 방법 3
Set<String> set = map.keySet(); // 키에 대한 Set 객체

// 값을 Collection
System.out.println("\n전체 가져오는 방법 3.");
Collection<Integer> col = map.values();
Iterator<Integer> it2 = col.iterator();
while(it.hasNext()) {
	int n = it2.next();
	System.out.print(n + " ");
}

 

Properties() 예제

	public static void main(String[] args) {
		// 키와 값이 모두 문자열만 가능
		Properties p = new Properties(); // Hashtable 을 상속 받음
		
		// Properties에 값 저장
		// p.setProperty("java", 95);
		p.setProperty("java", Integer.toString(95));
		p.setProperty("html", Integer.toString(80));
		p.setProperty("oracle", Integer.toString(90));
		p.setProperty("css", Integer.toString(75));
		p.setProperty("javascript", Integer.toString(90));
		
		// Properties 값 가져오기
		String s = p.getProperty("css");
		System.out.println(s);
		
		System.out.println(p);
		
		// 처음부터 끝까지 모두 출력
		System.out.println("\n전체 리스트");
		
		Iterator<Object> it = p.keySet().iterator();
		while(it.hasNext()) {
			String a = (String)it.next();
			String b = p.getProperty(a);
			System.out.println(a + " : " + b);
		}
	}
	public static void main(String[] args) {
		Properties p = new Properties();
		p.setProperty("kim java", "25");
		p.setProperty("홍길동", "29");
		p.setProperty("너자바", "30");
		p.setProperty("심심해", "19");
		
		p.list(System.out); // 표준 출력 장치로 출력

		// Properties 내용을 파일로 저장하기
		// FileOutputStream: 파일 출력 바이트 스트림. 파일 내용 저장.
		String pathname = "friend.properties";
		try (FileOutputStream fos = new FileOutputStream(pathname)) {
			p.store(fos, "친구..."); // Properties 객체의 내용을 파일로 저장
									// 문자나 숫자 이외는 UTF-8로 저장
			System.out.println("파일 저장 완료...");
		} catch (IOException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}

	}
}