JAVA Map반복하기

2021. 11. 26. 09:51자바

※전체코드는 맨 아래 있습니다. 

 

자바에서 map을 직접 반복하는 방법은 없고 map에서 제공해주는 set을 통해 반복해야 한다.

set을 반복하는 방법은 단순 for문과 iterator를 이용한 방법, 총 2가지가 있다.

map에서 제공하는 set은 2종류다. keySet과 entrySet 

그러므로 map을 반복하는 방법은 keySet반복개수(2) + entrySet반복개수(2)로 총 4개의 방법이 있다. 

 

예시로 다음과 같은 map을 가지고 하겠다.

Map<String,String> map=new HashMap<>();
map.put("key1", "value1");
map.put("key2", "value2");
map.put("key3", "value3");

그러면 map에는 다음과 같은 형태로 값이 저장 될 것이다.

key value
key1 value1
key2 value2
key3 value3

 

 

 

1.keySet

map에서 제공해주는 keySet() 메소드를 통해 key에 관한 Set을 얻을 수 있다.

이 예제에서는 ["key1","key2", "key3" ] 이라는 Set을 얻게 된다.

이 Set을 통해 for문과 iterator 원하는 반복형태로 반복하면  map을 반복 할 수 있다.

  	Set<String> keySet = map.keySet();   //[key1, key2, key3]

        //set에서 직접 for문
        for (String key : keySet) {      //key는 key1, key2, key3이 반복 될거고 각각의 key값을 통해 map에서 각각의 value값을 얻을 수 있다.
            String value = map.get(key);
            System.out.print("key값 = " + key + ", \t");
            System.out.println("value값 = " + value);
        }

        System.out.println();
	//set에서 iterator 얻은 후 iterator 반복
        Iterator<String> iterator = keySet.iterator();
        while (iterator.hasNext()) {
            String key = iterator.next();
            String value = map.get(key);
            System.out.print("key값 = " + key + ", \t");
            System.out.println("value값 = " + value);
        }

 

 

 

2.EntrySet 

map에서 제공해주는 entrySet() 메소드를 통해 Entry에 관한 Set을 얻을 수 있다.

근데 여기서 의문은 keySet은 String 타입의 key를 Set형태로 제공한다고 했다.

그래서 keySet의 데이터 타입은   Set<String> 이었다.

	Set<String> keySet = map.keySet();   //[key1, key2, key3]

 

 

마찬가지로 entrySet의 데이터 타입은  Set<Entry>  일 것이다.  

그럼 Entry란 무엇일까? 

Entry란 key와 value로 이루어진 하나의 데이터 형태이다.

이렇게 (key,value)로 이루어진 걸 Entry라고 하고  이 Entry가 모여서 만들어진게 Map이다.

 

Entry는 Map 내부의 Interface로 정의 되어있고,

우리가 실제로 만든 HashMap에서는 이 Entry를 상속 받은 Node가 정의 되어있다.

public interface Map<K,V> {

	interface Entry<K,V> {
        /**
         * Returns the key corresponding to this entry.
         *
         * @return the key corresponding to this entry
         * @throws IllegalStateException implementations may, but are not
         *         required to, throw this exception if the entry has been
         *         removed from the backing map.
         */
        K getKey();

        /**
         * Returns the value corresponding to this entry.  If the mapping
         * has been removed from the backing map (by the iterator's
         * <tt>remove</tt> operation), the results of this call are undefined.
         *
         * @return the value corresponding to this entry
         * @throws IllegalStateException implementations may, but are not
         *         required to, throw this exception if the entry has been
         *         removed from the backing map.
         */
        V getValue();
        
        .....
        
        }
   }
 public class HashMap<K,V> extends AbstractMap<K,V>
    implements Map<K,V>, Cloneable, Serializable {
 	.....
    
 	static class Node<K,V> implements Map.Entry<K,V> {
        final int hash;
        final K key;
        V value;
        Node<K,V> next;

        Node(int hash, K key, V value, Node<K,V> next) {
            this.hash = hash;
            this.key = key;
            this.value = value;
            this.next = next;
        }
        ...
    }
    ...
    
}

 

 

Entry는 제네릭으로 만들어지기 때문에  데이터 타입은 Entry<K,V>이다. 

