본문 바로가기
개발/Java collection framework

[Java] Map 컬랙션

by 두리두리안 2021. 6. 15.

Map 컬랙션은 키(Key)와 값(Value)으로 구성된 Entry객체를 저장하는 구조를 가지고 있다. 

키와 값은 모두 객체이다. 키는 중복될수 없지만 값은 중복 될수 있다. 

만약에 기존에 저장된 키와 동일한 키로 값을 저장하면 기존의 값은 없어지고 새로운 값으로 대치 된다. 

 

Map 컬랙션의 대표

  • HashMap
  • HashTable
  • LinkedHashMap 
  • Properties
  • TreeMap

매개 변수 타입과 리턴 타입에 K와 V라는 타입 파라미터가 있는데, 이것은 Map 인터페이스가 제네릭 타입이기 때문

 

객체 추가는 put() 메소드를 사용 
키로 객체를 찾아올 때에는 get()메소드를 사용

객체 삭제는 remove() 메소드를 사용한다. 

 

키를 알고 있다면 get()메소드로 간단하게 객체를 찾아오지만 저장된 전체 객체를 대상으로 하나씩 얻고 싶을 경우는 2가지 방법을 사용할 수 있다. 

 

  1. KeySet() 메소드로 모든 키를 Set 컬렉션으로 얻은 다음 반복자를 통해 키를 하나씩 얻고 get() 메소드를 통해 값을 얻으면 된다.

 

  1.  entrySet() 메소드로 모든 Map.Entry를 Set 컬랙션으로 얻은 다음, 반복자를 통해 Map.Entry를 하나씩 얻고           getKey()와  getValue() 메소드를 이용해 키와 값을 얻으면 된다.  

HashMap 

HashMap의 키로 사용할 객체를 hashCode()와 equals() 메소드를 재정의해서 동등객체가 될 조건을 정해야 한다.

 

Map<K, V> map = new HashMap<K, V>();

 

package Part15_프레임워크.HashMap;

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

public class HashMapExample {
    public static void main(String[] args){
        //Map 컬랙션 생성
        Map<String, Integer> map = new HashMap<>();

        //객체 저장
        map.put("최민준", 85);
        map.put("김민준", 90);
        map.put("이민준", 80);
        map.put("박민준", 95);
        System.out.println("총 Entry 수 : " +map.size());
        System.out.println();

        //객체 찾기
        System.out.println("\t최민준 > "+map.get("최민준"));
        System.out.println();
        
        //객체를 하나씩 처리
        Set<String> keySet = map.keySet();
        Iterator<String> keyIterator = keySet.iterator(); 
        // Iterator : 전체 객체를 대상으로 한번씩 반복해서 가져오는 반복자
        
        while (keyIterator.hasNext()){
            //hashNext - 가져올 객체가 있으면 true를 리턴 없으면 false를 리턴
            String key = keyIterator.next();
            //객체를 하나씩 가져올떄는 next() 사용 
            Integer value = map.get(key);
            System.out.println("\t" + key + " : " +value);
        }
        System.out.println();
        
        //객체 삭제
        map.remove("최민준");
        System.out.println("총 Entry 수 : " +map.size());

        //객체를 하나씩 처리
        Set<Map.Entry<String, Integer>> entrySet = map.entrySet();
        //map.entrySet는 map.entrySet 얻기 위해 선언 한것
        Iterator<Map.Entry<String, Integer>> entryIterator = entrySet.iterator();

        while (entryIterator.hasNext()){
            Map.Entry<String, Integer> entry = entryIterator.next();
            String key = entry.getKey();
            Integer value = entry.getValue();
            System.out.println("\t" + key + " : " + value);
        }
        System.out.println();
    }
}

 

 

학번과 이름이 동일한 Student를 동등 키로 간주하기 위해 Student 클래스에는 hashCode()와 equals() 메소드가 재정의 

 

 

package HashMap;

class Student {
    public int sno;
    public String name;

