Study/수업 내용 정리

Collection - Set / Map < 2021-10-05 >

뱅코더 2021. 10. 5. 22:45

목차

  • Collection - Set
  • Collection - Map

Set

- 순서가 없다 ( → 인덱스가 없다 )

- 중복 데이터(객체) 저장 불가(null도 1개만 저장 가능)

- 일반적인 Set에서 중복 데이터 확인을 위해 equals()가 반드시 오버라이딩 되어있어야 한다.

- HashSet, LinkedHashSet, TreeSet

 

* HashSet

- hash 함수를 이용해서 데이터를 저장하고 빠른 검색이 가능한 Set

 

* hash 함수란?

-> 입력된 단어를 지정된 길이의 문자열로 변환하는 함수

 

* hashCode() 메서드

- hash 함수를 이용해 데이터가 다르면 중복되지 않는 숫자를 만드는 메서드

 

* HashSet 사용 선행 조건

1) Set에 저장되는 객체에 equals()가 오버라이딩 되어 있어야 한다.

2) hashCode()도 오버라이딩 해야한다.

 



// String을 이용한 HashSet 예제
// -> 자바 제공 클래스는 기본적으로 equals()와 hashCode() 등 메서드가 작성되어 있는 경우가 많다.

Set<String> set = new HashSet<String>();

set.add("수박");
set.add(new String("사과"));
set.add(new String("포도"));
set.add(new String("딸기"));
set.add(new String("배"));
set.add(new String("포도"));

System.out.println("저장된 데이터 개수 : " + set.size());
// 데이터를 6개 추가했지만 5개만 출력
// -> 중복 데이터를 저장할 수 없기 때문

System.out.println(set.toString());
// 순서가 없기 때문에 입력한 순서대로 출력되지 않는다.

 

* Set에서 값을 하나씩 반복해서 접근하기

-> 순서가 없기 때문에 (Index 존재 X) 원하는 데이터를 하나씩 꺼내는 것이 불가능함.

 

방법 1)

* Iterator (반복자)

- 컬렉션에서 제공하는 객체 반복 접근자(하나씩 반복 접근)

방법 2)

* 향상된 for문 사용

- for( 값을 하나씩 담을 변수 : 컬렉션 또는 배열명) {

 }

// Lotto 번호 생성기를 간단하게 만들고
// 생성된 번호를 하나씩 꺼내기

Set<Integer> lotto = new HashSet<Integer>();
		
		while(true) {
			
			int random = (int)(Math.random() * 45 + 1);	// 1~45 난수
			
			lotto.add(random);
			// add() 수행 중 중복 값이 추가되는 경우 자동으로 제거된다.
			
			if(lotto.size() == 6)
				// size() : 저장된 데이터의 개수 (크기 X)
				break;
		}
		
		System.out.println("생성된 번호 : " + lotto);
        
        
// 1) Iterator 이용하기

Iterator<Integer> it = lotto.iterator();
		// * lotto.iterator() 
		//-> lotto 집합(Set)에 저장된 내용들을 하나씩 꺼내올 수 있는 형태로 변환 
		
		while(it.hasNext()) {
			// hasNext() : 다음 꺼내올 값이 있으면 true
			
			int num = it.next();	// Integer -> int (auto unboxing)
			// next() : 다음 값을 얻어옴.
			
			System.out.println("발생한 랜덤 값 : " + num);
		}
     
     
// 2) for문 사용

System.out.println("===========================");
		System.out.println("< 향상된 for문 사용 >");
		for(int num : lotto) {
			System.out.println("발생한 랜덤 값 : " + num);
		}

 

* TreeSet 

- 이진 트리 구조를 이용해 데이터를 저장하는 Set

- Binary Tree 특징 : 오름차순 자동 정렬

 

// TreeSet을 이용해 오름차순으로 숫자를 정렬하기

Set<Integer> lotto = new TreeSet<Integer>();
		
		while(true) {
			
			// 1~ 45 난수 생성
			int random = (int)(Math.random() * 45 + 1);
			
			// 난수 추가
			lotto.add(random);
			
			if(lotto.size() == 6)	// 번호가 6개가 되면 break;
				break;
		}
		
		System.out.println("자동 생성된 번호 : " + lotto);
        
// 출력 예시
// 자동 생성된 번호 : [6, 7, 18, 31, 36, 44]

Map

- Key + Value 한 쌍이 데이터가 되어 이를 모아둔 객체

- Key : 중복 허용 X , 순서 없음 -> Set 특징

- Value : Key에 의해 구분되기 때문에 중복 가능 -> List 특징

 

* HashMap<K, V>

- Java Map 중 가장 기초

- Key에 해당하는 객체는 equals(), hashCode() 오버라이딩 필수

 

* Map에서 데이터에 하나씩 접근하는 방법

Map<Integer, String> map = new HashMap<>(); 
				// == 타입 추론 기능 (제네릭을 적지 않아도 알아서 인식)
		
		map.put(1, "치킨");
		map.put(2, "피자");
		map.put(3, "김밥");
		map.put(4, "냉면");
		map.put(5, "떡볶이");
		map.put(6, "햄버거");
        
// get(key) : 매개 변수로 작성된 key와 매핑되는 value를 반환함
		System.out.println(map.get(3));	// 피자
		System.out.println(map.get(5));	// 떡볶이

* 모든 요소 반복 접근하기

// 1. Iterator 사용
		
		// 1) map에서 key만 모아둔 집합(Set)을 얻어오는 메서드인 keySet() 호출
		Set<Integer> set = map.keySet();

		// 2) 얻어온 set을 반복 접근하기 위한 Iterator로 변경
		Iterator<Integer> it = set.iterator();
		
		// 3) while문을 통해 반복 접근
		while(it.hasNext()) {
			
			// 4) 다음 접근한 key를 얻어와 변수에 저장
			int key = it.next();
			
			// 5) get(key) 메서드를 이용해서 Value를 얻어와 출력
			System.out.printf("key : %d , value : %s \n", key , map.get(key) );
		}
		
		// 2. 향상된 for문 사용
		// - keySet()으로 key 뽑아내기
		// - 향상된 for문으로 반복 접근
		System.out.println("==============================");
		
		Set<Integer> set2 = map.keySet();
		
		for(int key : set2) {
			
			System.out.printf("key : %d , value : %s \n", key , map.get(key) );
		}
		
	}