프로그래밍/자바(java) 융합개발자 2차

[자바 9일차] 28일차 - 컬렉션 프레임워크 (p.404~447)

aSpring 2021. 1. 22. 16:08
728x90
728x90

2021/01/20 - [공부/자바(java) 융합개발자 2차] - [자바 7일차] 26일차 - 상속, 추상클래스, 추상메서드 , 인터페이스(Do it 공부단 p.234~)

2021/01/21 - [공부/자바(java) 융합개발자 2차] - [자바 8일차] 27일차 -


제네릭 : 오브젝으로 자료 구조를 접근하게 되면 번거로움

ArrayList<Student> 처럼

- ArrayList : 자바가 미리 만들어 높은 것

Person<T>

- <> 안이 Student인지 뭔지 정할 수 없다면 정의하지 말고 비워두거나

- <T>, <E> 처럼 임의로 적어줌

 

Collection p.404

- List : 순서 있음, 중복 허용

- Set : 순서 없음, 중복 허용  안함

=> 원소 1개씩 가짐

======

- Map

예) 사전 : 순서 없음(순서가 의미가 없다는 뜻), 중복 허용 안함

apple 찾고싶다 ---> '사과'라는 의미를 찾기 위해 apple에 접근함

Map은 key값과 value 두 개로 이루어짐 => 원소 2개씩 가짐

 

api > java.util > Interfaces > Map

Interfaces : 모두 추상으로 이루어져 있기 때문에 가져다 쓰는 쪽에서 구현해 주어야 한다

- 자바에서 이름만 정해둠

Classes에도 있다

- Hashtable<k, v> : 제네릭

 

com.day09

HashMapTest.java

특징 보기

package com.day09;

import java.util.HashMap;

public class HashMapTest {

	public static void main(String[] args) {
		HashMap<String, String> hm = new HashMap<>();
		hm.put("one", "첫번째");
		hm.put("two", "두번째");
		hm.put("three", "세번째");
		hm.put("four", "네번째");
		System.out.println(hm);
	}
}

{four=네번째, one=첫번째, two=두번째, three=세번째}

- 순서대로 나오란 법은 없다(순서는 의미 없다). HashMap은 그냥 들어있는 p와 value를 이런식으로 출력해준다.

package com.day09;

import java.util.HashMap;

public class HashMapTest {

	public static void main(String[] args) {
		HashMap<String, String> hm = new HashMap<>();
		hm.put("one", "첫번째");
		hm.put("two", "두번째");
		hm.put("three", "세번째");
		hm.put("four", "네번째");
		System.out.println(hm);
		hm.put("four", "네번째다");
		System.out.println(hm);
	}
}

{four=네번째, one=첫번째, two=두번째, three=세번째}
{four=네번째다, one=첫번째, two=두번째, three=세번째}

 

기존의 four 없어지고 마지막에 집어넣은 four, 네번째다 가 출력됨 -> 덮어쓰기 된다

-> four가 중복되어 들어갔다 : 중복 value가 아니라 key 기준 -> 중복을 허용하지 않으므로 크기는 5가 아닌 여전히 4.

 

package com.day09;

import java.util.HashMap;

public class HashMapTest {

	public static void main(String[] args) {
		HashMap<String, String> hm = new HashMap<>();
		hm.put("one", "첫번째");
		hm.put("two", "두번째");
		hm.put("three", "세번째");
		hm.put("four", "네번째");
		System.out.println(hm);
		hm.put("four", "네번째다");
		System.out.println(hm);
		System.out.println(hm.size()); //길이 :  length가 아닌 size를 쓴다.
		hm.put("oneone", "첫번째"); //value 중복되게 적어줘보자
		System.out.println(hm); //바뀌는게 아니라 추가가 된다.
	}
}

{four=네번째, one=첫번째, two=두번째, three=세번째}
{four=네번째다, one=첫번째, two=두번째, three=세번째}
4
{four=네번째다, one=첫번째, oneone=첫번째, two=두번째, three=세번째}

 

value는 의미 없다. key가 같은가만 신경씀,

oneone 추가됨

package com.day09;

import java.util.HashMap;

public class HashMapTest {

	public static void main(String[] args) {
		HashMap<String, String> hm = new HashMap<>();
		hm.put("one", "첫번째");
		hm.put("two", "두번째");
		hm.put("three", "세번째");
		hm.put("four", "네번째");
		System.out.println(hm);
		hm.put("four", "네번째다");
		System.out.println(hm);
		System.out.println(hm.size()); //길이 :  length가 아닌 size를 쓴다.
		hm.put("oneone", "첫번째"); //value 중복되게 적어줘보자
		System.out.println(hm); //바뀌는게 아니라 추가가 된다.
		System.out.println(hm.size());
		//theree를 가져오고 싶다
		System.out.println(hm.get("three")); //get(key값); 안에 key값을 넣게 되면 value값을 알려준다
	}
}

{four=네번째, one=첫번째, two=두번째, three=세번째}
{four=네번째다, one=첫번째, two=두번째, three=세번째}
4
{four=네번째다, one=첫번째, oneone=첫번째, two=두번째, three=세번째}
5
세번째 -> get(key); key값을 집어넣으면 value값을 알려준다.

 

 

어떻게 h라는 맵을 정의/생성해야 "1", "딸기"처럼 집어넣을 수 있는지 생각해보자.

{1=딸기, 2=사과, 3=포도, 4=바나나}

 

