본문으로 바로가기

Map 인터페이스 - 3

category 자료구조 2024. 11. 7. 16:44

Map은 키(key)와 값(value)을 연관시키는 자료구조입니다. 이는 사전과 유사한 구조로, 각 키는 고유한 값을 가집니다. Java에서 Map은 인터페이스로 정의되어 있으며, 이를 구현한 여러 가지 클래스가 있습니다.

Map 주요 특징

  1. 키-값 저장: Map은 키(key)와 값(value)의 쌍으로 데이터를 저장합니다. 각 키는 고유해야 하며, 하나의 값에만 매핑됩니다.
  2. 중복 키 불가: Map은 각 키가 고유해야 합니다. 따라서 동일한 키를 두 번 이상 추가할 수 없습니다. 키의 유일성은 Map 내에서 보장됩니다.
  3. 순서 보장하지 않음: Map은 키-값 쌍을 저장하는데 순서를 유지하지 않습니다. 따라서 Map에 저장된 순서와 데이터를 순회할 때의 순서는 일치하지 않을 수 있습니다.

Map 주요 기능 및 메서드

  1. 키-값 저장: Map은 키와 값의 쌍을 저장합니다.
    • 메서드: put(key, value)
      • 설명: 지정된 키와 값을 매핑하여 Map에 저장합니다.
      • 반환값: 이전에 키에 매핑되어 있던 값, 없으면 null을 반환합니다.
  2. 데이터 검색: 주어진 키를 사용하여 매핑된 값을 검색합니다.
    • 메서드: get(key)
      • 설명: 지정된 키에 매핑되어 있는 값을 반환합니다.
      • 반환값: 지정된 키에 매핑되어 있는 값, 없으면 null을 반환합니다.
  3. 데이터 추가 및 갱신: 새로운 키-값 쌍을 추가하거나, 기존 키에 매핑된 값을 갱신합니다.
    • 메서드: put(key, value)
      • 설명: 지정된 키와 값을 매핑하여 Map에 저장합니다. 이미 존재하는 키인 경우 해당 키에 새로운 값을 덮어씁니다.
      • 반환값: 이전에 키에 매핑되어 있던 값, 없으면 null을 반환합니다.
  4. 데이터 삭제: 특정 키에 해당하는 값을 삭제합니다.
    • 메서드: remove(key)
      • 설명: 지정된 키에 매핑되어 있는 값을 제거합니다.
      • 반환값: 지정된 키에 매핑되어 있던 값, 없으면 null을 반환합니다.
  5. 크기 확인: Map의 크기(키-값 쌍의 수)를 확인합니다.
    • 메서드: size()
      • 설명: Map에 포함된 키-값 쌍의 수를 반환합니다.
      • 반환값: Map에 포함된 키-값 쌍의 수를 반환합니다.

구현 클래스

Collection
   |
   └── Map
        ├── HashMap
        ├── LinkedHashMap
        └── ...
  • HashMap: 가장 일반적으로 사용되는 Map 구현체로, 해시 테이블을 사용하여 키-값 쌍을 저장합니다. 요소의 삽입과 조회가 빠르며, 순서를 보장하지 않습니다.
  • LinkedHashMap: **HashMap**의 확장으로, 요소들이 추가된 순서를 유지합니다. 이는 내부적으로 링크드 리스트를 사용하여 요소의 순서를 기록합니다.
package structure.ch07;

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

public class HashMapTest {

