Java

HashMap

voider 2020. 9. 9. 10:51

HashMap

출처 : https://medium.com/tanay-toshniwal/count-distinct-elements-in-input-sequence-using-java-hashmaps-373a58697dd2

HashMap은 Hashtable의 페이스리프트 버전이다.

Map을 구현한 클래스의 특징은 아래와 같다.

  • key, value를 묶어서 하나의 데이터entry로 저장한다.
  • key는 유일unique해야 한다.
  • value는 중복 가능
  • 해싱hassing을 사용하므로 많은 양의 데이터를 검색할 때 뛰어난 성능을 보인다.
public class HashMap extends AbstractMap implements Map, Cloneable, Serializable {
    transient Entry[] table;
    ...
    ...
    /*HashMap의 내부클래스로 Entry가 정의 되어 있다.*/
    static class Entry implements Map.Entry {    
        final Object key;
        Object value;
        ...
    }
}

HashMap의 소스 일부다. key와 value를 별개의 값이 아니라 내부클래스로 정의한 다음, 하나의 배열로 다루고 있다. 이것이 데이터의 무결성(integrity)적인 측면에서 더 좋은 방법이다.

HashMap의 메서드

method 설명
HashMap(int initialCapacity) (생성자)지정한 값을 초기 용량으로 하는 객체 생성
HashMap(int initialCapacity, float loadFactor) (생성자)지정한 초기 용량과 loadFactor를 가진 객체 생성
HashMap(Map m) (생성자)지정한 Map의 모든 요소를 포함하는 객체 생성)
void clear() 모든 객체 삭제
Object clone() 객체를 복사해서 반환
boolean containsKey(Object key) 지정한 key가 포함되어 있는지 확인
boolean containsValue(Object value) 지정한 value가 포함되어 있는지 확인
Set entrySet() 지정한 키와 값을 엔트리(key+value)의 형태로 Set에 저장해서 반환
Object get(Object key) 지정한 key의 매핑된 value를 반환.
Object getOrDefault(Object key, Object defaultValue) 지정한 key의 value를 반환. key를 못 찾으면 defaultValue로 지정한 객체를 반환
boolean isEmpty() 객체가 비어있는지 확인
Set keySet() 저장된 모든 key가 저장된 Set을 반환
Object put(Object key, Object value) 지정한 key와 vlaue를 저장
void putAll(Map m) 지정한 Map에 저장된 모든 요소를 저장
Object remove(Object key) 지정한 key로 저장된 객체(key+value) 제거
Object replace(Object key, Object value) 지정한 key의 값을 지정한 value로 대체
boolean replace(Object key, Object oldValue, Object newValue 지정한 key와 oldValue가 모두 일치하는 경우에만 새로운 객체newValue로 대체
int size() 저장된 객체의 수 반환
Collection values() 저장된 모든 값을 컬렉션 형태로 변환
package com.javaex.ch11;

import java.util.*;

public class HashMapEx3 {
    static HashMap phoneBook = new HashMap();

    public static void main(String[] args) {
        addPhoneNo("친구","이코코","010-0000-0001");
        addPhoneNo("회사","박코코","010-0000-0002");
        addPhoneNo("회사","라코코","010-0000-0003");
        addPhoneNo("친구","파코코","010-0000-0004");
        addPhoneNo("친구","초코코","010-0000-0005");
        addPhoneNo("친구","동코코","010-0000-0006");
        addPhoneNo("회사","이코코","010-0000-0007");
        addPhoneNo("네네치킨","000-000-0000");
        printList();
    }


    //그룹에 전화번호 추가
    static void addPhoneNo(String groupName, String name, String tel) {
        addGroup(groupName);    //새 그룹 이름 만들기
        HashMap group = (HashMap)phoneBook.get(groupName);  //새로 만든 그룹 이름의 value를 불러오기
        group.put(tel, name);   //중복일 수 없는 전화번호를 key로 설정

    }

    //그룹 추가
    static void addGroup(String groupName) {
        if(!phoneBook.containsKey(groupName)){  //그룹 이름 중복 체크
            phoneBook.put(groupName, new HashMap());    //그룹 이름과 HashMap객체를 phoneBook에 추가
        }
    }

    //미분류 그룹
    static void addPhoneNo(String name, String tel) {
        addPhoneNo("기타", name, tel);
    }

    //전화번호부 전체 출력
    static void printList() {
        Set set = phoneBook.entrySet(); //Map에 저장된 객체를 Set으로 반환하는 entrySet()
        Iterator iterator = set.iterator();

        while (iterator.hasNext()) {
            Map.Entry entry = (Map.Entry) iterator.next();

            Set subSet = ((HashMap)entry.getValue()).entrySet();    //value값을 subSet에 저장
            Iterator subIt = subSet.iterator();

            System.out.println(" * " +entry.getKey()+"["+subSet.size()+"]");

            while (subIt.hasNext()) {
                Map.Entry sub = (Map.Entry) subIt.next();
                String telNo = (String)sub.getKey();
                String name = (String)sub.getValue();
                System.out.println(name + " : " + telNo);
            }
            System.out.println();
        }  //end - while
    } //printList()
} //end - class


/*
결과

 * 기타[1]
네네치킨 : 000-000-0000

 * 친구[4]
동코코 : 010-0000-0006
초코코 : 010-0000-0005
이코코 : 010-0000-0001
파코코 : 010-0000-0004

 * 회사[3]
이코코 : 010-0000-0007
박코코 : 010-0000-0002
라코코 : 010-0000-0003
*/

HashMap은 데이터를 모두 Object타입으로 저장하기 때문에 HashMap안에 HashMap을 넣을 수 있다.

package com.javaex.ch11;

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

public class HashMap4 {
    public static void main(String[] args) {
        String[] data = {"A","K","A","K","D","K","A","K","K","K","Z","D"};

        HashMap map = new HashMap();

        for(int i=0; i < data.length; i++) {
            if(map.containsKey(data[i])) { //map에 저장된 key 중에 data[i]가 있다면,
                Integer value = (Integer)map.get(data[i]);  //key의 value를 Integer에 저장.
                /*
                ???value.intValue()와 value의 결과값이 같은데 왜 intValue()를 쓸까?
                */
                map.put(data[i], value.intValue() + 1); //map에 data[i]와, value+1 값을 저장
            } else {
                map.put(data[i], 1);   //없다면 map에 data[i]의 값과, 1을 저장
            }
        } // end - for

        Iterator iterator = map.entrySet().iterator();

        while (iterator.hasNext()) {
            Map.Entry entry =(Map.Entry) iterator.next();
            int value = ((Integer)entry.getValue()).intValue();
//            System.out.println("entry.getKey() : " + entry.getKey());
//            System.out.println("entry.getValue() : " + entry.getValue());
            System.out.println(entry.getKey() + " : " + printBar('#',value)+ " " + value);
        }
    } //main()

    public static String printBar(char ch, int value) {
        char[] bar = new char[value];

        for (int i = 0; i < bar.length; i++) {
            bar[i] = ch;
        }
            return new String(bar);
    }
}

위 코드 진행 과정

  1. 문자열 배열에 담긴 문자열을 하나씩 읽어서 HashMap에 key로 저장, 값으로 1을 저장한다.
  2. HashMap에 같은 문자열이 같은 문자열이 키로 저장되어있는지 containsKey()로 확인한다.
  3. 있다면 저장되어 있는 문자열의 value를 +1한다.
  4. printBar()를 이용해서 그래프로 표현한다.

'Java' 카테고리의 다른 글

제네릭 클래스Generics Class  (0) 2020.09.09
TreeMap  (0) 2020.09.09
TreeSet  (0) 2020.09.09
HashSet  (0) 2020.09.09
Comparable & Comparator  (0) 2020.09.09