CF_11_HashMap, TreeMap 클래스

charl hi·2021년 9월 22일
0

JAVA_CF

목록 보기
11/12

TreeMap

  • 범위 검색과 정렬에 유리한 컬렉션 클래스(이진탐색트리 사용)
  • HashMap보다 데이터 추가, 삭제에 시간이 더 걸린다.


HashMap

  • Map 인터페이스를 구현하는 대표적인 컬렉션 클래스

  • 해싱(hashing)기법으로 데이터를 저장. 데이터가 많아도 검색이 빠르다.

  • 데이터를 키 & 값(key & value)의 쌍 = Entry[] 으로 저장

  • ✨✨순서X, 중복(키X, 값O)

  • Hashmap(동기화X), Hashtable(동기화O, 구버전)의 신버전

  • 순서를 유지하려면 LinkedHashMap클래스를 사용!



해싱(hashing)

  • 해싱 : 해시함수 를 이용하여 데이터를 저장하고 읽어오는 것

  • 해시 함수 : key를 받으면 해시함수가 해시코드를 알려준다.

  • 해시 코드 : ✨저장위치, ✨배열의 index

  • 예) 환자정보관리(연대별로 정보를 구분한 뒤, 주민번호를 받으면 해시함수가 7 이라는 해시코드를 알려준다.)

  • 해싱기법 사용하는 클래스 : Hashtable, HashMap, HashSet

    • 따라서 hashcode()를 사용
    • 👀👀hashcode() 오버라이딩 방법??
      : 💖💖Objects.hash()

해시 함수(hash function)

  • 해시 함수 : key를 받으면 해시함수가 해시코드를 알려준다.
    : ✨항상 같은 key를 받으면 같은 해시코드를 반환한다.
    : 해시함수로 해시테이블에 데이터를 저장, 검색

  • 💖💖Objects.hash() 를 사용하여 hashcode()를 오버라이딩 한다.


해시 테이블(hash table)

  • 오른쪽이 해시테이블!!

  • 배열 + 링크드리스트가 조합된 형태
  • 배열의 장점(높은 접근성 : 인덱스만 알면 바로 접근가능) + 링크드리스트의 장점(변경에 유리)

해시테이블에 저장 & 읽어오는 과정

저장

HashMap map = new HashMap();
map.push("myID", "1234");
map.push("abcd", "1111");
map.push("abcd", "1234");
...
myID - 1234
abcd - 1234
  • map.push

읽어오기

  1. 키로 해시함수를 호출해서 해시코드를 얻는다.
  2. 해시코드(해시함수의 반환값)에 대응하는 링크드리스트를 배열에서 찾는다.
  3. 링크드리스트에서 키와 일치하는 데이터를 찾는다.
  • ✨해시함수는 같은 키에 대해 항상 같은 해시코드를 반환해야 한다.
  • 서로 다른 키일이자도 같은 값의 해시코드를 반환할 수도 있다.


생성자

  1. HashMap()

  2. HashMap(Map m)

  • 맵 m을 HashMap으로 바꿀 때?
  1. HashMap(int initialCapacity)
  • initialCapacity : 배열의 길이. 초기용량
  1. HashMap(int initialCapacity, float loadFactor)
  • loadFactor : 언제 용량을 ?배로 늘릴 건지에 대한 기준


메소드

추가

  1. Object put(Object key, Object value)
  • 객체 key, value의 한 쌍 저장
  1. void putAll(Map m)
  • 지정된 맵 m의 모든 요소들(객체들)을 저장

삭제

  1. Object remove(Object key)
  • 지정된 key로 저장된 값(객체) 제거
  1. void clear()
  • 해시맵에 장된 모든 객체 제거

변경

  1. Object replace(Object key, Object value)
  • 지정된 key의 값(value)을 지정된 객체 value로 바꾸기
  1. boolean replace(Object key, Object oldValue, Object newValue)
  • 지정된 키와 객체(oldValue)가 모두 일치하는 경우에만 새로운 객체(newValue)로 변경
  • 지정된 객체 key의 값 oldValue를 지정된 객체 newValue로 바꾸기

읽어오기

  1. ✨✨Set entrySet()
  • (해시)맵에 저장된 키와 값 쌍을 ✨Map.Entry타입의 객체✨로 저장한 Set으로 반환
  1. ✨✨Set keySet()
  • (해시)맵에 저장된 모든 키 객체들을 Set에 저장해서 반환
  1. ✨✨Collection values()
  • (해시)맵에 저장된 모든 value 객체들을 컬렉션 형태로 반환
  • 해시맵에 저장된 모든 값을 컬렉션 형태로 반환

검색

  1. boolean containsKey(Object key)
  • 맵이 객체 key를 갖고있는지 묻기
  • 참이면 true, 아니면 false
  1. boolean containsValue(Object value)
  • 맵이 객체 value에 대응되는 key를 하나이상 갖고있는지 묻기
  • 참이면 true, 아니면 false

반환

  1. Object get(Object key)
  • 지정된 key에 대응하는 value객체를 찾아 반환
  • 못찾으면 null 반환
  1. Object getOrDefault(Object key, Object defaultValue)
  • 지정된 key의 값(객체value)을 반환
  • key를 못찾으면 -> 기본값 defaultValue로 지정된 객체를 반환