- value값만 출력하고싶다(즉, 과일 이름만, 딸기, 사과, 포도, 바나나만)

	HashMap<String, String> h = new HashMap<>(); //h라는 맵 정의, 생성
		h.put("1","딸기"); //
		h.put("2","사과");
		h.put("3","포도");
		h.put("4","바나나");
		//h 출력
		System.out.println(h);
		//value값만 출력 - 즉, 딸기, 사과, 포도, 바나나만 찍어달라
		System.out.println(h.get("1"));
		System.out.println(h.get("2"));
		System.out.println(h.get("3"));
		System.out.println(h.get("4"));
		//또는
		for(int i = 0; i < h.size(); i++) {
			
		}

{1=딸기, 2=사과, 3=포도, 4=바나나}
딸기
사과
포도
바나나

지금 i는 숫자형, "1", "2", "3", "4"는 문자형

 

아래가 제일 간단하지않나?

HashMap<String, String> h = new HashMap<>(); //h라는 맵 정의, 생성
		h.put("1","딸기"); //
		h.put("2","사과");
		h.put("3","포도");
		h.put("4","바나나");
		//h 출력
		System.out.println(h);
		//value값만 출력 - 즉, 딸기, 사과, 포도, 바나나만 찍어달라
		System.out.println(h.values());

{1=딸기, 2=사과, 3=포도, 4=바나나}  -> System.out.println(h);
[딸기, 사과, 포도, 바나나] -> System.out.println(h.values());

- value 값은 다 나오는데 순서는 의미가 없으므로 어떤 순서 없이 그냥 막 나옴

- 왜 딸기가 먼저 나오지? 의문을 안가져도 됨 그냥 아~ value값이 출력되네~(순서 의미 X)

- 만약 정렬을 해야하면 정렬하는 것을 써주면 됨

 

//h라는 해쉬맴에서 키값에서 "1"이 있나요?

//h 라는 해쉬맴에서 value값에 "바나나"가 있나요?

package com.day09;

import java.util.HashMap;

public class HashMapTest {

	public static void main(String[] args) {
		HashMap<String, String> hm = new HashMap<>();
		hm.put("one", "첫번째");
		hm.put("two", "두번째");
		hm.put("three", "세번째");
		hm.put("four", "네번째");
		System.out.println(hm);
		hm.put("four", "네번째다");
		System.out.println(hm);
		System.out.println(hm.size()); //길이 :  length가 아닌 size를 쓴다.
		hm.put("oneone", "첫번째"); //value 중복되게 적어줘보자
		System.out.println(hm); //바뀌는게 아니라 추가가 된다.
		System.out.println(hm.size());
		//theree를 가져오고 싶다
		System.out.println(hm.get("three")); //get(key값); 안에 key값을 넣게 되면 value값을 알려준다
		
		HashMap<String, String> h = new HashMap<>(); //h라는 맵 정의, 생성
		h.put("1","딸기"); //
		h.put("2","사과");
		h.put("3","포도");
		h.put("4","바나나");
		//h 출력
		System.out.println(h);
		//value값만 출력 - 즉, 딸기, 사과, 포도, 바나나만 찍어달라
		System.out.println(h.get("1"));
		System.out.println(h.get("2"));
		System.out.println(h.get("3"));
		System.out.println(h.get("4"));
		//위와 같이 항상 써줄수는 없다
		for(int i = 1; i <= h.size(); i++) {
			System.out.println(h.get(i+"")); //문자형으로 바꿔주기 - 방법1
		}
		System.out.println("==============");
		for(int i = 1; i <= h.size(); i++) {
			System.out.println(h.get(String.valueOf(i))); //문자형으로 바꿔주기 - 방법2
		}
		System.out.println("==============");
		//values() 이용
		for(String value : h.values()) { //values()는 amp에서 value값 전체 리턴
			System.out.println(value);
		}
		//h 라는 해쉬맴에서 key값에서 "1"이 있나요?
		System.out.println(h.containsKey("1"));//있으면 true, 없으면 false라고 출력됨
		//h 라는 해쉬맴에서 value값에 "바나나"가 있나요?
		System.out.println(h.containsValue("바나나"));
	}
}

{four=네번째, one=첫번째, two=두번째, three=세번째}
{four=네번째다, one=첫번째, two=두번째, three=세번째}
4
{four=네번째다, one=첫번째, oneone=첫번째, two=두번째, three=세번째}
5
세번째
{1=딸기, 2=사과, 3=포도, 4=바나나}
딸기
사과
포도
바나나
딸기
사과
포도
바나나
==============
딸기
사과
포도
바나나
==============
딸기
사과
포도
바나나
true
true

 

키 값만 출력

- 중복을 허용하지 않는 집합체  : set

 

 

- 아래처럼 하면 안되나..?

 

 

HashMapTest01.java

package com.day09;

public class HashMapTest01 {
		/*
		 * 1. 해쉬맵 hm 생성
		 * 2. 1~20 사이의 난수 발생(Math.random())
		 * 3. 난수 10개를 hm에 추가 단, value값 중복 허용 안됨
		 * [결과]
		 * 1 25
		 * 2 20
		 * 3 10
		 * .. 
		 * 이런식으로
		 */
         
	public static void main(String[] args) {
		
	}

}

 

-컬렉션 프레임웍 : 객체를 다룸 -> int는 객체가 아님 래퍼클래스 Integer로 써줘야 함

이렇게 까지 써주면 중복 발생

보기 편하게 만들어주기

 

- values 값을 오름차순으로 정렬하여 출력

sort() 안에는 List형이 들어가야 함

그러나,

values는 Collection 형임 -> List형으로 바꾸어 주기

//collection이 가지는 reverse라는 함수 사용해보기

import를 하나하나 안시켜주고 *로 한꺼번에 해주어도 되지만 굳이 이렇게 할 필요 없음

 

최소값, 최대값 구하기

package com.day09;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;

public class HashMapTest01 {
	/*
	 * 1. 해쉬맵 hm 생성 
	 * 2. 1~20 사이의 난수 발생(Math.random()) 
	 * 3. 난수 10개를 hm에 추가 단, value값 중복 허용 안됨 
	 * [결과] 1 25 2 20 3 10 .. 이런식으로
	 */

