Java

[Java]Map계열 - HashMap

MoZZANG 2022. 3. 18. 21:59
HashMap의 특징
  • Map(인터페이스)계열의 컬렉션 클래스이다.
  • key와 value(객체)의 쌍으로 객체 저장
  • 키값으로 검색하기 때문에 다른 컬렉션보다 검색속도가 빠르다.
  • 키값은 중복이 안된다.

 

 

 

바로 예제를 보면서 알아보자.

 

<Raw Type>

1) 컬렉션 객체 생성 

▲ 타입 파라미터에 아무것도 넣지않은 Raw Type의 객체를 생성했다.

 

 

 

2) 객체 저장

▲ Map계열의 클래스에서 객체를 저장할 때는 put()메소드를 사용한다. put()메소드는 첫번째 인자로 키값을, 두번째 인자로 Value(객체)값을 받는다. 여기서는 우리가 타입파라미터에 아무것도 지정하지 않았기때문에 모든 타입의 키값과 객체값을 넣을 수 있다.

 

또한 put()메소드로 저장시 해당 키값으로 이전에 저장한 객체를 반환하는 특징을 가지고 있다.

즉, 우리가 위 코드에서 map.put("name","가길동")을 실행하면 name이라는 키값으로 저장하는 최초의 순간이기 때문에 이전에 저장된 객체가 없다. 따라서 null이 반환되며 만약 이전에 name이라는 키값으로 홍길동이라는 데이터를 저장한 적이 있다면 홍길동을 반환해줄 것이다.

 

 

 

 

3) 저장된 객체 수

▲ 다른 컬렉션 클래스에서도 사용하는 size()메소드를 사용하면 크기를 알 수 있다. 현재크기는 4개를 저장했기 때문에 4이다.

 

 

 

4) 키 값을 중복해서 저장

▲ Map은 키값은 고유하지만 객체는 고유하지 않다. 언제든지 수정될 수 있다. 우리는 위에서 "name"이라는 키값으로 "가길동"이라는 객체를 저장했다. 금고에 맞는 key는 하나, 내용물도 하나만 넣을 수 있기 때문에 name이라는 키로 열 수 있는 금고에 새로운 객체를 넣으려면 기존의 객체는 빼내고 넣어야한다. 따라서 키값은 중복해서 사용할 수 있지만 해당 키값에 기존에 저장된 객체는 지워지고 새로운 객체가 대신 들어가는 것이다. 때문에 사이즈는 여전히 4이다.

 

 

 

5-1) 출력 - 키 값을 알때

Map계열에서 key에 해당하는 객체를 꺼내올 때는 get()메소드를 사용한다. get()안에 키값을 넣으면 해당 키에 해당하는 객체를 반환한다.

 

'

 

 

5-2) 출력 - 키 값을 알때

▲ 항상 꺼내오는 것이 힘들다. Map계열은 다른 Set계열이나 List계열과 다르게 key와 value로 이루어 지기 때문에 키값을 알아야 그 키에 맞는 객체를 가져올 수 있기 때문에 순서가 조금 필요하다. 위 STEP을 잘 보고 이행해보자.

 

우선 keySet()이라는 메소드를 호출하면 Map에 저장된 모든 키값들만을 가져온다. 가져와서 Set계열의 컬렉션 형태로 변환하는 특징이 있다. 

 

확장for문은 Set계열과 List계열에서만 사용가능하다. Map계열에서는 사용불가이니 주의하자.

우리가 가져온 모든 key들을 Set타입의 변수 keys에 넣었기 때문에 여기서는 확장for문을 사용할 수 있다.

 

확장for문을 사용하여 가져온 모든 key에서 하나씩 꺼내어서 get()메소드에 넣어주면 말그대로 get! 해당 키에 맞는 객체를 가져오게 된다. 위 코드에서 가져온 객체를 Object타입의 변수 value에 저장했는데 이는 우리가 현재 키와 객체의 타입을 지정하지 않은 Raw Type을 사용하고 있기 때문에 모든 타입을 다 담을 수 있는 Object 변수에 넣은 것이다.