	public static void main(String[] args) {
		
		// key, value 구조 한 쌍이다. 
		// 업 캐스팅된 상태이다. 
		Map<String, String> books = new HashMap<String, String>();
		
		// 추가 : 데이터 추가 
		books.put("해리포터", "J.K 롤링");
		books.put("반지의제왕", "J.R.R 톨킨");
		books.put("1984","조지오웰");

		// 읽기 : 데이터 읽기 
		String author = books.get("해리포터");
		System.out.println("해리 포트 저자 : " + author);
		
		String author2 = books.get("1984");
		System.out.println("1984 저자 : " + author2);
		
		// 수정 : 데이터 수정 
		books.put("1984", "조조입니다");
		System.out.println(books.get("1984"));
		
		// 삭제 : 데이터 삭제 
		books.remove("1984");
		
		// 유용한 기능 확인 
		// 1. 자료구조 map 에 저장되어 있는 key 값들을 확인하는 방법 
		System.out.println(" map 자료구조의 key값 확인 : " + books.keySet());
		
		// 반복문 활용 
		// map 구조는 순서가 없어서 for -> use index 사용 불가;
		System.out.println("-----------------------------");
		for (String key : books.keySet()) {
				System.out.println("key 값 호출 : " + key);
				System.out.println("key를 통해서 value 에 접근 : " +  books.get(key));
		}
		
		// 두번째 방법 
		// 반복자 활용하는 방법 
		System.out.println("------------------------------------------");
		Iterator<Entry<String, String>> iter = books.entrySet().iterator();
		while(iter.hasNext()) {
			// Entry<String, String>
			Entry<String, String> entry = iter.next();
			System.out.println(" 책 : " + entry.getKey() + ", " + "저자 : " + entry.getValue());
		}
		
		System.out.println("--------------------------------");
		// 자료구에서 제공하는  foreach 구문에 사용 
		// 람다 표현식  : 타입 추론 , 화살표기법을 사용한다.  
		books.forEach( (key,value) -> {
			System.out.println("key : " + key);
			System.out.println("value : " + value);
		});
		
		// 전체 삭제 
		books.clear();
		// 요소의 갯수 확인 
		System.out.println(books.size());

	} // end of main 
}

도전과제: 회원 가입 순서 기록 및 조회 시스템

문제 설명: 사용자들이 웹사이트에 가입한 순서대로 회원 정보를 기록하고, 가입한 순서를 기준으로 회원을 조회하는 시스템을 구현하고자 합니다. 사용자는 이름과 이메일 주소로 구성되며, 시스템은 사용자가 가입한 순서대로 정보를 저장해야 합니다. 사용자를 조회할 때는 가입한 순서대로 출력해야 하며, 특정 사용자의 정보를 업데이트할 수 있어야 합니다.

해결 방법: **LinkedHashMap**을 사용하여 사용자의 가입 순서를 유지하면서 사용자 정보를 저장합니다. **LinkedHashMap**은 요소가 추가된 순서대로 요소를 저장하고 반환하는 특성이 있어 이 문제에 적합합니다.

package structure.ch07;

import java.util.LinkedHashMap;
import java.util.Map;

public class UserRegistrationSystem {
	
	private Map<String, User> users = new LinkedHashMap<>();
	
	// 정적 내부 클래스를
	static class User {
		String name; 
		String email; 
		public User(String name, String email) {
			this.name = name; 
			this.email = email;
		}
		@Override
		public String toString() {
			return "이름 : " + name + ", 이메일 : " + email;
		}
	} // end of inner User class 
	
	// 사용자 등록 기능 
	public void addUser(String name, String email) {
		// key, value(User)  
		users.put(email, new User(name, email));
	}
	
	// 사용자들 출력 기능 
	public void displayUsers() {
		for(User user : users.values()) {
			System.out.println(user);
		}
	}
	
	
	// 코드 테스트 (메인 함수) 
	public static void main(String[] args) {
		
		UserRegistrationSystem system = new UserRegistrationSystem();
		// 스캐너 
		User user1 = new User("홍길동1", "a@naver.com");
		User user2 = new User("홍길동2", "b@naver.com");
		User user3 = new User("홍길동3", "c@naver.com");
		
		system.addUser(user1.name, user1.email);
		system.addUser(user2.name, user2.email);
		system.addUser(user3.name, user3.email);
		
		// Map 구조는 기본적으로 순서를 보장하지 않지만 LinkedHashMap 을 사용해서 해결 
		// 가입한 순서대로 출력하는지 확인 
		system.displayUsers();		
	}
}
이름 : 홍길동1, 이메일 : a@naver.com
이름 : 홍길동2, 이메일 : b@naver.com
이름 : 홍길동3, 이메일 : c@naver.com

'자료구조' 카테고리의 다른 글

Set 인터페이스 - 2  (0) 2024.11.07
List 인터페이스 - 1  (3) 2024.11.07
LinkedList 직접 구현해보기  (0) 2024.10.04
큐(Queue) 구현하기  (0) 2024.10.04
컬렉션 프레임워크(collection framework)란?  (1) 2024.10.02