	public static void main(String[] args) {
		HashMap<Integer, Integer> hm = new HashMap();
		for (int i = 1; i <= 10; i++) {
			while (true) {
				int value = (int) (Math.random() * 20) + 1; // Math.randm()은 더블형이므로 강제 형 변환
				if (hm.containsValue(value) == false) { // 발생한 난수가 Map에 없으면 넣는다
					hm.put(i, value); // 래퍼클래스 hm.put(i, new Ineteger(value));
					break;
				} // if
			} // while
		} // for
		System.out.println(hm);
		System.out.println("===================");
		for(int value : hm.values()) {
			System.out.print(value + "\t");
		}
		System.out.println();
		//values 값을 오름차순으로 정렬하여 출력
		List<Integer> list = new ArrayList<>(hm.values()); //List형으로 변경
		Collections.sort(list);//sort()안에는 List형이 와야 함
		System.out.println("====정렬 후=====");
		for(int i : list) { //출력
			System.out.print(i + "\t");
		}
		//collection이 가지는 reverse라는 함수 사용해보기
		System.out.println("\n===========reverse===================");
		Collections.reverse(list);
		for(int i : list) { //출력
			System.out.print(i + "\t");
		}
		//최소값, 최대값 구하기
		System.out.println();
		System.out.println("최대값 : " + Collections.max(list));
		System.out.println("최소값 : " + Collections.min(list));
	}
}

{1=9, 2=14, 3=19, 4=18, 5=5, 6=15, 7=17, 8=13, 9=2, 10=6}
===================
9 14 19 18 5 15 17 13 2 6
====정렬 후=====
2 5 6 9 13 14 15 17 18 19
===========reverse===================
19 18 17 15 14 13 9 6 5 2
최대값 : 19
최소값 : 2

List 써도 되고, ArrayList 써도 된다. 부모가 List 이므로!

그러나 new 뒤에는 List가 올 수는 없음

sort 안에 List형이 와야된다고 해도 ArrayList의 부모가 List이므로 ArrayList도 가능하다

 

HashMapTest02.java

package com.day09;

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

public class HashMapTest02 {

	public static void main(String[] args) {
		HashMap<String, String> hm = new HashMap<>();
		hm.put("java", "1111");
		hm.put("oracle", "1234");
		hm.put("jsp", "abcd");
		Scanner sc = new Scanner(System.in);
		System.out.println("id/password를 입력하세요");
		// 입력하신 id는 없습니다.
		// 비밀번호가 일치하지 않습니다.
		// 모두 일치합니다.
	}
}

// id, pw를 입력 받고 상황에 따라 다음과 같이 출력

// 입력하신 id는 없습니다.
// 비밀번호가 일치하지 않습니다.
// 모두 일치합니다.

 

package com.day09;

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

public class HashMapTest02 {

	public static void main(String[] args) {
		HashMap<String, String> hm = new HashMap<>();
		hm.put("java", "1111");
		hm.put("oracle", "1234");
		hm.put("jsp", "abcd");
		Scanner sc = new Scanner(System.in);
		System.out.println("id/password를 입력하세요");
		// 입력하신 id는 없습니다.
		System.out.println("ID 입력 >>");
		String id = sc.next(); //java
		System.out.println("password 입력 >>");
		String password = sc.next(); //abcd -> map에 있긴 하지만 java의 비번이 abcd가 아니므로 모두 일치합니다 이렇게 나오면 곤란
		// id맵에 있는가?
		if(hm.containsKey(id) == false) { //id가 없는 경우 아래 출력
			System.out.println("입력하신 id는 없습니다.");
			return; //void 상태에서 return을 하면 종료의 의미, 아래 문장을 더 실행하지 않음
		} 
		if(hm.get(id).equals(password)) { // id에 맞는 비밀번호인지?
			System.out.println("모두 일치합니다.");
		} else { //id는 맞는데 비밀번호가 틀린 경우
			System.out.println("비밀번호가 일치하지 않습니다.");
		}
	}
}
id/password를 입력하세요
ID 입력 >>
dddd
password 입력 >>
fff
입력하신 id는 없습니다.
id/password를 입력하세요
ID 입력 >>
java
password 입력 >>
1234
비밀번호가 일치하지 않습니다.
id/password를 입력하세요
ID 입력 >>
java
password 입력 >>
1111
모두 일치합니다.
id/password를 입력하세요
ID 입력 >>
dddd
password 입력 >>
1111
입력하신 id는 없습니다.

 

HashMapTest03.java

package com.day09;

public class HashMapTest03 {
	/*
	 * 1. 해쉬맵 map 생성
	 * 2. 단어를 입력받아 단어와 횟수저장
	 * 3. 대소문자 구분없이 x 치면 종료
	 * 4. map 출력
	 * [출력 예시]
	 * 입력 : java java test test java test oracle database
	 * java 3 -> 문자와 문자가 몇번 적혔는지 갯수 저장, 출력
	 * test 3
	 * oracle 1
	 * database 1
	 */
	
	public static void main(String[] args) {
		

	}

}

==> 풀이

package com.day09;

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

public class HashMapTest03 {
	/*
	 * 1. 해쉬맵 map 생성
	 * 2. 단어를 입력받아 단어와 횟수저장
	 * 3. 대소문자 구분없이 x 치면 종료
	 * 4. map 출력
	 * [출력 예시]
	 * 입력 : java java test test java test oracle database
	 * java 3 -> 문자와 문자가 몇번 적혔는지 갯수 저장, 출력
	 * test 3
	 * oracle 1
	 * database 1
	 */
	
