Java

[Java] Map과 Generic(제네릭)이란? (예시 포함)

고즈너키 2023. 6. 13. 16:46

Intro

Map은 자바의 컬렉션 프레임워크 중 하나로, 키-값(Key-Value) 쌍으로 데이터를 저장하는 자료구조입니다.

가장 많이 쓰이는 형태는 Map<String, Integer> scores = new HashMap<>(); 이며,
Map을 정확하게 이해하기 위해선 Generic(제너릭)이 무엇인지부터 살펴보아야 합니다.

제네릭(Generic)은 위 Map 예시에서 `<>` 부분을 의미하며, 타입의 일반화를 할 수 있게 합니다.

제네릭(Generic)

  • 제네릭(Generic)은 자바에서 클래스나 메서드를 작성할 때 타입의 일반화를 가능하게 해주는 기능입니다. 이를 통해 코드의 재사용성과 타입 안정성을 높일 수 있습니다.
// 제네릭 클래스
/** 
 * T는 타입 매개변수로, 이 클래스를 사용할 때 실제 타입으로 대체될 타입을 의미
 * 예를 들어, Box<String>은 content 필드의 타입이 String이 되는 것을 의미
 */ 
public class Box<T> { 
    private T content;

    public void setContent(T content) {
        this.content = content;
    }

    public T getContent() {
        return content;
    }
}

public class Example {
	// 제네릭 메서드
	/**
	 * 메서드 선언부에서 타입 매개변수 <E>를 사용
	 * 이를 통해 메서드 내에서 제네릭 타입 E를 사용 가능
	 * printArray() 메서드는 배열을 받아서 배열의 요소를 출력하는 기능을 수행
	 * 이 때, 메서드를 호출할 때 실제 타입을 지정하여 사용
	 */
    public static <E> void printArray(E[] array) {
        for (E element : array) {
            System.out.println(element);
        }
    }

    public static void main(String[] args) {
        Box<String> stringBox = new Box<>();
        stringBox.setContent("Hello, World!");
        String content = stringBox.getContent();
        System.out.println(content);

        Integer[] numbers = {1, 2, 3, 4, 5};
        printArray(numbers);

        String[] words = {"apple", "banana", "orange"};
        printArray(words);
    }
}

위의 예시에서는 Box 클래스를 활용하여 제네릭을 사용하고, printArray() 메서드를 통해 배열의 요소를 출력하는 제네릭 메서드를 작성하였습니다. 이를 통해 타입에 관계없이 재사용 가능한 클래스와 메서드를 작성할 수 있습니다.

제네릭은 컴파일 시점에서 타입 체크를 수행하므로, 잘못된 타입 사용으로 인한 오류를 컴파일 단계에서 확인할 수 있습니다. 이를 통해 런타임 에러를 방지하고 코드의 안정성을 높일 수 있습니다.

 

Map

  • Map은 자바 컬렉션 프레임워크의 하나로, 키(Key)와 값(Value)의 쌍으로 이루어진 데이터를 저장하는 자료구조입니다. 이를 통해 특정 키에 해당하는 값을 빠르게 검색하고 접근할 수 있습니다.

    예를 들어, 학생의 이름과 점수를 저장하는 경우, 학생의 이름을 키로 하고 점수를 값으로 하는 Map을 사용할 수 있습니다.
import java.util.HashMap;
import java.util.Map;

public class Example {
    public static void main(String[] args) {
        // Map 생성 (키: 학생 이름, 값: 점수)
        Map<String, Integer> scores = new HashMap<>();

        // 데이터 추가
        scores.put("John", 90);
        scores.put("Emily", 95);
        scores.put("Ryan", 88);

        // 데이터 접근
        int johnScore = scores.get("John");
        System.out.println("John's score: " + johnScore);

        // 데이터 수정
        scores.put("John", 92);

        // 데이터 삭제
        scores.remove("Ryan");

        // 모든 항목 순회
        for (Map.Entry<String, Integer> entry : scores.entrySet()) {
            String name = entry.getKey();
            int score = entry.getValue();
            System.out.println(name + "'s score: " + score);
        }
    }
}

위의 예시에서 Map<String, Integer>은 키를 String 타입으로, 값을 Integer 타입으로 지정한 제네릭 문법입니다. 이를 통해 Map에 저장되는 데이터의 타입을 명시할 수 있습니다.

위의 코드에서는 HashMap을 사용하여 Map을 생성하였습니다. put() 메서드를 사용하여 데이터를 추가하고, get() 메서드를 사용하여 특정 키에 해당하는 값을 가져옵니다. put() 메서드를 통해 이미 존재하는 키에 새로운 값을 저장하면 값이 업데이트되고, remove() 메서드를 사용하여 특정 키에 해당하는 데이터를 삭제할 수 있습니다.

또한, entrySet() 메서드를 사용하여 모든 항목을 순회할 수 있습니다. 각 항목은 Map.Entry 인터페이스를 통해 키와 값을 가져올 수 있습니다.

제네릭을 사용함으로써, 컴파일 시점에서 타입 안정성을 보장받을 수 있고, 타입 캐스팅을 줄여 코드의 가독성과 유지보수성을 높일 수 있습니다.

Map의 특징

Map은 자바의 컬렉션 프레임워크 중 하나로, 키-값(Key-Value) 쌍으로 데이터를 저장하는 자료구조입니다. Map의 주요 특징은 다음과 같습니다.

  1. 고유한 키(Key)와 값(Value): Map은 키-값 쌍으로 데이터를 저장합니다. 키는 중복되지 않으며, 각 키는 해당하는 값과 연결됩니다. 키는 객체로서 유일한 식별자 역할을 하며, 값은 키에 해당하는 데이터를 나타냅니다.

  2. 순서가 없는 데이터 집합: Map은 데이터를 키-값 쌍으로 저장하므로 순서가 있는 데이터 구조가 아닙니다. 즉, 데이터가 저장되는 순서와 검색되는 순서가 동일하지 않습니다.

  3. 빠른 검색 속도: Map은 키를 사용하여 값을 검색하는 데 특화되어 있습니다. 내부적으로 키에 대한 해시 함수를 사용하여 데이터를 저장하므로, 많은 데이터에서도 빠른 검색 속도를 제공합니다.

  4. 중복된 값 허용: Map에서는 키가 고유해야 하지만, 값은 중복될 수 있습니다. 다른 키가 같은 값을 가리키는 것은 허용됩니다.

  5. 다양한 구현 클래스: 자바에서는 Map 인터페이스를 구현한 여러 가지 클래스가 제공됩니다. HashMap, TreeMap, LinkedHashMap 등이 있으며, 각각의 클래스는 내부 구현 방식과 특성에 차이가 있습니다. 선택한 구현 클래스에 따라 성능과 정렬, 순서 등의 특성이 달라집니다.
Map은 다양한 상황에서 유용하게 활용될 수 있습니다. 예를 들어, 데이터베이스에서 특정 키를 사용하여 데이터를 빠르게 찾아야 할 때, 키-값 쌍으로 이루어진 설정 정보를 관리해야 할 때, 빠른 탐색이 필요한 알고리즘을 구현해야 할 때 등에 활용될 수 있습니다.