우리가 타입파라미터를 지정하면 Obejct는 우리가 지정한 타입에 맞게 바뀌어야 할 것이다.

 

 

▲ 위 코드의 출력결과

 

 

 

5-3) Value만 얻어 올때

 

▲ 키값을 제외한 모든 객체들만을 가져올때는 values()메소드를 사용하면 된다.

 

▲values()메소드를 사용했을 때의 결과

 

 

 

6) 검색

▲ 해당키가 Map에 존재하는지를 체크할 때는 containsKey()메소드를, 해당 객체가 Map에 존재하는 지를 체크할 때는 containsValue()메소드를 사용하면 된다. 두 메소드 모두 boolean값을 반환하기 때문에 존재하면 true, 존재하지 않으면 false를 반환한다.

 

 

 

7) 삭제

▲ 삭제 메소드는 다른타입의 컬렉션과 동일하다. 하지만 Map에서 reomve() 를 사용하면 해당 키값에 해당하는 객체를 지움과 동시에 삭제된 객체를 반환한다는 특징이 있다. 

 

▲ Map계열에서는 removeAll()이라는 메소드가 없다. 따라서 .clear()메소드로 전체 삭제를 해야한다.

 

 

 

 

 

 

<Generic Type>

1) 컬렉션 객체 생성 

▲ 이번에는 키값을 String타입만, value값으로 Student타입만을 받겠다고 타입을 지정해주었다. 이처럼 타입파라미터에 타입을 지정해주면 해당 타입만 저장이 가능하기 때문에 자동으로 컴파일시점에 타입체크가 가능하기 때문에 타입안정성(Type Safety)가 높아진다. 또한 해당 타입만 저장할 것이기 때문에 형변환 또한 불필요해진다는 장점이 있다.

 

 

※ Student타입은 우리블로그에서 자주예제로 사용하는 타입입니다.

 

 

 

 

2) 컬렉션에 저장할 객체 생성 및 저장

 

▲ 저장할 객체 생성 및 저장. 역시나 Map계열이므로 put()메소드를 이용한다. 

 

 

 

 

3) 객체 꺼내기

▲Raw type예제에서 한 방법과 동일한 방법으로 객체를 꺼낸다.

 

 

 

 

 

<맵계열 컬렉션에 저장된 객체 정렬하기>

이번에는 Map에 저장된 객체들을 정렬한 후 출력해보는 예제를 보자

 

우리가 앞선 포스팅 중 배열과 List계열 컬렉션에서 정렬하는 법을 살펴본바가 있다. 하지만 Map계열에는 적용되지 않기 때문에 Map계열을 List계열로 바꾼 후 정렬을 해아한다.

 

 

▲정렬할 객체들을 생성하고 저장하자.

 

 

Map계열에서 정렬을 할 때는 Entry라는 인터페이스를 용한다.

 

Enrty인터페이스
  • Entry는 Map인터페이스의 내부 정적 인터페이스이다.
  • Entry는 해당 맵의 key=value쌍을 요소로 갖는 객체이다.
  • 여기서 'key=value' 를 Entry라고 부른다.
  • 즉 위의 sortMap에 저장된 키=객체의 엔트리들을 저장한 리스트 컬렉션을 생성한다.

 

1. Entry를 요소로 갖는 List컬렉션 객체 생성

 

 

 

-정렬 전 엔트리객체-

 

▲ default는 오름차순이기 때문에 우리가 정렬을 따로 하지않으면 오름차순으로 자동정렬 되어있다.

 

 

 

 

 

2. 1에서 생성한 List컬렉션에 Collections.sort()적용

 

▲ 방법과 구조는 모두 '배열과 List컬렉션 정렬'포스팅에서 알아본 것과 동일하다. 

 

필수적으로 Comparable을 상속받아야 하고 compare()메소드를 오버라이딩 해야한다.