	public static void main(String[] args) {
		HashMap<String, Integer> map = new HashMap<>();
		Scanner sc = new Scanner(System.in); //단어 입력 받기 위해 필요
		while(true) { //x치면 종료니까 무한 루프 돌리기
			System.out.println("단어 입력 >> ");
			String word = sc.next();
			if(word.equalsIgnoreCase("x")) break; //x 또는 X이면 break
			int value;
			if(map.containsKey(word)) { //입력받은 단어가 이미 있으면 갯수 +1
				value = map.get(word)+1; // 원래의 갯수 +1
			} else { //입력받은 단어가 기존 입력 받은 것 중에 없으면
				value = 1; //없으면 1개있는 것
			}
			map.put(word, value);
		}
		System.out.println(map);
	}
}

단어 입력 >> 
aa bb cc dd aa dd ee
단어 입력 >> 
단어 입력 >> 
단어 입력 >> 
단어 입력 >> 
단어 입력 >> 
단어 입력 >> 
단어 입력 >> 
ccc x
단어 입력 >> 
{aa=2, bb=1, cc=1, dd=2, ee=1, ccc=1}

 

//삼항 연산자 : if에 걸리는 것이 한 줄밖에 없음

package com.day09;

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

public class HashMapTest03 {
	/*
	 * 1. 해쉬맵 map 생성
	 * 2. 단어를 입력받아 단어와 횟수저장
	 * 3. 대소문자 구분없이 x 치면 종료
	 * 4. map 출력
	 * [출력 예시]
	 * 입력 : java java test test java test oracle database
	 * java 3 -> 문자와 문자가 몇번 적혔는지 갯수 저장, 출력
	 * test 3
	 * oracle 1
	 * database 1
	 */
	
	public static void main(String[] args) {
		HashMap<String, Integer> map = new HashMap<>();
		Scanner sc = new Scanner(System.in); //단어 입력 받기 위해 필요
		while(true) { //x치면 종료니까 무한 루프 돌리기
			System.out.println("단어 입력 >> ");
			String word = sc.next();
			if(word.equalsIgnoreCase("x")) break; //x 또는 X이면 break
			int value;
			//if(map.containsKey(word)) { //입력받은 단어가 이미 있으면 갯수 +1
			//	value = map.get(word)+1; // 원래의 갯수 +1
			//} else { //입력받은 단어가 기존 입력 받은 것 중에 없으면
			//	value = 1; //없으면 1개있는 것
			//}
			//map.put(word, value);
			//위를 삼항연산자로 표현
			map.put(word, map.containsKey(word) == true? map.get(word)+1 : 1);
		}
		System.out.println(map);
		sc.close();
	}
}

단어 입력 >> 
java java test test java test oracle database
단어 입력 >> 
단어 입력 >> 
단어 입력 >> 
단어 입력 >> 
단어 입력 >> 
단어 입력 >> 
단어 입력 >> 
단어 입력 >> 
x
{database=1, java=3, oracle=1, test=3}

 

저거 단어 입력이 계속 나오는데.. 안나오게 할 수는 없을까?

 

HashStudent.java

package com.day09;

import java.util.HashMap;

class Person {
	private String id;
	private String tel;
	
	public Person (String id, String tel) {
		this.id = id;
		this.tel = tel;
	}
	//getter
	public String getId() {
		return id;
	}
	public String getTel() {
		return tel;
	}
	@Override
	public String toString() {
		return "Person [id=" + id + ", tel=" + tel + "]";
	}
}

public class HashStudent {
	HashMap<String, Person> map = new HashMap<>();	
	
}

package com.day09;

import java.util.HashMap;

class Person {
	private String id;
	private String tel;
	
	public Person (String id, String tel) {
		this.id = id;
		this.tel = tel;
	}
	//getter
	public String getId() {
		return id;
	}
	public String getTel() {
		return tel;
	}
	@Override
	public String toString() {
		return "Person [id=" + id + ", tel=" + tel + "]";
	}
}

public class HashStudent {
	
	public static void main(String[] args) {
		HashMap<String, Person> map = new HashMap<>(); //Person형이 들어감 -> 주소값을 찾아서 
		map.put("홍길동", new Person("1", "010-1111-1111"));
		map.put("이순신", new Person("2", "010-2222-2222"));
		map.put("강감찬", new Person("3", "010-3333-3333"));
		System.out.println(map);
	}
}

{홍길동=Person [id=1, tel=010-1111-1111], 강감찬=Person [id=3, tel=010-3333-3333], 이순신=Person [id=2, tel=010-2222-2222]}

 

package com.day09;

import java.util.HashMap;

class Person {
	private String id;
	private String tel;
	
	public Person (String id, String tel) {
		this.id = id;
		this.tel = tel;
	}
	//getter
	public String getId() {
		return id;
	}
	public String getTel() {
		return tel;
	}
	//@Override
	//public String toString() {
	//	return "Person [id=" + id + ", tel=" + tel + "]";
	//}
}

public class HashStudent {
	
	public static void main(String[] args) {
		HashMap<String, Person> map = new HashMap<>(); //Person형이 들어감 -> 주소값을 찾아서 
		map.put("홍길동", new Person("1", "010-1111-1111"));
		map.put("이순신", new Person("2", "010-2222-2222"));
		map.put("강감찬", new Person("3", "010-3333-3333"));
		System.out.println(map);
	}
}

오버라이딩 시켜주지 않으면 아래처럼 주소값을 출력해줌.

{홍길동=com.day09.Person@5594a1b5, 강감찬=com.day09.Person@6a5fc7f7, 이순신=com.day09.Person@3b6eb2ec}

 

//홍길동의 정보 출력

Person [id=1, tel=010-1111-1111]

 

