본문 바로가기

Study/Java

[Java] HashMap은 값이 들어가는 순서를 보장하지 않는다

자바의 컬렉션 중 Map 인터페이스를 구현한 대표적인 예시가 HashMap이라고 할 수 있다.

HashMap은 key와 value를 쌍으로 가지는 Entity 객체를 담는 자료구조이다.

key와 value는 각각 객체이다. value는 중복될 수 있지만, key는 중복될 수 없는 것이 특징이다.

만약 기존에 있던 key와 동일한 key로 value를 저장하게 되면 기존에 있던 값은 삭제되고 새로운 값이 들어가게 된다.

 

이름처럼 Hashing을 사용하기 때문에 많은 양의 데이터를 검색할 때 높은 성능을 보인다.

 

그런데 HashMap은 hash 함수를 사용하여 값을 저장하기 때문에, 사용자가 값이 저장되는 위치를 알기 어렵고 값이 들어가는 순서는 위치와 무관해지게 된다.

 

예를 들어

 

import java.util.Map;
import java.util.HashMap;

public class Main {
    public static void main(String[] args) {
	    
        Map<String, Integer> map = new HashMap();
		
        for (int i = 0; i < 10; i++) {
            String key = "index_" + i;
            Integer value = i;
            map.put(key, value);
        }
		
        map.forEach((key, value) -> {
            System.out.println("key: " + key + ", value: " + value);
        });
    
	}
}

 

다음과 같이 HashMap을 생성하여 내부에 key와 value를 각각 String과 Integer로 지정하여 집어넣어준다.

예상대로라면 map 내부에 있는 내용을 출력했을 때

 

key: index_0, value: 0
key: index_1, value: 1
key: index_2, value: 2
key: index_3, value: 3
key: index_4, value: 4
key: index_5, value: 5
key: index_6, value: 6
key: index_7, value: 7
key: index_8, value: 8
key: index_9, value: 9

 

라고 나오는게 맞을 것이다..

 

실제로 출력해보면

 

key: index_1, value: 1
key: index_2, value: 2
key: index_3, value: 3
key: index_4, value: 4
key: index_0, value: 0
key: index_9, value: 9
key: index_5, value: 5
key: index_6, value: 6
key: index_7, value: 7
key: index_8, value: 8

 

이렇게 for 루프로 밀어넣은 순서에 상관없이 무작위로 값이 들어간 것을 볼 수 있다...

 

만약 HashMap에 값을 집어넣을 때 그 순서를 보장받고 싶다면 LinkedHashMap을 쓸 수 있다.

 

LinkedHashMap은 이중 연결 리스트(Doubly Linked List)를 사용하므로 순서를 유지한다. 그래서 데이터를 저장할 때 FIFO(First In First Out) 방식으로 저장하며, 순서를 유지하기 때문에 HashMap보다 더 많은 메모리를 사용하게 된다.

 

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

public class Main {
    public static void main(String[] args) {
	    
        Map<String, Integer> map = new LinkedHashMap();
		
        for (int i = 0; i < 10; i++) {
            String key = "index_" + i;
            Integer value = i;
            map.put(key, value);
        }
		
        map.forEach((key, value) -> {
            System.out.println("key: " + key + ", value: " + value);
        });
    }
}

 

이렇게 LinkedHashMap을 사용하여 데이터를 순서대로 집어넣고 출력해보면

 

key: index_0, value: 0
key: index_1, value: 1
key: index_2, value: 2
key: index_3, value: 3
key: index_4, value: 4
key: index_5, value: 5
key: index_6, value: 6
key: index_7, value: 7
key: index_8, value: 8
key: index_9, value: 9

 

값이 입력되는 순서를 보장받을 수 있다.