본문

HashMap(JAVA)

반응형

# HashMap

HashMap은 키(key)와 값(value)을 묶어서 하나의 데이터(entry)로 저장한다는 특징을 갖는다.

그리고 해싱(hashing)을 사용하기 때문에 많은 양의 데이터를 검색하는데 있어서 뛰어난 성능을 보인다.


비객체지향적인 코드 

객체지향적인 코드 

Object[] key;

Object[] value;

Entry[] table;

class Entry {

   Object key;

   Object value;

}


- 키(key) : 컬렉션 내의키(key) 중에서 유일해야 한다.

- 값(value) : 키(key)와 달리 데이터의 중복을 허용한다.


키는 저장된 값을 찾는데 사용되는 것이기 때문에 컬렉션 내에서 유일해야한다.
즉, HashMap에 저장된 데이터를 하나의 키로 검색했을 때 결과가 단 하나이어야 함을 뜻한다.
만일 하나의 키에 대해 여러 검색결과 값을 얻는다면 원하는 값이 어떤 것인지 알 수 없기 때문이다.


Source 01) HashMapEx01.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package hashMapEx;
 
import java.util.HashMap;
import java.util.Scanner;
 
public class HashMapEx01 {
 
    public static void main(String[] args) {
        HashMap map = new HashMap();
        map.put("hello""1234");
        map.put("hi""1111"); // 무시됨
        map.put("hi""1234");
 
        // 화면으로부터 라인단위로 입력받는다.
        Scanner s = new Scanner(System.in);
 
        while (true) {
            System.out.println("id와 password를 입력해주세요.");
            System.out.println("id : ");
            String id = s.nextLine().trim(); // trim()은 공백제거 메소드
 
            System.out.println("password : ");
            String password = s.nextLine().trim();
            System.out.println();
 
            if (!map.containsKey(id)) {
                System.out.println("입력하신 id는 존재하지 않습니다." + " 다시 입력해주세요.");
 
                continue;
            } else {
                if (!(map.get(id).equals(password))) {
                    System.out.println("비밀번호가 일치하지 않습니다. 다시 입력해주세요.");
                } else {
                    System.out.println("id와 비밀번호가 일치합니다.");
                    break;
                }
            }
        }
    }
}
cs


Result)



3개의 데이터 쌍을 저장했지만 실제로는 2개 밖에 저장되지 않은 이유는 중복된 키가 이기 때문이다.
세 번째로 저장한 데이터의 키인 'hi'는 이미 존재하기 때문에 새로 추가되는 대신 기존의 값을 덮어썼다.
그래서 키 'hi'에 연결된 값은 '1234'가 된다.




Source 02) HashMapEx02.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
package hashMapEx;
 
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
 
public class HashMapEx02 {
 
    public static void main(String[] args) {
        HashMap map = new HashMap();
        map.put("임승한 "new Integer(90));    // 무시됨
        map.put("임승한 "new Integer(100));
        map.put("홍길동 "new Integer(100));
        map.put("춘향이 "new Integer(90));
        map.put("김두환 "new Integer(90));
 
        // entrySet()을 이용해서 키와 값을 함께 읽어옴
        Set set = map.entrySet();
        Iterator it = set.iterator();
 
        while (it.hasNext()) {
            Map.Entry e = (Map.Entry) it.next();
            System.out.println("이름 : " + e.getKey() + "점수 : " + e.getValue());
        }
  
          // keySet()을 이용해서 키값을 읽어옴
        set = map.keySet();
        System.out.println("참가자 명단 : " + set);
 
         // values()을 이용해서 키값을 읽어옴
        Collection value = map.values();
        it = value.iterator();
 
        int total = 0;
 
        while (it.hasNext()) {
            Integer i = (Integer) it.next();
            total += i.intValue();
        }
 
        System.out.println("총점 : " + total);
        System.out.println("평균 : " + (float) total / set.size());
        System.out.println("최고점수 : " + Collections.max(value));
        System.out.println("최저점수 : " + Collections.max(value));
 
    }
 
}
cs

Result)

1
2
3
4
5
6
7
8
9
이름 : 춘향이 점수 : 90
이름 : 홍길동 점수 : 100
이름 : 김두환 점수 : 90
이름 : 임승한 점수 : 100
참가자 명단 : [춘향이 , 홍길동 , 김두환 , 임승한 ]
총점 : 380
평균 : 95.0
최고점수 : 100
최저점수 : 90
cs


Source 03) HashMapEx03.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
package hashMapEx;
 
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
 
public class HashMapEx03 {
    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("세탁""010-0000-0000");
 
