본문 바로가기
Algorithm & Data Structure/study

[Data Structure / Java] ✒️ HashMap

by ro117youshin 2022. 8. 18.
728x90

HashMap이란

 HashMap은 Map 인터페이스를 구현한 대표적인 Map 컬렉션이다. Map 인터페이스를 상속하고 있기 때문에 Map의 성질을 그대로 가지고 있다. Map은 key와 value로 구성된 Entry객체를 저장하는 구조를 가지고 있는 자료구조이다. 여기서 key와 value는 모두 객체이다. HashMap은 해싱(Hashing)을 사용하기 때문에 많은 양의 데이터를 검색하는 데 있어서 뛰어난 성능을 보인다.

https://coding-factory.tistory.com/556

 HashMap은 Hash function을 통해 key와 value가 저장되는 위치를 결정하므로, 사용자는 그 위치를 알 수 없고, 삽입되는 순서와 들어 있는 위치 또한 관계가 없다.

 

HashMap 사용법

선언

HashMap<String,String> map1 = new HashMap<String,String>();//HashMap생성
HashMap<String,String> map2 = new HashMap<>();//new에서 타입 파라미터 생략가능
HashMap<String,String> map3 = new HashMap<>(map1);//map1의 모든 값을 가진 HashMap생성
HashMap<String,String> map4 = new HashMap<>(10);//초기 용량(capacity)지정
HashMap<String,String> map5 = new HashMap<>(10, 0.7f);//초기 capacity,load factor지정
HashMap<String,String> map6 = new HashMap<String,String>(){{//초기값 지정
    put("a","b");
}};

HashMap을 생성하려면 key 타입과 value 타입을 파라미터로 주고 기본 생성자를 호출하면 됩니다. HashMap은 저장공간보다 값이 추가로 들어오면 List처럼 저장공간을 추가로 늘리는데 List처럼 저장공간을 한 칸씩 늘리지 않고 약 두배로 늘린다. 여기서 과부하가 많이 발생한다. 그렇기에 초기에 저장할 데이터 개수를 알고 있다면 Map의 초기 용량을 지정해주는 것이 좋다. 해당 내용은 아래 링크에서 상세히 기술되어 있다.

https://d2.naver.com/helloworld/831311

 

값 추가

HashMap<Integer,String> map = new HashMap<>();//new에서 타입 파라미터 생략가능
map.put(1,"아메리카노"); //값 추가
map.put(2,"카페라떼");
map.put(3,"녹차라떼");

HashMap에 값을 추가하려면 put(key,value) 메서드를 사용하면 된다. 선언 시 HashMap에 설정해준 타입과 같은 타입의 Key와 Value값을 넣어야 하며 만약 입력되는 키 값이 HashMap 내부에 존재한다면 기존의 값은 새로 입력되는 값으로 대치된다.

 

값 삭제

HashMap<Integer,String> map = new HashMap<>();//new에서 타입 파라미터 생략가능
map.put(1,"아메리카노"); //값 추가
map.put(2,"카페라떼");
map.put(3,"녹차라떼");

map.remove(1); // key 값 1 제거
map.clear(); // 모든 값 제거

HashMap의 값을 제거하려면 remove(key) 메서드를 사용하면 된다.

오직 key값으로만 Map의 요소를 삭제할 수 있다. 모든 값을 제거하려면 clear() 메서드를 사용하면 된다.

 

값 출력

HashMap<Integer,String> map = new HashMap<Integer,String>(){{//초기값 지정
    put(1,"아메리카노");
    put(2,"카페라떼");
    put(3,"녹차라떼");
}};
		
System.out.println(map); //전체 출력 : {1=아메리카노, 2=카페라떼, 3=녹차라떼}
System.out.println(map.get(1));//key값 1의 value얻기 : 아메리카노
		
//entrySet() 활용
for (Entry<Integer, String> entry : map.entrySet()) {
    System.out.println("[Key]:" + entry.getKey() + " [Value]:" + entry.getValue());
}
//[Key]:1 [Value]:아메리카노
//[Key]:2 [Value]:카페라떼
//[Key]:3 [Value]:녹차라떼

//KeySet() 활용
for(Integer i : map.keySet()){ //저장된 key값 확인
    System.out.println("[Key]:" + i + " [Value]:" + map.get(i));
}
//[Key]:1 [Value]:아메리카노
//[Key]:2 [Value]:카페라떼
//[Key]:3 [Value]:녹차라떼

HashMap을 출력하는 방법에는 다양한 방법이 있다.

그냥 print하게 되면 {}로 묶어 Map의 전체 key값, value가 출력된다. 특정 key값의 value를 가져오고싶다면 get(key)를 사용하면 되고 전체를 출력하려면 entrySet()이나 keySet() 메서드를 활용하여 Map의 객체를 반환받은 후 출력하면 된다. entrySet()은 key와 value 모두가 필요할 경우 사용하며 keySet()은 key 값만 필요할 경우 사용하는데 key값만 받아서 get(key)를 활용하여 value도 출력할 수도 있기에 어떤 메서드를 선택하든지 간에 큰 상관이 없어 대부분 코드가 간단한 keySet을 활용하시던데 key값을 이용해서 value를 찾는 과정에서 시간이 많이 소모되므로 많은 양의 데이터를 가져와야 한다면 entrySet()이 좋다.(약 20%~200% 성능 저하가 있음)

Iterator 사용

HashMap<Integer,String> map = new HashMap<Integer,String>(){{//초기값 지정
    put(1,"아메리카노");
    put(2,"카페라떼");
    put(3,"녹차라떼");
}};
		
//entrySet().iterator()
Iterator<Entry<Integer, String>> entries = map.entrySet().iterator();
while(entries.hasNext()){
    Map.Entry<Integer, String> entry = entries.next();
    System.out.println("[Key]:" + entry.getKey() + " [Value]:" +  entry.getValue());
}
//[Key]:1 [Value]:아메리카노
//[Key]:2 [Value]:카페라떼
//[Key]:3 [Value]:녹차라떼
		
//keySet().iterator()
Iterator<Integer> keys = map.keySet().iterator();
while(keys.hasNext()){
    int key = keys.next();
    System.out.println("[Key]:" + key + " [Value]:" +  map.get(key));
}
//[Key]:1 [Value]:아메리카노
//[Key]:2 [Value]:카페라떼
//[Key]:3 [Value]:녹차라떼

HashMap의 전체 출력 시 반복문을 사용하지 안호 Iterator를 사용해도 된다.

 

Reference

 

 

댓글