//이순신의 정보 출력 -> 바로 출력하지 않고 정보를 p에 담아서 출력해보기

p는 Person형이다! 우리가 만든 객체도 연결해서 쓸 수 있다.

 

VectorTest.java

동기화 부분이 구현되어있는 것이 Vector.

ArrayList는 동기화가 구현되지 있지 않음

 

ArrayList와 같다고 보면 됨

package com.day09;

import java.util.Iterator;
import java.util.Vector;

public class VectorTest {

	public static void main(String[] args) {
		Vector<Integer> vc = new Vector<>();
		vc.add(5); //0번째에 5
		vc.add(new Integer(5)); //1번째에 5
		vc.add(-1); //2번째에 -1
		vc.add(2, 100); //위치값 2에 100 집어넣음 -> -1은 3으로 밀림
		for(Integer i : vc) {
			System.out.print(i + "\t");
		}
		System.out.println();
		//객체를 순회하면서 가져온다
		Iterator<Integer> it = vc.iterator(); //for문 대신에 쓸 수 있다.
		while(it.hasNext()) { //있는 동안 -> stringTokenizer처럼 이동하면 하나씩 줄어든다.
			System.out.println(it.next());
		}
	}
}

5   5   100   -1
5
5
100
-1

 

CapitalApp.java

==> 오류 없애기

package com.day09;

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

public class CapitalApp {
	static Scanner sc = new Scanner(System.in);
	private HashMap<String, String> map = new HashMap<>();
	//생성자
	public CapitalApp() { //문제 먼저 만들기
		map.put("한국", "서울");
		map.put("일본", "동경");
		map.put("중국", "베이징");
		map.put("미국", "워싱턴");
		map.put("영국", "런던");
		map.put("프랑스", "파리");
		map.put("독일", "베를린");
	}
	public static void showMenu() {
		System.out.println("=== 수도 맞추기 게임 ====");
		System.out.println("1.입력 2.퀴즈 3.종료 >>>");
	}
	public void input() {
		
	}
	public void quiz() {
		System.out.println(map);
	}

	public static void main(String[] args) {
		CapitalApp ca = new CapitalApp();
		while(true) {
			CapitalApp.showMenu();
			int choice = sc.nextInt();
			switch(choice) {
			case 1 : ca.input(); break;
			case 2 : ca.quiz(); break;
			case 3 : System.out.println("종료");
					System.exit(0);
			default : System.out.println("입력오류"); 
			}//switch
		}//while
	}//main
}//class

 

==> 여기까지 입력하고 실행시켜보기

 

=== 수도 맞추기 게임 ====
1.입력 2.퀴즈 3.종료 >>>
2
{프랑스=파리, 독일=베를린, 미국=워싱턴, 일본=동경, 영국=런던, 중국=베이징, 한국=서울}
=== 수도 맞추기 게임 ====
1.입력 2.퀴즈 3.종료 >>>

 

==> 해당 나라에 대한 수도만 맞다고 정답 처리해야됨

- 문제를 낼 때, key를 선택해서 뿌려주기 -> 차례대로? no. 일종의 문제 은행이므로 랜덤하게 뿌려주면 됨 -> 그러려면 순서를 달고 무작위로 뽑아야 함 -> map 은 순서가 의미가 없다고 했음 -> map으로는 구할 수 없으니 List로 바꾼 다음 랜덤으로 순서를 구하고 그 번호에 해당하는 나라를 출력해주어야 퀴즈 문제가 될 수 있다.

 

package com.day09;

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

public class CapitalApp {
	static Scanner sc = new Scanner(System.in);
	private HashMap<String, String> map = new HashMap<>();
	//생성자
	public CapitalApp() { //문제 먼저 만들기
		map.put("한국", "서울");
		map.put("일본", "동경");
		map.put("중국", "베이징");
		map.put("미국", "워싱턴");
		map.put("영국", "런던");
		map.put("프랑스", "파리");
		map.put("독일", "베를린");
	}
	public static void showMenu() {
		System.out.println("=== 수도 맞추기 게임 ====");
		System.out.println("1.입력 2.퀴즈 3.종료 >>>");
	}
	public void input() {
		
	}
	public void quiz() {
		//키값만 구하기
		Set<String> set = map.keySet(); //set은 값만 가지고 있는데 중복 허용 X -> 현재는 나라만 있음 -> 위치를 알아야 함
		//구한 키값만 set을 이용해 담기
		Object[] arr = set.toArray();//set을 Object[]의 배열로 바꿔줌 -> why? 순서가 필요하기 때문에
		while(true) {
			int r = (int)(Math.random()*map.size()); //0~배열의 길이만큼, 크기만큼의 난수 발생
			//arr[r]을 구해야 함
			String country = (String)arr[r]; //문제 낼 나라 0이면 한국 ~ 6이면 독일
			String sudo = map.get(country); //해당 나라(key값)에 대한 value(정답)을 sudo에 저장함 
			
			//문제 출제
			System.out.println(country + "의 수도는 (종료는x) ? ");
			String dap = sc.next(); //답을 dap에 입력받음
			if(dap.equalsIgnoreCase("x")) break; //x 또는 X 치면 종료
			if(sudo.equals(dap)) { //입력한 dap과 정답을 저장된 sudo가 일치하면
				System.out.println("정답!!!!"); //정답이라고 알려주고
			} else { //틀리면
				System.out.println("틀렸습니다"); //틀렸다고 알려줌
			}
		}
	}

	public static void main(String[] args) {
		CapitalApp ca = new CapitalApp();
		while(true) {
			CapitalApp.showMenu();
			int choice = sc.nextInt();
			switch(choice) {
			case 1 : ca.input(); break;
			case 2 : ca.quiz(); break;
			case 3 : System.out.println("종료");
					System.exit(0);
			default : System.out.println("입력오류"); 
			}//switch
		}//while
	}//main
}//class

