Java의 Map 인터페이스는 데이터를 키-값 쌍으로 관리하기에 적합하지만, 데이터 변환과 필터링을 위해 추가적인 작업이 필요할 때가 많습니다. 특히 Stream API와 Lambda 표현식을 활용하면 Map의 데이터 필터링이 훨씬 간결해집니다. 이 글에서는 Stream과 Lambda를 이용한 Map 데이터 필터링, Map을 List로 변환하는 방법과 그 반대의 경우, 그리고 특정 조건에 맞는 데이터 추출 및 가공 방법을 상세히 설명합니다.
Stream과 Lambda를 이용한 Map의 데이터 필터링
Java 8 이상에서는 Stream API와 Lambda를 통해 Map 데이터를 효율적으로 필터링할 수 있습니다. 이는 특정 조건에 맞는 데이터만 추출하거나, 키 또는 값에 대한 조건을 적용할 때 유용합니다.
예제: 값이 특정 기준을 만족하는 항목 필터링
다음 예제에서는 Map에서 값이 50 이상인 항목만 필터링해 출력합니다.
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class MapFilterExample {
public static void main(String[] args) {
Map<String, Integer> scores = new HashMap<>();
scores.put("Alice", 65);
scores.put("Bob", 45);
scores.put("Charlie", 75);
Map<String, Integer> filteredScores = scores.entrySet().stream()
.filter(entry -> entry.getValue() >= 50)
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
System.out.println(filteredScores); // {Alice=65, Charlie=75}
}
}
이 예제에서 entrySet().stream()을 사용해 Map을 스트림으로 변환하고, filter() 메서드를 이용해 값이 50 이상인 조건에 맞는 데이터만 필터링했습니다. 이처럼 Lambda를 사용하면 필터링 조건을 간결하게 표현할 수 있습니다.
예제: 특정 키로 시작하는 항목 필터링
키가 특정 문자로 시작하는 항목만 필터링하는 경우, startsWith() 메서드를 활용할 수 있습니다.
Map<String, Integer> filteredByKey = scores.entrySet().stream()
.filter(entry -> entry.getKey().startsWith("A"))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
System.out.println(filteredByKey); // {Alice=65}
이와 같이, Lambda 표현식과 startsWith() 조건을 함께 사용하여 Map의 특정 키로 시작하는 항목만 간단히 추출할 수 있습니다.
Map을 List로 변환하거나, 그 반대로 변환하기
Map과 List 변환은 데이터를 다양한 컬렉션 구조로 가공하여 처리할 때 필요합니다. Map의 데이터는 주로 키-값 쌍이지만, 특정 상황에서는 키나 값만 추출하거나, 새로운 형식의 데이터를 사용해야 할 때가 있습니다.
Map의 키 또는 값만 추출하여 List로 변환
Map의 키만 추출해 List로 변환하거나, 값만 추출해 List로 변환하는 것은 매우 간단합니다.
import java.util.List;
List<String> keys = new ArrayList<>(scores.keySet());
List<Integer> values = new ArrayList<>(scores.values());
System.out.println(keys); // [Alice, Bob, Charlie]
System.out.println(values); // [65, 45, 75]
위 예제에서 keySet()과 values() 메서드를 활용하여 Map의 키와 값을 별도의 List로 변환했습니다. 이는 데이터가 키 또는 값 중심으로 필요할 때 유용하게 사용할 수 있습니다.
Map의 엔트리를 List로 변환하기
Map의 각 항목을 Map.Entry로 변환하여 List로 구성할 수도 있습니다.
List<Map.Entry<String, Integer>> entryList = new ArrayList<>(scores.entrySet());
System.out.println(entryList); // [Alice=65, Bob=45, Charlie=75]
이 방법을 사용하면 Map을 항목 단위로 변환하여 List에서 Map 엔트리를 직접 조작할 수 있습니다. entrySet()은 Map의 모든 항목을 Map.Entry 형태로 반환하므로 List로 변환이 용이합니다.
List를 Map으로 변환하기
List를 Map으로 변환하려면 Collectors.toMap()을 사용할 수 있습니다.
import java.util.Arrays;
import java.util.List;
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
Map<String, Integer> nameLengthMap = names.stream()
.collect(Collectors.toMap(name -> name, String::length));
System.out.println(nameLengthMap); // {Alice=5, Bob=3, Charlie=7}
이 예제에서는 names라는 List의 각 항목을 키로, 이름의 길이를 값으로 변환한 Map을 생성했습니다. 이를 통해 데이터를 원하는 형태로 가공하고 변환할 수 있습니다.
특정 조건에 맞는 데이터 추출 및 가공
특정 조건에 맞는 데이터 추출은 데이터 필터링을 넘어 조건에 맞는 데이터를 가공하여 새로이 생성하는 경우입니다.
예제: 값에 특정 가공 적용하기
아래는 모든 점수를 10점씩 증가시킨 새로운 Map을 생성하는 예제입니다.
Map<String, Integer> increasedScores = scores.entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getKey, entry -> entry.getValue() + 10));
System.out.println(increasedScores); // {Alice=75, Bob=55, Charlie=85}
이 예제는 기존 Map의 값에 가공을 더해 새로운 값을 가진 Map을 생성합니다. 데이터 가공과 변환은 이처럼 Collectors.toMap()을 통해 쉽게 구현할 수 있습니다.
예제: Map에서 특정 데이터 추출하여 합계 구하기
특정 조건을 만족하는 값의 합계를 구하는 예제입니다.
int totalHighScores = scores.values().stream()
.filter(score -> score >= 50)
.mapToInt(Integer::intValue)
.sum();
System.out.println(totalHighScores); // 140
여기서는 조건에 맞는 값들만 필터링하여 합계를 구했습니다. 이와 같이 Stream API는 간결한 방식으로 조건에 맞는 데이터의 합산, 평균, 최대값, 최소값을 구하는 기능을 제공합니다.
참고사이트
'JAVA' 카테고리의 다른 글
[JAVA] Jackson ObjectMapper란? (1) | 2024.11.09 |
---|---|
[JAVA] Jackson 환경 설정 (1) | 2024.11.08 |
[JAVA] Jackson 이란? (0) | 2024.11.07 |
[JAVA] Map과 JSON 데이터 변환 (0) | 2024.11.06 |
[JAVA] 고급 Map 패턴 및 활용 예제 (0) | 2024.11.06 |
[JAVA] Map 동기화 멀티스레딩 (2) | 2024.11.05 |
[JAVA] Map 성능 최적화와 메모리 관리 (0) | 2024.11.05 |
[JAVA] Map Java8 이상의 기능과 메서드 (0) | 2024.11.05 |