    public Student(int sno, String name){
        this.sno = sno;
        this.name = name;
    }

    public boolean equals(Object obj){ // 학번과 이름이 동일한 경우 true를 리턴
        if(obj instanceof Student) {
            Student student = (Student) obj;
            return (sno == student.sno) && (name == student.name);
        }else {
            return false;
        }
    }

    public int hashCode(){ // 학번과 이름이 같다면 동일한 값을 리턴
        return sno + name.hashCode();
    }
}

 

package HashMap;

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

public class HashMapExample2 {
    public static  void  main(String[] args){
        Map<Student ,Integer> map = new HashMap<>();
        //질문

        map.put(new Student(1, "최준"), 95);
        map.put(new Student(2, "김준"), 91);

        System.out.println("책에서 확인한 부분");
        System.out.println("*********************");
        System.out.println("총 Entry 수 : " +map.size());
        System.out.println("*********************");
        System.out.println(" ** 추가 부분 ** ");
        System.out.println("*********************");

        for(Student s : map.keySet()){
            System.out.println("Key값 : "+s.name +" > "+ s.sno);
        }

        for(Map.Entry<Student, Integer> v : map.entrySet()){
            System.out.println("value값 : " + v.getValue());
        }
    }
}

 

 


HashTable

HashTable은 HashMap과 동일한 내부 구조를 가지고 있다. 

멀티 스레드가 동시에 이 메소드를 실행할 수는 없고, 하나의 스레드가 실행을 완료해야만 다른 스레드를 실행 할 수 있다. 

멀티 스레드 환경에서 안전하게 객체를 추가, 삭제할 수 있다. 이것을 스레드가 안전(thread safe)하다 라고 함

 

Map<K, V>map = new Hashtable<K, V>();

키로 String타입을 사용하고, 값으로 Integer타입을 사용하는 Hashtable은 밑과 같이 생성

Map<String, Integer>map = new Hashtable<String, Integer>();

 

 

package Part15_프레임워크.Hashtable;

import java.util.Hashtable;
import java.util.Map;
import java.util.Scanner;

public class HashTableExample {
    public static void main(String[] args){
        Map<String, String> map = new Hashtable<String, String>();

        map.put("spring", "12");
        map.put("summer", "123");
        map.put("fall", "1234");
        map.put("winter", "12345");

        Scanner scanner = new Scanner(System.in);

        while (true){
            System.out.println("아이디와 비번을 입력");
            System.out.println("아이디 > ");
            String id = scanner.nextLine(); // 키보드로부터 입력된 아이디를 읽는다.

            System.out.println("버번 입력 > ");
            String password = scanner.nextLine();
            System.out.println();
            
            if(map.containsKey(id)){        // 아이디인 키가 존재하는지 확인
                if(map.get(id).equals(password)){
                    System.out.println("로그인 되었습니다.");
                    break;
                }else{
                    System.out.println("비번이 일치 ㄴㄴ");
                }
            }else {
                System.out.println("입력하신 아이디가 없음");
            }
        }
    }
}


검색기능을 강화시킨 컬랙션

이진 트리 구조

이진트리는 여러 개의 노드가 트리 형태로 연결된 구조로 루트 노드(Root node)라고 불리는 하나의 노드에서 부터 시작해서 각 노드에 최대 2개의 노드를 연결할 수 있는 구조를 가지고 있다. 

 

사진 참고 :

https://velog.io/@keum0821/%ED%8A%B8%EB%A6%AC%EC%9D%98-%EA%B0%9C%EB%85%90%EA%B3%BC-%EC%9D%B4%EC%A7%84-%ED%8A%B8%EB%A6%AC

 

트리의 개념과 이진 트리

트리(Tree)란, 배열, 링크드리스트, 스택, 큐와 같이 일직선 개념의 자료구조가 아니라 부모-자식 개념을 가지는 자료구조이다.(출처 : 위키피디아)트리는 위 그림처럼 표현이 되는 자료구조인데,

velog.io

 

TreeSet

