JAVA

[Java] HashMap

로춘남 2022. 1. 26. 13:37
728x90


HashMap 이란?

Map 인터페이스를 구현하고 있는 대표적인 자바 클래스. key-value쌍으로 되어있다. Map의 대표적인 특징은 key는 정확히 하나의 value만 가질 수 있다.

public class HashMap<K, V> extends AbstractMap<K,V> implements Map<K, V>, Cloneable, Serializable {

}

HashMap 클래스의 내부는 위와 같은 상속, 구현 관계를 가지고 있다.

 

HashMap은 왜 필요할까?

List 형태를 사용하지 않고 HashMap을 사용하는 이유는 바로 성능 때문이다. 만약 List를 사용했다면 검색하는데 있어 시간복잡도는 O(n)으로 나타날것이다. 반면 HashMap은 삽입, 검색 시간에 시간복잡도 O(1)이라는 이점을 가지고 있다.

key값의 hashCode를 index로 Array에 값을 저장하기때문에 검색속도는 매우 빠르다. 또한 Hashing을검색을 사용하고 있어 대용량 데이터 관리에도 적합한 성능을 보여주고 있다. key의 값은 중복되지 않고, value값은 중복이 허용된다.

 

HashMap에서 데이터를 넣는 방법은 put() 함수를 사용한다. 첫 번째 인수로 key값을 넣고, 두 번째 인수로 value를 입력한다. key값에 integer가 아닌 소수점이 있는 실수를 사용하게 되면 error가 발생된다.

 

ex)

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

map.put(1, "서울");
map.put(2, "로마");
map.put(3, "뉴욕");
map.put(2, "파리");
map.put(5, "런던");

System.out.println(map);

//출력
{1=서울, 2=파리, 3=뉴욕, 5=런던}

단, 사용을 할때 주의할 점은 key값은 중복이 되지 않고, value값은 허용이 된다. 또한 위 코드처럼 2에 해당하는 부분. key값이 중복이 된다면 최종적으로 저장되는 value는 "파리"로 나중에 입력된 key의 value로 덮어 씌어지게 된다.

 

HashMap을 이용하여 값을 가져오는 방법은 get() 함수를 사용할 수 있다.

map.put(1, "서울");
map.put(2, "로마");
map.put(3, "뉴욕");
map.put(2, "파리");
map.put(5, "런던");

String val = map.get(2).toString();
System.out.println("key값이 2 " + val);

//출력값
ke값이 2 파리

HashMap을 이용하여 반복문으로 데이터를 꺼내올때는 Iterator라는 방법을 이용 할 수 있다. 자바의 컬렉션 프레임워크에서 컬렉션에 저장되어 있는 데이터를 읽어오는 방법이다.

public interface Iterator{

boolean hasNext();
Object next();
void remove();

}

boolean hasNext()는 읽어 올 요소가 남아있는지 확인하는 것. 만약 요소가 남아있다면 true. 없으면 false를 반환한다.

Object next()는 다음데이터를 반환하며, void remove()는 next()로 읽어 온 요소를 삭제한다. next()를 호출했다면 다음에 remove()를 호출해줘야한다.

 

Iterator 타입에 변수를 생성하고 컬렉션에 iterator 메서드를 값으로 넣으면, List타입의 변수를 iterator으로 변환한다.

Iterator iter = listTest.iterator();
while(iter.hasNext()) {
	System.out.println(iter.next());
}

여기서 hasNext()메서드는 while 반복문으로 iter변수에 다음 데이터가 잇을때까지 실행하게 된다. while문에 조건을 hasNext()로 검사한 뒤 next() 데이터를 반환한다.

 

iterator 메서드 호출순서는 hasNext -> next -> remove 순으로 이루어진다. List 혹은 Set 인터페이스를 구현하는 컬렉션은 iterator()가 컬렉션의 특징에 맞게 설계가 되어있다.

 

HashMap은 iterator()로 Iterator 객체를 return한다. 이것은 반복문으로 데이터를 처리 할 때 아주 유용하다. hasNext() 함수로 null인지 판단하여 while문을 반복하고, 차례대로 데이터를 가져올 수 있는 next()로 값을 꺼내온다. 이렇게 꺼내온값은 value가 아닌 key값이며, key값에 해당하는 value를 가져오려면 get()함수를 사용해야한다.

 

map.put(1, "서울");
map.put(2, "로마");
map.put(3, "뉴욕");
 
Iterator<Integer> keySetIterator = map.keySet().iterator();
while (keySetIterator.hasNext()) {
    Integer key = keySetIterator.next();
    System.out.println("key: " + key + " value: " + map.get(key));
}

// 출력
key: 1 value: 서율
key: 2 value: 로마
key: 3 value: 뉴욕

 

HashMap 객체에 저장된 데이터를 한 번에 지우기 위해선

map.put(1, "서울");
map.put(2, "로마");
map.put(3, "뉴욕");
 
System.out.println(map);
map.clear(); //삭제
System.out.println(map);

//빈 객체인지 체크하는 isEmpty 함수
boolean isEmpty = map.isEmpty();
System.out.println(isEmpty);

//출력
{1=서울,2=로마,3=뉴욕}
{}
true

clear()함수는 저장된 모든 데이터를 지우며, null 포인트를 만드는것은 아니다. 지우고나서 데이터가 있는지 없는지를 체크해볼수있는 함수가 바로 isEmpty()다. clear()로 지웠기때문에 출력값은 true가 나오게 된다.

 

특정 key값에 해당하는 데이터는 remove()를 적용 할 수 있다.

 

map.put(1, "서울");
map.put(2, "로마");
map.put(3, "뉴욕");
 
Integer kye = 3;
Object value = map.remove(key);
System.out.println("key값 삭제 후 리턴받은 결과: " + value);

//출력
key값 삭제 후 리턴받은 결과: 뉴욕

remove() 함수를 적용하면 key값을 넘기면서 데이터를 지울수있다.

 

HashMap을 이용하여 데이터를 정렬 할 수도 있다.

map.put(3, "서울");
map.put(1, "로마");
map.put(2, "뉴욕");
 
System.out.println("정렬하지 않았을때:" + map);
TreeMap sortedHashMap = new TreeMap(map);
System.out.println("정렬했을때:" + sortedHashMap);

//출력
정렬하지 않았을때:{3=서울,1=로마,2=뉴욕}
정렬했을때:{1=로마,2=뉴욕,3=서울}

 

출처: https://hgserver.tistory.com/54

728x90