=== 수도 맞추기 게임 ====
1.입력 2.퀴즈 3.종료 >>>
2
중국의 수도는 (종료는x) ? 
동경
틀렸습니다
미국의 수도는 (종료는x) ? 
워싱턴
정답!!!!
미국의 수도는 (종료는x) ? 
x
=== 수도 맞추기 게임 ====
1.입력 2.퀴즈 3.종료 >>>
3
종료

 

이제 input() -> 문제 출제임

먼저 현재 몇개의 문제가 입력되어있는지 알려주기

중복된 내용은 입력하지 않고, 이미 있다고 알려주기

 

package com.day09;

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

public class CapitalApp {
	static Scanner sc = new Scanner(System.in);
	private HashMap<String, String> map = new HashMap<>();
	//생성자
	public CapitalApp() { //문제 먼저 만들기
		map.put("한국", "서울");
		map.put("일본", "동경");
		map.put("중국", "베이징");
		map.put("미국", "워싱턴");
		map.put("영국", "런던");
		map.put("프랑스", "파리");
		map.put("독일", "베를린");
	}
	public static void showMenu() {
		System.out.println("=== 수도 맞추기 게임 ====");
		System.out.println("1.입력 2.퀴즈 3.종료 >>>");
	}
	public void input() {
		int n = map.size(); //현재 문제 갯수 알려주기
		System.out.println("현재 " + n + "개의 나라와 수도가 입력되어 있습니다.");
		while(true) {//얼마나 많이 입력할지 모르니 while
			System.out.println("나라, 수도 입력(종료는 x) >> ");
			String con = sc.next(); //입력받은 나라 이름을 con에 저장
			if(con.equalsIgnoreCase("x")) break; //x 또는 X이면 break함
			if(map.containsKey(con)) {//입력한 나라 con이 map에 이미 있으면
				System.out.println("이미 입력한 나라입니다.");
				continue; //수도 입력받지 않고 넘어감
			} 
			String capitcal = sc.next();//수도 입력
			map.put(con, capitcal);
		}
	}
	public void quiz() {
		//키값만 구하기
		Set<String> set = map.keySet(); //set은 값만 가지고 있는데 중복 허용 X -> 현재는 나라만 있음 -> 위치를 알아야 함
		//구한 키값만 set을 이용해 담기
		Object[] arr = set.toArray();//set을 Object[]의 배열로 바꿔줌 -> why? 순서가 필요하기 때문에
		while(true) {
			int r = (int)(Math.random()*map.size()); //0~배열의 길이만큼, 크기만큼의 난수 발생
			//arr[r]을 구해야 함
			String country = (String)arr[r]; //문제 낼 나라 0이면 한국 ~ 6이면 독일
			String sudo = map.get(country); //해당 나라(key값)에 대한 value(정답)을 sudo에 저장함 
			
			//문제 출제
			System.out.println(country + "의 수도는 (종료는x) ? ");
			String dap = sc.next(); //답을 dap에 입력받음
			if(dap.equalsIgnoreCase("x")) break; //x 또는 X 치면 종료
			if(sudo.equals(dap)) { //입력한 dap과 정답을 저장된 sudo가 일치하면
				System.out.println("정답!!!!"); //정답이라고 알려주고
			} else { //틀리면
				System.out.println("틀렸습니다"); //틀렸다고 알려줌
			}
		}
	}

	public static void main(String[] args) {
		CapitalApp ca = new CapitalApp();
		while(true) {
			CapitalApp.showMenu();
			int choice = sc.nextInt();
			switch(choice) {
			case 1 : ca.input(); break;
			case 2 : ca.quiz(); break;
			case 3 : System.out.println("종료");
					System.exit(0);
			default : System.out.println("입력오류"); 
			}//switch
		}//while
	}//main
}//class

=== 수도 맞추기 게임 ====
1.입력 2.퀴즈 3.종료 >>>
1
현재 7개의 나라와 수도가 입력되어 있습니다.
나라, 수도 입력(종료는 x) >> 
aaa
111
나라, 수도 입력(종료는 x) >> 
bbb 222
나라, 수도 입력(종료는 x) >> 
ccc 333
나라, 수도 입력(종료는 x) >> 
2
33
나라, 수도 입력(종료는 x) >> 
x
=== 수도 맞추기 게임 ====
1.입력 2.퀴즈 3.종료 >>>
2
ccc의 수도는 (종료는x) ? 
333
정답!!!!
2의 수도는 (종료는x) ? 
x
=== 수도 맞추기 게임 ====
1.입력 2.퀴즈 3.종료 >>>
1
현재 11개의 나라와 수도가 입력되어 있습니다.
나라, 수도 입력(종료는 x) >> 
ccc
이미 입력한 나라입니다.
나라, 수도 입력(종료는 x) >> 
x
=== 수도 맞추기 게임 ====
1.입력 2.퀴즈 3.종료 >>>
3
종료

 


 

책 : Collection 프레임워크 p.404

[Collection 인터페이스]

List -- 순서 있음, 중복 허용

Set -- 순서 없음, 중복 허용 안함

==== Iterator

[Map 인터페이스]

Map -- 순서 없음, 중복 허용 안함

key value로 이루어짐

 

예) 사전

 

apple ---> 사과

 

예제 p.407

Member.java

package com.day09;
//p.407
public class Member {
	private int memberId; //회원 아이디 - 속성1
	private String memberName; //회원 이름 - 속성2
	//생성자
	public Member(int memberId, String memberName) {
		super();
		this.memberId = memberId;
		this.memberName = memberName;
	}
	
	public int getMemberId() {
		return memberId;
	}
	
	public void setMemberId(int memberId) {
		this.memberId = memberId;
	}

