Java/컬렉션

[Java]Map을 List로 변환

DevStory 2022. 4. 4.

Map과 List

Java에서 Map은 키(key)-값(value) 쌍을 이루는 컬렉션입니다. 키는 고유한 값이며 중복될 수 없습니다.

 

일반적으로 Map 인터페이스를 구현한 클래스인 HashMap을 사용합니다.

Map<String, Integer> map = new HashMap<>();
map.put("John", 34);
map.put("Jane", 26);
map.put("Tom", 27);
map.put("Bill", 29);

System.out.println("Print Map: " + map);

실행 결과

Print Map: {Tom=27, John=34, Bill=29, Jane=26}

실행 결과를 보면 아시겠지만 삽입된 순서대로 출력되지 않았습니다. HashMap의 특징으로 삽입 순서를 보장하지 않습니다.

 

반면에 List는 순차적으로 데이터를 저장하고 각 요소에는 고유한 인덱스가 존재합니다.

List<String> li = new ArrayList<String>(
        Arrays.asList("John", "Jane", "Tom", "Bill"));
        
System.out.println("Print List: " + li);
System.out.println("Print Second Item: " + li.get(1));

실행 결과

Print List: [John, Jane, Tom, Bill]
Print Second Item: Jane

Map을 List로 변환하는 방법

위에서 Map과 List를 간단하게 소개하였습니다. Map과 List는 데이터를 관리하는 방법이 다르지만 Map의 키와 값을 List로 관리해야 하는 경우가 존재합니다. 이러한 경우 Map을 List로 변환해야 합니다.


Map.Entry<K, V> 타입의 List로 변환

Java 1.8에 도입된 Stream은 무거운 작업들을 쉽고 간단하게 만들어줍니다. Stream은 컬렉션(Collection)과 함께 사용할 수 있으며 Map을 List로 변환하는데 도움이 될 수 있습니다.

 

stream() 메서드를 사용한다면 Map의 키-값을 유지할 수 있습니다.

public static void main(String[] args) {
  Map<String, Integer> map = new HashMap<>();
  map.put("John", 34);
  map.put("Jane", 26);
  map.put("Tom", 27);
  map.put("Bill", 29);

  List<Map.Entry<String, Integer>> li = map.entrySet()
          .stream()
          .collect(Collectors.toList());

  System.out.println("List: " + li);
}

실행 결과

List: [Tom=27, John=34, Bill=29, Jane=26]

Stream은 List, Map, Set, Queue와 같은 컬렉션이 아니므로 stream() 메서드의 결과를 컬렉션으로 변환하는 작업이 필요합니다. 

반응형

두 개의 List를 사용

Map은 키-값 쌍을 이루는 2차원 컬렉션이고 List는 1차원 컬렉션입니다. 2개의 List를 사용하여 하나는 Map의 키 정보를 가지며 다른 하나는 Map의 값 정보를 가질 수 있습니다.

 

키의 목록을 반환하는 keySet() 메서드와 값의 목록을 반환하는 values() 메서드를 ArrayList 생성자에 전달합니다.

public static void main(String[] args) {
  Map<String, Integer> map = new HashMap<>();
  map.put("John", 34);
  map.put("Jane", 26);
  map.put("Tom", 27);
  map.put("Bill", 29);

  List<String> keyList = new ArrayList(map.keySet());
  List<Integer> valueList = new ArrayList(map.values());

  System.out.println("Key List: " + keyList);
  System.out.println("Value List: " + valueList);
}

실행 결과

Key List: [Tom, John, Bill, Jane]
Value List: [27, 34, 29, 26]

Collectors.toList() 및 Stream.map() 메서드

public static void main(String[] args) {
  Map<String, Integer> map = new HashMap<>();
  map.put("John", 34);
  map.put("Jane", 26);
  map.put("Tom", 27);
  map.put("Bill", 29);

  List<String> keyList = map.keySet()
          .stream()
          .collect(Collectors.toList());
          
  List<Integer> valueList = map.values()
          .stream()
          .collect(Collectors.toList());

  System.out.println("Key List: " + keyList);
  System.out.println("Value List: " + valueList);
}

실행 결과

Key List: [Tom, John, Bill, Jane]
Value List: [27, 34, 29, 26]

이 방식은 데이터를 컬렉션으로 변환하기 전에 다른 작업을 할 수 있다는 장점이 있습니다. 예를 들어 문자열을 소문자로 변환하거나 숫자 타입인 경우 연산을 수행할 수 있습니다.

 

다음은 익명 함수를 사용하여 키를 소문자로 변환하고 값에 10을 곱합니다.

public static void main(String[] args) {
  Map<String, Integer> map = new HashMap<>();
  map.put("John", 34);
  map.put("Jane", 26);
  map.put("Tom", 27);
  map.put("Bill", 29);

  List<String> keyList = map.keySet()
          .stream()
          .map(String::toLowerCase) // 메서드 참조
          .collect(Collectors.toList());

  List<Integer> valueList = map.values()
          .stream()
          .map(i -> i * 10)
          .collect(Collectors.toList());

  System.out.println("Key List: " + keyList);
  System.out.println("Value List: " + valueList);
}

실행 결과

Key List: [tom, john, bill, jane]
Value List: [270, 340, 290, 260]
메서드 참조
람다식에서 하나의 메서드만 호출하는 경우 다음과 같이 람다식을 간략히 할 수 있습니다.
클래스명::메서드명
참조변수::메서드명

Stream.filter() 및 Stream.sorted() 메서드

stream()의 결과를 컬렉션으로 만들기 전에 필터링하거나 정렬하고 싶은 경우 filter() 및 sorted() 메서드를 사용합니다.

public static void main(String[] args) {
  Map<String, Integer> map = new HashMap<>();
  map.put("John", 34);
  map.put("Jane", 26);
  map.put("Tom", 27);
  map.put("Bill", 29);

  List<String> keyList = map.keySet()
          .stream()
          .sorted() // 정렬
          .collect(Collectors.toList());

  List<Integer> valueList = map.values()
          .stream()
          .filter(i -> i >= 30) // 30이상인 데이터만 추출
          .collect(Collectors.toList());

  System.out.println("Key List: " + keyList);
  System.out.println("Value List: " + valueList);
}

실행 결과

Key List: [Bill, Jane, John, Tom]
Value List: [34]
반응형

댓글