기타

  1. boolean isEmpty()
  • 비어있는지 확인. 비어있으면 true, 차있으면 false
  1. int size()
  • 저장된 객체의 개수 반환
  1. Object clone()
  • 복제


key 일치 후 value 일치

ex11_16

import java.util.HashMap;
import java.util.Scanner;

public class Ex11_16 {

	public static void main(String[] args) {
		HashMap map = new HashMap();
		map.put("myID", "1234");
		map.put("asdf", "1111");
		System.out.println(map);
		map.put("asdf", "1234");
		System.out.println(map);
		
		Scanner sc = new Scanner(System.in);
		
		while(true) {
			System.out.println("id와 password를 입력해주세요.");
			System.out.print("id : ");
			String id = sc.nextLine().trim();	//String 앞뒤 공백제거
			System.out.print("password : ");
			String password = sc.nextLine().trim();
			
			//***key일치 확인 : equals가 아닌 containsKey!!
			//boolean equals(Object o) 맵과 o과 같은지 비교 이므로 안됨!!
			if(!map.containsKey(id)) {
				System.out.println("입력하신 id는 존재하지 않습니다. 다시 입력해주세요.");
				continue;	//***반복문 끝으로 가고 다시 다음 반복으로
			}
			
			//*****key를 반환하고 난 다음에 해당 key의 짝꿍value비교!!! 
			//이럴땐 containsValue하면 안된다!!
			//***value일치 확인 : key일치 확인 후 -> equals
			if(!(map.get(id)).equals(password)) {
				System.out.println("password가 일치하지 않습니다. 다시 입력해주세요.");
			} else {
				System.out.println("id와 password가 일치합니다.");
				System.out.println("로그인 성공 ... WELCOME!!");
				break;	//반복문 나가기
			}
		}

	}

}



✨✨entry/key/value 읽어오기

✨✨entry 읽어오기

ex11_17

Map & Iterator

map에서 iterator 사용방법

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 Ex11_17 {

	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));
		
		System.out.println(map);
		
		//***cf_06 iterator로 읽어오기
		Set set = map.entrySet();
        //***쌍으로
        System.out.println(set);
		Iterator it = set.iterator();
		//아래는 위의 두줄을 줄인 것
		//Iterator it = map.entrySet().iterator();
		
		while(it.hasNext()) {
			//*****이거 잘 모르겠다. 묶음entry로 받아야하는데
			//Map인터페이스 내부의 Entry인터페이스
			//인터페이스안에 선언된 내부클래스나 인터페이스는 모두 static이라 바로 호출 가능
			//이전에 list와set에선 : Object obj = it.next();이렇게 받았는데 얜 Entry니까
			//(Map.Entry)형변환이 필요하다.
			Map.Entry e = (Map.Entry)it.next();
			System.out.println("이름 : "+e.getKey()+", 점수 : "+e.getValue());
		}
		
		//***key들만
		set = map.keySet();
		System.out.println("참가자 명단 : "+set);
		
		//***value들만(Collection)
		Collection c = map.values();
		System.out.println("점수 모음 : "+c);
		
		it = c.iterator();
		//아래는 위의 두줄을 줄인 것
		//it = map.values().iterator();
		int total = 0;
		while(it.hasNext()) {
			Integer i = (Integer) it.next();
            total += i.intValue();
			//int i = (int)it.next(); 해도됨. 오토박싱
			//total += i;
		}
		
		System.out.println("총점 : "+total);
		System.out.println("평균 : "+(float)total/set.size());
		System.out.println("최고점수 : "+Collections.max(c));
		System.out.println("최저점수 : "+Collections.min(c));
		//**위의 max(), min()은 Comparable구현한 클래스객체만 들어올 수 있다!

	}

}

{안자바=90, 김자바=100, 강자바=90, 이자바=100}
[안자바=90, 김자바=100, 강자바=90, 이자바=100]
이름 : 안자바, 점수 : 90
이름 : 김자바, 점수 : 100
이름 : 강자바, 점수 : 90
이름 : 이자바, 점수 : 100
참가자 명단 : [안자바, 김자바, 강자바, 이자바]
점수 모음 : [90, 100, 90, 100]
총점 : 100
평균 : 25.0
최고점수 : 100
최저점수 : 90


ex11_18

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

public class Ex11_18 {

	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])) {
				int value = (int)map.get(data[i]);
				//get(Object key) : key에 대응하는 ***value반환이다***
				//**** 있으면 +1 
				map.put(data[i], value+1);
			}else {
				map.put(data[i], 1);
			}
		}
		//Set set = map.entrySet();
		Iterator it = map.entrySet().iterator();
		
		while(it.hasNext()) {
			Map.Entry e = (Map.Entry)it.next();
			int value = (int) e.getValue();
			System.out.println(e.getKey()+" : "+printBar('#', value)+" "+value);
		}

	}
	
	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);
		//***String(char[] chArr) 라는 생성자가 있음!!!
	}

}

A : ### 3
D : ## 2
Z : # 1
K : ###### 6



Ref

0개의 댓글