	public String getMemberName() {
		return memberName;
	}
	
	public void setMemberName(String memberName) {
		this.memberName = memberName;
	}
	
	@Override
	public String toString() { //toString() 메서드 재정의
		return memberName + " 회원 님의 아이디는 " + memberId + "입니다";
	}
}

MemberArrayList.java p.410

package com.day09;
//p410

import java.util.ArrayList;

public class MemberArrayList { //매니저 같은 역할
	private ArrayList<Member> arrayList; //ArrayList 선언 -> import 3번
	
	public MemberArrayList() {
		arrayList = new ArrayList<>(); //Member형으로 선언한 ArrayList 생성 -> <>안에 굳이 Member 안 넣어줘도 됨
	}
	
	public void addMember(Member member) { //ArrayList에 회원을 추가하는 메서드
		arrayList.add(member);
	}

	public boolean removeMember(int memberId) { // 해당 아이디를 가지 회원을 ArrayList에서 찾아 제거함
		for(int i = 0; i < arrayList.size(); i++) {
			Member member = arrayList.get(i); //get() 메서드로 회원을 순차적으로 가져옴
			int tempId = member.getMemberId();
			if(tempId == memberId) { //회원 아이디가 매개변수와 일치하면
				arrayList.remove(i); //해당 회원을 삭제
				return true;
			}
		}
		System.out.println(memberId + "가 존재하지 않습니다."); //반복문이 끝날 때까지 해당 아이디를 찾지 못한 경우
		return false;
	} 
	
	public void showAllMember() { //전체 회원을 출력하는 메서드
		for(Member member : arrayList) {
			System.out.println(member);
		}
		System.out.println();
	}
}

MemberArrayListTest.java p.411

package com.day09;
//p411
public class MemberArrayListTest {

	public static void main(String[] args) {
		MemberArrayList memberArrayList = new MemberArrayList();
		Member memberLee1 = new Member(1001, "홍길동1"); //객체 생성 - 새로운 회원 인스턴스 생성1
		Member memberLee2 = new Member(1002, "홍길동2"); //새로운 회원 인스턴스 생성2
		Member memberLee3 = new Member(1003, "홍길동3"); //새로운 회원 인스턴스 생성3
		Member memberLee4 = new Member(1004, "홍길동4"); //새로운 회원 인스턴스 생성4
		
		memberArrayList.addMember(memberLee1); //객체 add - ArrayList에 회원 추가
		memberArrayList.addMember(memberLee2);
		memberArrayList.addMember(memberLee3);
		memberArrayList.addMember(memberLee4);
		
		memberArrayList.showAllMember(); //전체 회원 출력
		
		memberArrayList.removeMember(memberLee1.getMemberId()); //홍길동1 회원 삭제
		memberArrayList.showAllMember();//홍길동1 회원 삭제 후 다시 전체 회원 출력
	}
}

홍길동1 회원 님의 아이디는 1001입니다
홍길동2 회원 님의 아이디는 1002입니다
홍길동3 회원 님의 아이디는 1003입니다
홍길동4 회원 님의 아이디는 1004입니다

홍길동2 회원 님의 아이디는 1002입니다
홍길동3 회원 님의 아이디는 1003입니다
홍길동4 회원 님의 아이디는 1004입니다


[스택과 큐] p.419

- 스택 : 입구가 하나

ex) 엘리베이터 -> 출입구가 1개 -> 먼저 들어가는 사람이 나중에 나옴(Last in First out : LIFO) -> 역순으로 나오게 됨

push(넣는것) pop(빼는것)

 

- 큐 : 들어온 순서대로 나감(first in first out : FIFO)

 

우리 책에서는 이걸 ArrayList로 구현함

MyStack.java

package com.day09;

import java.util.ArrayList;

//p419
public class MyStack {
	private ArrayList<String> arrayStack = new ArrayList<>();//저장소 만들기
	
	public void push(String data) {//스택의 맨 뒤에 요소를 추가
		arrayStack.add(data);
	}
	
	public String pop() { //스택의 맨 뒤에서 요소 꺼냄
		int len = arrayStack.size(); //arrayStack.size() -> ArrayList에 저장된 유효한 자료의 개수
		if(len==0) {
			System.out.println("스택이 비어있습니다.");
			return null;
		}
		return (arrayStack.remove(len-1));// 맨 뒤에 있는 자료 반환하고 배열에서 제거
	}
	
	public static void main(String[] args) {
		MyStack stack = new MyStack();
		stack.push("A");
		stack.push("B");
		stack.push("C");

		System.out.println(stack.pop());
		System.out.println(stack.pop());
		System.out.println(stack.pop());
	}
}

C
B
A

 

스택은 입구가 하나라서 뺄때도 나중에 들어온 애를 빼야되는데

큐의 경우는 입구가 두개라서 먼저 들어온 애를 먼저 빼줌

 

위의 예제에서는 pop, push라는 함수를 부른 것이고

사실 스택에 이미 pop(), push()가 구현되어 있음 -> 이걸 그대로 가져다 쓰면 됨

 

StackTest.java

package com.day09;

import java.util.Stack;

public class StackTest {

	public static void main(String[] args) {
		Stack<String> st = new Stack<>();
		st.push("one");
		st.push("two");
		st.push("three");

		System.out.println(st.pop());
		System.out.println(st.pop());
		System.out.println(st.pop());
	}
}

three
two
one

 

 


HashSetTest.java p.423

package com.day09;

import java.util.HashSet;
import java.util.Iterator;

//p423
public class HashSetTest {