예제에서는 Map을 만들 때 

  Map<String, String> map = new HashMap<>();

으로 만들었기 때문에 Entry<String,String>이 된다.  

이 때 Entry자체는 Map의 내부 인터페이스이기 때문에 entrySet() 메소의 return 타입은 다음과 같다. 

Set<Map.Entry<String, String>> entrySet = map.entrySet();

 

만약 java.util.Map.Entry를  import 한다면  다음과 같이 된다.   ( import  java.util.Map.Entry; )

 Set<Entry<String, String>> entrySet = map.entrySet();
 

이제 이 entrySet을 가지고 for문이나 iterator를 통해 반복해주면 된다.

 // Set<Map.Entry<String, String>> entrySet = map.entrySet();  //Map.entry import하기 전
       Set<Entry<String, String>> entrySet = map.entrySet();

        //set에서 직접 for문
        for(Entry<String,String> entry : entrySet){
            String key=entry.getKey();
            String value=entry.getValue();
            System.out.print("key값 = " + key + ", \t");
            System.out.println("value값 = " + value);
        }

        System.out.println();

        //iteraotr얻어서 반복
        Iterator<Entry<String,String>> entryIterator= entrySet.iterator();
        while (entryIterator.hasNext()){
            Entry<String,String> entry=entryIterator.next();
            String key=entry.getKey();
            String value=entry.getValue();
            System.out.print("key값 = " + key + ", \t");
            System.out.println("value값 = " + value);
        }

 

 

 

이렇게 총 4가지의 map반복에 대해 알아보았다.

map반복에서 중요한 건 map에서 Set을 얻은 다음 Set을 반복한다는 것이다.

나는 처음에 map 반복 할 때 마다 인터넷을 참고했었는데 set을 반복한다는 것을 알고나서는

안 보고 자연스럽게 하게 되었다.  여러분들도 Map 반복을 안 보고 자연스럽게 할 수 있으면 좋겠다.

 

마지막으로 전체 코드이다.

import java.util.*;
import  java.util.Map.Entry;

public class Main {


    public static void main(String[] args) {
        Map<String, String> map = new HashMap<>();
        map.put("key1", "value1");
        map.put("key2", "value2");
        map.put("key3", "value3");

        Set<String> keySet = map.keySet();   //[key1, key2, key3]

        //set에서 직접 for문
        for (String key : keySet) {      //key는 key1, key2, key3이 반복 될거고 각각의 key값을 통해 map에서 각각의 value값을 얻을 수 있다.
            String value = map.get(key);
            System.out.print("key값 = " + key + ", \t");
            System.out.println("value값 = " + value);
        }

        System.out.println();
        //set에서 iterator 얻은 후 iterator 반복
        Iterator<String> iterator = keySet.iterator();
        while (iterator.hasNext()) {
            String key = iterator.next();
            String value = map.get(key);
            System.out.print("key값 = " + key + ", \t");
            System.out.println("value값 = " + value);
        }
        
        
		System.out.println();
        System.out.println();
        
		
       // Set<Map.Entry<String, String>> entrySet = map.entrySet();  //Map.entry import하기 전
       Set<Entry<String, String>> entrySet = map.entrySet();

        //set에서 직접 for문
        for(Entry<String,String> entry : entrySet){
            String key=entry.getKey();
            String value=entry.getValue();
            System.out.print("key값 = " + key + ", \t");
            System.out.println("value값 = " + value);
        }

        System.out.println();

        //iteraotr얻어서 반복
        Iterator<Entry<String,String>> entryIterator= entrySet.iterator();
        while (entryIterator.hasNext()){
            Entry<String,String> entry=entryIterator.next();
            String key=entry.getKey();
            String value=entry.getValue();
            System.out.print("key값 = " + key + ", \t");
            System.out.println("value값 = " + value);
        }

    }
}

 

 

 

 

※ 위의 4가지 방법말고 forEach메소드를 이용해서 할 수도 있지만,  entrySet iterator와 똑같은 방식이다.

 map.forEach( (key, value) -> {
      System.out.print("key값 = " + key + ", \t");
      System.out.println("value값 = " + value);
  });

 또 set에서 stream을 이용해서 반복 할 수도 있다.