Collection - Map

Zino·2022년 12월 29일

Java

목록 보기
25/26

Map

  • 키(key)와 값(value)으로 구성되어 있으며, 키와 값은 모두 객체
    키는 중복 저장을 허용하지 않고(Set방식), 값은 중복 저장 가능(List방식)
    키가 중복되는 경우, 기존에 있는 키에 해당하는 값을 덮어 씌움
    구현 클래스로 HashMap, HashTable, LinkedHashMap, Properties, TreeMap이 있음

//ex)
Key:Value (Key = Value)

“name” : ”홍길동”
“address” : “서울시 중구”

“name” : ”고길동”
“address” : “서울시 강북구”

map은 출석부와 비슷하다, 같은 반에 동명이인(value)은 있어도 같은 번호(key)일 수 없다.


Map 계열 주요 메소드

  • Map에 담겨있는 요소들에 순차적으로 접근하기 위한 방법 2가지 (검색)
    keySet()
    : keySet()으로 Map의 Key를 Set에 담은 후 Set에 있는 Iterator를 통해 접근
    entrySet()
    : entrySet()으로 Map의 키와 값을 Set에 담은 후 Set에 있는 Iterator를 통해 접근

Enumeration, Iterator, ListIterator

  • 컬렉션에 저장된 요소를 접근하는데 사용되는 인터페이스
    • Enumeration : Iterator의 구버전
    • ListIterator : Iterator를 상속받아 양방향 특징

  • 상속구조 때문에 iterator() 메소드는 List와 Set 계열에서만 사용
    🡪 Map의 경우 Set 또는 List화 시켜서 iterator()를 사용해야 함

  • 주요 메소드

HashMap

  • 키 객체는 hashCode()와 equals()를 재정의해 동등 객체가 될 조건을 정해야 함
    때문에 키 타입은 hashCode와 equals()메소드가 재정의되어 있는 String타입을 주로 사용
//ex)
Map<K, V> map = new HashMap<K, V>();

Hashtable

  • 키 객체 만드는 법은 HashMap과 동일하나 Hashtable은 스레드 동기화가 된 상태이기 때문에,
    복수의 스레드가 동시에 Hashtable에 접근해 객체를 추가, 삭제 하더라도 스레드에 안전 (Thread safe)
//ex)
Map<K, V> map = new HashTable<K, V>();


Properties

  • 키와 값을 String타입으로 제한한 Map컬렉션
    주로 Properties는 프로퍼티(*.properties)파일을 읽어 들일 때 주로 사용

프로퍼티(*.properties) 파일

  • 옵션정보, 데이터베이스 연결정보, 국제화(다국어)정보를 기록하여 텍스트 파일로 활용
  • 애플리케이션에서 주로 변경이 잦은 문자열을 저장하여 관리하기 때문에
    유지보수를 편리하게 만들어 줌
  • 키와 값이 ‘=‘기호로 연결되어 있는 텍스트 파일로 ISO 8859-1 문자셋으로 저장되고,
    한글은 유니코드(Unicode)로 변환되어 저장

TreeSet과 TreeMap

  • 검색 기능을 강화시킨 컬렉션으로, 계층 구조를 활용해 이진 트리 자료구조를 구현하여 제공
    트리 : 각 노드 간 연결된 모양이 나무와 같다고 해서 붙여진 이름


TreeSet

  • 이진 트리를 기반으로 한 Set컬렉션으로, 왼쪽과 오른쪽 자식 노드를 참조하기 위한 두 개의 변수로 구성


TreeMap

  • 이진 트리를 기반으로 한 Map 컬렉션으로, 키와 값이 저장된 Map.Entry를 저장하고
    왼쪽과 오른쪽 자식 노드를 참조하기 위한 두 개의 변수로 구성


TreeSet, TreeMap 정렬

오름차순(기본 정렬)

  • TreeSet의 객체와 TreeMap의 key는 저장과 동시에 자동 오름차순 정렬
  • 숫자(Integer, Double) 타입일 경우 값으로 정렬
  • 문자열(String) 타입일 경우 유니코드로 정렬
  • 정렬을 위해 java.lang.Comparable을 구현한 객체 요구
    그러지 않을 경우 ClassCastException 발생
    (Integer, Double, String 모두 Comparable 인터페이스를 통해 오름차순이 구현되어 있음)