	public static void main(String[] args) {
		HashSet<String> hashSet = new HashSet<>();
		hashSet.add(new String("홍길동1"));
		hashSet.add(new String("홍길동2"));
		hashSet.add(new String("홍길동3"));
		hashSet.add(new String("홍길동4"));
		hashSet.add(new String("홍길동5"));
		
		System.out.println(hashSet);
		Iterator<String> it = hashSet.iterator();
		while(it.hasNext()) {
			System.out.println(it.next());
		}
	}
}

[홍길동4, 홍길동5, 홍길동2, 홍길동3, 홍길동1]
홍길동4
홍길동5
홍길동2
홍길동3
홍길동1

 

 

HashSetTest2.java

/* Set을 이용
 * 로또번호 6자리 출력
 * (1에서 45까지의 난수 6개 출력)
(당연히 중복 안됨) */

package com.day09;

import java.util.HashSet;
import java.util.Set;

public class HashSetTest2 {
	/*
	 * Set을 이용
	 * 로또번호 6자리 출력
	 * (1에서 45까지의 난수 6개 출력)
	 * (당연히 중복 안됨)
	 */

	public static void main(String[] args) {
		Set<Integer> set = new HashSet<>(); //얘는 중복되면 알아서 못들어가서 신경쓸 필요 없음
		while(set.size()<6) {
			int r = (int)(Math.random()*45)+1; //0~44까지 나오니까 +1해줘서 1~45
			set.add(r);
		}
		System.out.println(set);
	}
}

[32, 33, 3, 38, 6, 9]

 

//오름차순으로 정렬해서 출력

package com.day09;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class HashSetTest2 {
	/*
	 * Set을 이용
	 * 로또번호 6자리 출력
	 * (1에서 45까지의 난수 6개 출력)
	 * (당연히 중복 안됨)
	 */

	public static void main(String[] args) {
		Set<Integer> set = new HashSet<>(); //얘는 중복되면 알아서 못들어가서 신경쓸 필요 없음
		while(set.size()<6) {
			int r = (int)(Math.random()*45)+1; //0~44까지 나오니까 +1해줘서 1~45
			set.add(r);
		}
		System.out.println(set);
		//오름차순으로 정렬해서 출력

		//set --> List로 변환
		List<Integer> list = new ArrayList<>(set);
		Collections.sort(list);;
		System.out.println(list);
	}
}

[20, 37, 21, 41, 13, 31]
[13, 20, 21, 31, 37, 41]

 

이렇게 적어줘도 됨

package com.day09;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class HashSetTest2 {
	/*
	 * Set을 이용
	 * 로또번호 6자리 출력
	 * (1에서 45까지의 난수 6개 출력)
	 * (당연히 중복 안됨)
	 */

	public static void main(String[] args) {
		Set<Integer> set = new HashSet<>(); //얘는 중복되면 알아서 못들어가서 신경쓸 필요 없음
		while(set.size()<6) {
			int r = (int)(Math.random()*45)+1; //0~44까지 나오니까 +1해줘서 1~45
			set.add(r);
		}
		System.out.println(set);
		//오름차순으로 정렬해서 출력

		//set --> List로 변환
		List<Integer> list = new ArrayList<>(set);
		Collections.sort(list);;
		System.out.println(list);
		Object[] arr = set.toArray(); //배열로 바꿈
		Arrays.sort(arr);
		System.out.println(Arrays.toString(arr) + "");
	}
}

[32, 34, 4, 24, 44, 15]
[4, 15, 24, 32, 34, 44]
[4, 15, 24, 32, 34, 44] -> 결과 동일

 

 

p.447

Q6. 다음 코드에서 CarTest의 결과가 true, true, false가 되도록 HashMap을 사용하여 CarFactory 클래스를 구현해 보세요.

Car.java

package com.day09;

public class Car {
	private String name;
	
	public Car() {}
	public Car(String name) {
		this.name = name;
	}
}

CarTest.java

package com.day09;

public class CarTest {
	public static void main(String[] args) {
		CarFactory factory = CarFactory.getInstance();
		
		Car sonata1 = factory.createCar("연수 차");
		Car sonata2 = factory.createCar("연수 차");
		System.out.println(sonata1 == sonata2); //true
		
		Car avante1 = factory.createCar("승연 차");
		Car avante2 = factory.createCar("승연 차");
		System.out.println(avante1 == avante2); //true
		
		System.out.println(sonata1 == avante1); //false

	}
}

 

 

CarFactory 클래스를 따로 만들어도 되고 같이 만들어도 된다.

map은 key 값이 같으면 같다고 함

 

CarFactory.java

package com.day09;

import java.util.HashMap;

public class CarFactory {
	
	HashMap<String, Car> carMap = new HashMap<>();
	private static CarFactory instance = new CarFactory(); //2. 그러나 static이기 때문에 프로그램이 실행 되자마자 먼저 만든다
	//싱글톤 : 계속 new해서 만드는 것이 아니라 DB할 때는 이런식으로 많이 한다.
	public static CarFactory getInstance() {
		//if(instance == null) -> 1. null이면 만들어라 -> 3. 따라서 이걸 생략해줘도 된다.
		//instance = new CarFactory();
		return instance;
	}
	
	public Car createCar(String name) {
		if(carMap.containsKey(name)) { //맵에 있음
			return carMap.get(name);
		}
		Car car = new Car(); //맵에 없음
		carMap.put(name, car);
		return car;
	}
}

true
true
false

 

하나의 파일로 만들면 파일명은 CarTest로 해줘야 함

- main을 가지고 있는 것을 파일명으로 해주어야 함

 


다음 시간에는 예외처리 할 예정

 

프로그램을 공부할 때는 순서대로X

main 부터 보고 왔다갔다 하면서 봐야 하고 호출되는걸 따라가서 다 보고

생성자 보고..

옆에 주석처리로 메모하거나 책 등에 적어가면서 공부하기

728x90
728x90