TreeSet은 이진 트리를 기반으로한 Set컬랙션이다. 하나의 노드는 노드값인 Value와 왼쪽과 오른쪽 자식 노드를 참조하기 위한 두 개의 변수로 구성된다. TreeSet에 객체를 저장하면 자동으로 정렬되는데 부모값과 비교해서 낮은 것은 왼쪽 자식 노드에, 높은 것은 오른쪽 자식 노드에 저장한다. 

 

Map<String> treeSet = new TreeSet<>();

 

package Part15_프레임워크.TreeSet;

import java.util.TreeSet;

public class TreeSetExample1 {
    public static void main(String[] args){
        TreeSet<Integer> scores = new TreeSet<>();
        scores.add(new Integer(87));
        scores.add(new Integer(98));
        scores.add(new Integer(75));
        scores.add(new Integer(95));
        scores.add(new Integer(80));

        Integer score = null;

        score = scores.first();
        System.out.println("가장 낮은 점수 : " +score);

        score = scores.last();
        System.out.println("가장 높은 점수 : " +score);

        score = scores.lower(new Integer(95));
        System.out.println("95점 아래 점수 : " +score);

        score = scores.higher(new Integer(95));
        System.out.println("95점 윗 점수 : " +score);

        score = scores.floor(new Integer(95));
        System.out.println("95점 이거나 바로 아래 점수 : " +score);

        score = scores.ceiling(new Integer(85));
        System.out.println("85점 이거나 바로 위의 점수 : " +score);

        while (!scores.isEmpty()){
            score = scores.pollFirst();
            System.out.println(score + "(남은 객체 수 : " +scores.size() + ")");
        }
    }
}

 

 


TreeMap

TreeMap은 이진트리를 기반으로 한 Map컬렉션이다.

TreeSet과의 차이점은 키와 값이 저장된 Map.Entry를 저장한다는 점이다. TreeMap에 객체를 저장하면 자동으로 정렬되는데, 기본적으로 부모 키값과 비교해서 키 값이 낮은 것은 왼쪽 자식노드에, 키 값이 높은것은 오른쪽 자식 노드에 Map.Entry객체를 저장한다. 

 

package Part15_프레임워크.TreeMap;

import java.util.Map;
import java.util.TreeMap;

public class TreeMapExample {
    public static void main(String[] args) {
        TreeMap<Integer, String> scores = new TreeMap<>();
        scores.put(new Integer(87), "최민준");
        scores.put(new Integer(98), "이민준");
        scores.put(new Integer(75), "박민준");
        scores.put(new Integer(95), "정민준");
        scores.put(new Integer(80), "김민준");

        Map.Entry<Integer, String> entry = null;

        entry = scores.firstEntry();
        System.out.println("가장 낮은 점수 > " + entry.getKey() + "-" + entry.getValue());

        entry = scores.lastEntry();
        System.out.println("가장 높은 점수 > " + entry.getKey() + "-" + entry.getValue());

        entry = scores.lowerEntry(new Integer(95));
        System.out.println("95점 아래 점수 > " + entry.getKey() + "-" + entry.getValue());

        entry = scores.higherEntry(new Integer(95));
        System.out.println("95점 위 점수 > "+entry.getKey() + "-" +entry.getValue());

        entry = scores.floorEntry(new Integer(95));
        System.out.println("95점 이거나 바로 아래 점수 > "+entry.getKey() + "-" +entry.getValue());

        while (!scores.isEmpty()){
            entry = scores.pollFirstEntry();
            System.out.println(entry.getKey() + "-" +entry.getValue() + "(남은 객체 수 > "+scores.size() +")" );
        }
    }
}

 

 

'개발 > Java collection framework' 카테고리의 다른 글

[Java] LIFO와 FIFO 컬랙션  (0) 2021.06.15
[JAVA] Set 컬랙션  (0) 2021.06.15
[Java] List 컬랙션  (0) 2021.06.11
[Java] 컬렉션 프레임 워크란  (0) 2021.06.11