내림차순(따로 구현)

  • TreeSet, TreeMap 객체 생성 시 매개변수 생성자를 통해 재정렬 가능
    //ex)
    TreeSet<E> tSet = new TreeSet(Comparator<? super E> comparator);
    TreeMap<K, V> tMap = new TreeMap(Comparator<? super K> comparator);
  • 또 다른 방법으로 숫자(Integer, Double), 문자열(String) 타입을 제외한 Comparable을
    상속 받는 객체인 경우 compareTo() 메소드의 오버라이딩 부분을 내림차순으로 변경

예제

public class MapService {
	
	// Map : key와 Value 한 쌍이 데이터가 되어 이를 모아둔 객체
	
	// - Key를 모아두면 Set의 특징(중복 X)
	// - Value를 모아두면 List의 특징(중복 O)
	
	public void ex1() {
		
		// HashMap<K,V> : Map의 자식 클래스 중 가장 대표되는 Map
		
		Map<Integer, String> map = new HashMap<Integer, String>();
		
		// Map.put(Integer Key, Sting Value) : 추가(put)
		map.put(1, "홍길동");
		map.put(2, "고길동");
		map.put(3, "김길동");
		map.put(4, "이길동");
		map.put(5, "박길동");
		map.put(6, "최길동");
		
		//Key 중복
		map.put(1, "홍홍홍"); // 중복 허용 X, 대신 value를 덮어씀
		
		//Value 중복 
		map.put(7, "최길동"); 
		
		System.out.println(map); // map.toString() 오버라이딩 되어있음.
		
	}
	
	public void ex2() {
		
		// Map 사용 예제
		
		// Vo(값 저장용 객체)는 특정 데이터 묶음의 재사용이 많은 경우 주로 사용
		// -> 재사용이 적은 VO는 오히려 코드 낭비
		// -> Map을 이용해서 VO와 비슷한 코드를 작성할 수 있다!
		
		// 1) VO버전
		
		Member mem = new Member();
		
		// 값 세팅
		mem.setId("userId");
		mem.setPw("userPw");
		mem.setAge(30);
		
		// 값 출력
		
		System.out.println( mem.getId());
		System.out.println( mem.getPw());
		System.out.println( mem.getAge());
		
		System.out.println("======================================");
		
		// 2) Map버전
		
		Map<String, Object> map = new HashMap<String, Object>();
		// value가 Object 타입 == 어떤 객체든 Value에 들어올 수 있다!
		
		// 값 세팅
		map.put("id", "user02");
		map.put("pw", "pass02");
		map.put("age", 25); // int -> Integer(AutoBoxing)
		
		
		// 값 출력
		System.out.println(map.get("id").toString());
		// String java.lang.Object.toString() -> 정적 바인딩
		// 실행 중 확인해보니 String 자식 객체 -> 자식 toSting() 호출
		//							   -> 동적 바인딩
		System.out.println(map.get("pw"));
		System.out.println(map.get("age"));
		
		
		System.out.println("=====================================");
		//*** Map에 저장된 데이터 순차적으로 접근하기 ***
		
		// Map에서 Key만 모아두면 Set의 특징 
		// -> 이를 활용할 수 있도록 Map에서 keySet() 메서드 제공
		// --> Key만 모아서 Set으로 반환
		
		Set<String> set = map.keySet(); // id, pw, age 가 저장된 set을 반환
		
		System.out.println(set);
		
		
		// 향상된 for문 
		
		for(String key : set) {
			System.out.println(map.get(key));
			// key가 반복될 때 마다 변경
			// -> 변경된 key에 맞는 map의 value가 출력
		}
		
		// map에 저장된 데이터가 많을 때,
		// 어떤 key가 있는지 불분명 할 때,
		// map에 저장된 모든 데이터에 접근 해야할 때
		// keySet() + 향상된 for문 코드를 사용한다.
		
		
		
		
	}
	
	public void ex3() {
		
		// List + Map 
		// user 10명 , user의 id 쭉뽑는다
		
		// k : v
		// "id" : "user01"
		// "id" : "user01"
		// "id" : "user01"
		// ...
		
		List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
		
		for( int i = 0; i < 10; i++) {
			// Map 생성
			Map<String, Object> map = new HashMap<String, Object>();
			
			map.put("id", "user0" + i);
			map.put("pass", "user0" + i);
			
			// Map을 Lis에 추가
			list.add(map);
		}
		
		// for문 종료 시점에 List에는 10개의 Map객체가 추가 되어있다.
		// * List에 지정된 Map에서 Key가 "id"인 경우의 value를 출력*
		// 향상된 for문 
		for(Map<String, Object> temp : list) {
			System.out.println(temp.get("id"));
			
		}
		
	}
}
profile
Willingness to be a fool!

0개의 댓글