        printList();
    }
 
    /*
     * HashMap은 데이터의 키와 값을 모두 Object타입으로 저장하기 때문에 HashMap의 값(value)으로 HashMap을
     * 다시 저장할 수 있다. 이렇게 함으로써 하나의 키에 다시 복수의 데이터를 저장할 수 있다. 먼저 전화번호를 저장할 그룹을 만들고
     * 그룹 안에 다시 이름과 전화번호를 저장하도록 했다. 이때 이름대신 전화번호를 키로 사용했다는 것을 확인하자. 이름은 동명이인이 있을
     * 수 있지만 전화번호는 유일하기 때문이다.
     */
 
    // 그룹을 추가하는 메서드
    private static void addGroup(String groupName) {
        if (!phoneBook.containsKey(groupName))
            phoneBook.put(groupName, new HashMap());
    }
 
    // 그룹에 전화번호를 추가하는 메서드
    private static void addPhoneNo(String groupName, String name, String tel) {
        addGroup(groupName);
        HashMap group = (HashMap) phoneBook.get(groupName);
        group.put(tel, name); // 이름은 중복될 수 있으니 전화번호를 key로 저장한다.
    }
 
    private static void addPhoneNo(String name, String tel) {
        addPhoneNo("기타", name, tel);
    }
 
    // 전화번호부 전체를 출력하는 메서드
    // entrySet() : 키(key)와 값(value)을 함께 읽어온다.
    /* HashMap을 중첩으로 사용했기 때문에 Iterator도 두번 사용되었다. */
    private static void printList() {
        Set set = phoneBook.entrySet();
        Iterator it = set.iterator();
 
        while (it.hasNext()) {
            Map.Entry e = (Map.Entry) it.next();
 
            Set subSet = ((HashMap) e.getValue()).entrySet();
            Iterator subIt = subSet.iterator();
 
            System.out.println(" * " + e.getKey() + "[" + subSet.size() + "]");
 
            while (subIt.hasNext()) {
                Map.Entry subE = (Map.Entry) subIt.next();
                String telNo = (String) subE.getKey();
                String name = (String) subE.getValue();
                System.out.println(name + " " + telNo);
 
            }
 
            System.out.println();
        }
    }
}
cs

Result)

1
2
3
4
5
6
7
8
9
10
11
12
13
 * 기타[1]
세탁 010-0000-0000
 
 * 친구[3]
홍길동 010-0000-0002
임승한 010-0000-0001
아무개 010-0000-0003
 
 * 회사[4]
나사원 010-0000-0006
이사원 010-0000-0005
인사원 010-0000-0007
김사원 010-0000-0004
cs


Source 04) HashMapEx04.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
package hashMapEx;
 
import java.awt.print.Printable;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
 
public class HashMapEx04 {
 
    public static void main(String[] args) {
        String[] data = { "A""K""A""A""K""D""K""A""K""K""K""K""Z""D" };
 
        HashMap map = new HashMap();
 
        for (int i = 0; i < data.length; i++) {
            /*
             * HashMap에 같은 문자열이 키로 저장되어 있는지 containKey()로 확인하여
             * 이미 저장되어 있는 문자열이면 값을 1증가시킨다.
             */
            if (map.containsKey(data[i])) {
                Integer value = (Integer) map.get(data[i]);
                map.put(data[i], new Integer(value.intValue() + 1));
            } else {
                /*
                 * 문자열 배열에 담긴 문자열을 하나씩 읽어서 HashMap에 키로 저장하고 값으로 1을 저장한다.
                 */
                map.put(data[i], new Integer(1));
            }
        }
 
        Iterator it = map.entrySet().iterator();
 
        while (it.hasNext()) {
            Map.Entry entry = (Map.Entry) it.next();
            int value = ((Integer) entry.getValue()).intValue();
            System.out.println(entry.getKey() + " : " + PrintBar('#', value) + " " + value);
        }
    }
 
    private static Object 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); // String(char[] chArr)
    }
 
}
cs

Result)

1
2
3
4
A : #### 4
D : ## 2
Z : # 1
K : ####### 7
cs

문자열 배열에 담긴 문자열을 하나씩 읽어서 HashMap에 키로 저장하고 값으로 1을 저장한다.
 HashMap에 같은 문자열이 키로 저장되어 있는지 containKey()로 확인하여 이미 저장되어 있는 문자열이면 값을 1증가시킨다. 

그리고 그 결과를 printBar()을 이용해서 그래프로 표현했다. 이렇게 하면 문자열 배열에 담긴 문자열들의 빈도수를 구할 수 있다. 

한정된 범위 내에 있는 순차적인 값들의 빈도수배열을 이용하지만, 이처럼 한정되지 않은 범위의 비순차적인 값들의 빈도수HashMap을 이용해서 구할 수 있다.




출처 및 참고자료 : JAVA의정석(남궁성 저)

반응형

공유

댓글