java/학교,기관

제네릭과 컬렉션(프로그래밍 심화)(명품 JAVA Programming )

지트리아 2022. 11. 21. 10:28

용어정리

해시 함수 : 임의의 길이를 갖는 메시지를 입력받아 고정된 길이의 해시값을 출력하는 함수이다. 저장된 자료의 양에 상관없이 원소 하나를 저장하고 검색하는 것을 상수 시간에 가능하게 하기 위해 해시 테이블이 나왓다.

 

본문정리

컬렉션과 제네릭

컬렉션은 제네릭이라는 기법으로 구현되어 있다. 컬렉션은 배열이 가진 고정 크기의 단점을 극복하기 위해 객체들을 쉽게 삽입, 삭제, 검색할 수 있는 가변 크기의 컨테이너이다.

Vector, ArrayList, LinkedList, Stack, HashSet은 모두 단일 클래스의 객체만을 요소로 다루지만,

HashMap키와 값의 쌍으로 이루어지는 데이터를 저장하고, '키'로 쉽게 검색하도록 만든 컬렉션이다.

컬렉션의 특징은 다음과 같다.

1. 제네릭이라는 기법으로 만들어져 있다. HashMap은 <K>, <V>를 가지고 나머지는 <E>를 갖는데, 이들을 타입 매개 변수라고 한다. 여기서 E는 특정 타입(인티절 같은 것)만 다루지 않고 여러 종류의 타입으로 변신할 수 있도록, 컬렉션을 일반화하기위해 사용하는 것이다. 따라서 E는 일반화시킨 타입 혹은 제네릭 타입이라고 부른다. 핵심은 컬렉션은 여러 타입의 값을 다룰 수 있도록 변신이 가능하지만, 사용할 때는 지정된 타입의 값만 저장 가능하다.

2. 컬렉션의 요소는 객체들만 가능하다. int, char과 같은 기본 타입의 데이터는 원칙적으로 컬렉션의 요소로 불가능하다. 하지만 삽입하면 자동 박싱에 의해 Wrapper클래스 타입으로 변환된어 객체에 저장된다.

또한 Collection 클래스의 메소드는 모두 static 타입이므로 Collection 객체를 생성할 필요가 없다.

메소드에는 다음과 같은 종류가 있다.

sort() : 컬렉션에 포함된 요소들의 정렬

reverse() :  요소를 반대 순으로 정렬

max(), min() : 요소들의 최댓값과 최솟값 찾아내기

binarySearch() : 이진검색

 

제네릭은 클래스나 메소드를 타입 매개변수를 이용하여 선언하는 기법이다. 또한 클래스 코드를 찍어내듯이 생산할 수 있도록 일반화 시키는 도구이다.

앞서 말했듯 제네릭 타입 매개변수는 혼동을 피하기 위해 하나의 대문자를 사용한다.

: Element를 의미하며 컬렉션에서 요소임을 나타냄

T : Type을 의미

: Value를 의미

: Key를 의미

 

제네릭 컬렉션 활용

Vector<E>는 배열을 가변 크기로 다룰 수 있게 하고, 객체의 삽입·삭제·이동이 쉽도록 구성한 컬렉션 클래스이다. 백터는 삽입되는 요소의 개수에 따라 자동으로 크기를 조절하고, 요소의 삽입과 삭제에 따라 자동으로 요소들의 자리를 이동한다.

벡터 생성은 다음과 같이 한다.

Vector<Integer> v = new Vector<Integer>();

여기서 인티저 대신 int넣으면 안된다. 만약 E에 구체적인 타입을 지정하지 않으면 경고 메시지가 출력된다. 용량을 초기에 설정하고 싶다면 ()안에 용량을 지정하면 된다. 메소드는 다음과 같다.

boolean add(E element) : 백터의 맨 뒤에 element 추가
void add(int index, E element) : 인데스 index에 element를 삽입
int capacity() : 백터의 현재 용량 리턴
boolean addAll(Collection<? extends E > c) : 컬렉션 c의 모든 요소를 벡터의 맨 뒤에 추가
void clear() : 벡터의 모든 요소 삭제
boolean contains(Object o) : 벡터가 지정된 객체 o를 포함하고 있으면 true 리턴
E elementAt(int index) : 인데스 index의 요소 리턴
E get(int index) : 인데스 index의 요소 리턴
int indexOf(Object o) : o와 같은 첫 번째 요소의 인덱스 리턴, 없으면 -1리턴
boolean isEmpty() : 벡터가 비어 있으면 true 리턴
E removve(int index) : 인덱스 index의 요소 삭제
boolean remove(Object o) : 객체 o와 같은 첫 번째 요소를 벡터에서 삭제
void removeAllElements() : 벡터의 모든 요소를 삭제하고 크기를 0으로 만듦
int size() : 벡터가 포함하는 요소의 개수 리턴
Object[] toArray() : 벡터의 모든 요소를 포함하는 배열 리턴

여기서 add로 예를 들어보겠다. 

v.add(Integer.valueOf(5)); #객체로 삽입을 해야하지만
v.add(5); #자동 박싱 기능을 활용해도 된다.

여기서 3.5나 "hello"같은 다른 타입을 넣으면 안된다. 다만 null은 넣을 수 있으며, 해당 값을 검색 할 수도 있다. 

컬렉션을 매개변수로 전달받는 메소드 또한 선언 가능하다.

public void printVector(Vector<Integer> v){
~~
}

 타입 추론 기능, var키워드 기능이 생기면서 다음과 같이도 선언할 수 있어졌다.

Vector<Integer> v1 = new Vector<>(); #타입 추론 기능
var v2 = new Vector<Integer> ();#var 키워드 기능

 

ArrayList<E>는 가변 크기의 배열을 구현한 컬렉션 클래스이며 Vector 클래스와 거의 동일하다. 다른 점은 스레드 간에 동기화를 지원하지 않기 때문에, 다수의 스레드가 동시에 ArrayList에 요소를 삽입하거나 삭제할 때 ArrayList의 데이터가 훼손될 우려가 있다. 하지만 스레드간 동기화를 하지 않기 때문에 빠르다.(즉 단일 스레드 응용에는 효과적이다.)

ArrayList생성과 메소드는 다음과 같다.

ArrayList<String> v = new ArrayList<String>();
#여기서 또한 타입 추론 기능과 var 키워드 기능을 이용할 수 있다.
boolean add(E element) : ArrayList의 맨 뒤에 Element 추가
void add(int index, E element) : 인덱스 index 위치에 element 삽입
boolean addAll(Collector<? extends E > c) : 컬렉션 c의 모든 요소를 ArrayList의 맨 뒤에 추가
void clear() : ArrayList의 모든 요소 삭제
boolean contains(Object o) : ArrayList가 지정한 객체를 포함하고 있으면 true 리턴
E elementAt(int index) : index 인덱스 요소 리턴
E get(int index) : index 인엑스 요소 리턴
int indexOf(object o) : o 와 같은 첫 번째 요소의 인덱스 리턴, 없으면 -1 리턴
boolean isEmpty() : ArrayList가 비어있으면 true 리턴
E remove(int index) : index 인덱스의 요소 삭제
boolean remove(Object o) : o와 같은 첫 번째 요소를 ArrayList에서 삭제
int size() : ArrayList가 포함하는 요소의 개수 리턴
Object[] toArray() : ArrayList의 모든 요소를 포함하는 배열 리턴

 

Iterator<E> 인터페이스는 Vector, ArrayList, LinkedList, Set과 같이 요소가 순서대로 저장된 컬렉션에 요소를 순차 검색할 때 사용한다. 여기서 Iterator객체를 반복자로도 부른다. 메소드는 다음과 같다.

Vector<Integer> v = new Vector<Integer>();
Iterator<Integer> it = v.iterator();
boolean hashNext() : 방문할 요소가 남아 있으면 true 리턴
E next() : 다음 요소 리턴
void remove() : 마지막으로 리턴된 요소 제거

 

HashMap<K, V> 컬렉션은 와 의 쌍으로 구성되는 요소를 다룬다. 여기서는 put(), get() 메소드를 이용하여 요소를 삽입하거나 검색한다.

HashMap<String, String> h = new HashMap<String, String>();
#여기서도 타입 추론기능과 var 키워드 기능을 이용할 수 있다.

h.put("apple", "사과");
String kor = h.get("apple");

해시맵은 Vector<E>나 ArrayList<E>와는 다른점이 있다.

먼저 요소의 삽입, 삭제 시간이 매우 빠르다.

요소 검색은 더욱 빠르다.

인덱스를 이용하여 요소에 접근할 수 없고 오직 '키'로만 검색 해야 한다. 메소드는  다음과 같다.

void clear() : 해시맵의 모든 요소 삭제
boolean containsKey(Object key) : 지정된 키를 포함하고 있으면 true 리턴
boolean vontainsValue(Object value) : 지정된 값에 일치하는 키가 있으면 true 리턴
V get(Object key) : 지정된 키의 값 리턴, 키가 없으면 null 리턴
boolean isEmpty() : 해시맵이 비어있으면 true 리턴
Set<K> keySet() : 해시맵의 모든 키를 담은 Set<k> 컬렉션  리턴
V put(K key, V value) : key와 value 쌍을 해시맵에 저장
V remove(Object Key) : 지정된 키를 찾아 키와 값 모두 삭제
int size() : HashMap에 포함된 요소의 개수 리턴

 

LinkedList<E>요소들을 양방향으로 연결하여 관리한다는 점을 제외하곤 Vector, ArrayList와 거의 같다.

 

 

제네릭 만들기

여태 설명한 내용은 JDK에 제네릭으로 구현된 컬렉션을 사용하는 방법을 알아본 것이다.

제네릭 클래스를 작성하는 방법은 기존의 클래스 작성 방법과 유사하다. 가장 큰 차이는 클래스 이름 다음에 일반화된 타입의 매개변수를 <>사이에 추가한다는 것이다.

타입 매개변수 T를 가진 제네릭 클래스 MyClass는 다음과 같이 작성한다.
public class MyClass <t> { // 제네릭 클래스 Myclass, 타입 매개변수 T
	T val; // 변수 val의 타입은 T
    void set(T a){
    	val = a; // T타입의 값 a를 val에 지정
    }
    T get(){
    	return val; // T 타입의 값 val 리턴
    }
}
제네릭 클래스의 레퍼런스 변수를 선언은 다음과 같이한다.
MyClass<String> s; // <T>를 String으로 구체화

List<Integer> li; // <E>를 Integer로 구체화하는 것과 같은 원리

위 처럼 제네릭 클래스에 구체적인 타입을 대입하여 구체적인 객체를 생성하는 과정을 구체화라 한다. 이 과정은 자바 컴파일러에 의해 이루어진다. 구체화에는 기본 타입은 사용할 수 없다.

또한 제네릭 클래스 내에서 제네릭 타입을 가진 객체의 생성은 허용되지 않는다. (책 425쪽에 자세한 내용이 나오는데 익혀야 할 듯?)

또한 제네릭 클래스 또는 인터페이스 타입의 배열은 선언할 수 없다. 그러나 제네릭 타입의 배열 선언은 가능하다.

GStack<Integer> [] gs = new GStack<Integer>[10]; //컴파일 오류
public void myArray(T[] a){...} //가능!!

다음은 제네릭 메소드를 구현하는 예이다.

Class GenericMethodEx{
	static <T> void toStack(T[] a, GStack<t> gs){
    	for(int i = 0; i < a.length; i++){
        gs.push(a[i]);
        }
     }
 }

아래의 코드는 toStack()의 호출문으로부터 타입 매개변수 T를 String으로 유추하는 경우이다.

String[] sArray = new String[100];
GStack<String> stringStack = new GStack<String>();
GenericMethodEx.toStack(sArray, stringStack);// 타입 매개변수 T를 String으로 유추함

 

 

장점은 다음과 같다.

동적으로 타입이 결정되지 않고 컴파일 시에 타입이 결정되므로 보다 안전한 프로그램 가능

런타임 타입 충돌 문제 방지

개발 시 타입 캐스팅 절차 불필요

ClassCastException 방지

 

본문제

Q1. Scanner 클래스로 -1이 입력될 때까지 양의 정수를 입력받아 벡터에 저장하고 벡터를 검색하여 가장 큰 수를 출력하는 프로그램을 작성하라.

정수(-1이 입력될 때까지)>> 10 6 22 6 88 77 -1
가장 큰 수는 88

 

import java.util.*;

public class Java {
	public static void main(String args[]) {
		Scanner sc = new Scanner(System.in);
		Vector<Integer> ve = new Vector<Integer>();
		
		while(true) {
			int k = sc.nextInt();
			if(k==-1) {
				break;
			}
			else {
				ve.add(k);
			}
		}
		
		Iterator<Integer> ie = ve.iterator();
		
		int max = ve.elementAt(0);
		while(ie.hasNext()) {
			int t = ie.next();
			if(max < t) {
				max = t;
			}
		}		
		
		System.out.println("가장 큰 수는 " + max);		
	}
}

 

Q2. Scanner 클래스를 사용하여 6개 학점('A', 'B', 'C', 'D', 'F')을 문자로 입력받아 ArrayList에 저장하고, ArrayList를 검색하여 학점을 점수(A=4.0, B=3.0, C=2.0, D=1.0, F=0)로 변환하여 평균을 출력하는 프로그램을 작성하라.

6개의 학점을 빈 칸으로 분리 입력(A/B/C/D/F) >> A C A B F D
2.3333333333333335

 

import java.util.*;

public class Java {
	public static void main(String args[]) {
		Scanner sc = new Scanner(System.in);
		ArrayList<Character> al = new ArrayList<Character>(6);
		double sum = 0;
		
		System.out.print("6개의 학점을 빈 칸으로 분리 입력(A/B/C/D/E)");
		for(int i = 0; i < 6; i++) {
			char c = sc.next().charAt(0);
			al.add(c);			
		}
		Iterator <Character> ie = al.iterator();
		
		while(ie.hasNext()) {
			switch (ie.next()){
				case 'A':
					sum += 4.0;
					break;
				case 'B':
					sum += 3.0;
					break;
				case 'C':
					sum += 2.0;
					break;
				case 'D':
					sum += 1.0;
					break;
				case 'E':
					sum += 0;
					break;
			}
		}
		System.out.print(sum/6);
	}
}

 

Q3. "그만"이 입력될 때까지 나라 이름과 인구를 입력받아 저장하고, 다시 나라 이름을 입력받아 인구를 출력하는 프로그램을 작성하라. 다음 해시맵을 이용하라.

나라 이름과 인구를 입력하세요.(예: Korea 5000)

나라 이름, 인구 >> Korea 5000

나라 이름, 인구 >> USA 1000000

나라 이름, 인구 >> Swiss 2000

나라 이름, 인구 >> France 3000

나라 이름, 인구 >> 그만

인구 검색 >> France

France의 인구는 3000

인구 검색 >> 스위스

스위스 나라는 없습니다.

인구 검색 >> 그만

 

import java.util.*;

public class Java {
	public static void main(String args[]) {
		Scanner sc = new Scanner(System.in);
		HashMap<String, Integer> nations = new HashMap<String, Integer>();
		
		System.out.println("나라 이름과 인구를 입력하세요.(예: Korea 5000");
		
		while(true) {			
			System.out.print("나라 이름, 인구 >>");
			String str = sc.next();
			if(str.equals("그만")) {
				break;
			}
			int num = sc.nextInt();
				nations.put(str, num);
		}
		while(true) {			
			System.out.print("인구 검색>>");
			String str = sc.next();
			if(str.equals("그만")) {
				break;
			}
			else {
				if(nations.get(str) == null) {
					System.out.println(str + " 나라는 없습니다.");
				}
				else {
					System.out.println(str + "의 인구는 "+ nations.get(str));
				}
			}
		}
	}
}

 

Q4. Vector 컬렉션을 이용하여 강수량의 평균을 유지 관리하는 프로그램을 작성하라. 강수량을 입력하면 벡터에 추가하고 현재 입력된 모든 강수량과 평균을 출력한다.

강수량 입력 (0 입력시 종료) >> 5

5 

현재 평균 5

강수량 입력 (0 입력시 종료) >> 80

5 80 

현재 평균 42

강수량 입력 (0 입력시 종료) >> 53

5 80 53 

현재 평균 46

강수량 입력 (0 입력시 종료) >> 22

5 80 53 22 

현재 평균 40

강수량 입력 (0 입력시 종료) >> 0

 

import java.util.*;

public class Java {
	public static void main(String args[]) {
		Scanner sc = new Scanner(System.in);
		Vector <Integer> ve = new Vector <Integer> ();
		int a = 0, sum = 0, k = 0;
		
		while(true) {
			System.out.print("강수량 입력 (0 입력시 종료)>>");
			a = sc.nextInt();
			if(a==0) {
				break;
			}
			ve.add(a);
			for(int i = 0; i <ve.size(); i++) {
				sum += ve.elementAt(i);
				System.out.print(ve.elementAt(i) + " ");
			}
			System.out.println("\n현재 평균 " + sum/ve.size());
			sum = 0;
		}		
	}
}

 

Q5. 하나의 학생 정보를 나타내는 Student 클래스에는 이름, 학과, 학번, 학점 평균을 저장하는 필드가 있다.

 

(1) 학생마다 Student 객체를 생성하고 4명의 학생 정보를 ArrayList<Student> 컬렉션에 저장한 후에, ArrayList<Student>의 모든 학생(4명) 정보를 출력하고 학생 이름을 입력받아 해당 학생의 학점 평균을 출력하는 프로그램을 작성하라.

학생 이름, 학과, 학번, 학점평균 입력하세요.

>> 황기태, 모바일, 1, 4.1

>> 이재문, 안드로이드, 2, 3.9

>> 김남윤, 웹공학, 3, 3.5

>> 최찬미, 빅데이터, 4, 4.25

----------------------------------

이름: 황기태

학과: 모바일

학번: 1

학점평균: 4.1

----------------------------------

이름: 이재문

학과: 안드로이드

학번: 2

학점평균: 3.9

----------------------------------

이름: 김남윤

학과: 웹공학

학번: 3

학점평균: 3.5

----------------------------------

이름: 최찬미

학과: 빅데이터

학번: 4

학점평균: 4.25

----------------------------------

학생 이름 >> 최찬미

최찬미, 빅데이터, 4, 4.25

학생 이름 >> 이재문

이재문, 안드로이드, 2, 3.9

학생 이름 >> 그만

 

import java.util.*;

class student{
	String name, major, level, score;
	public student(String name, String major, String level, String score) {
		this.name=name;this.major=major;this.level=level;this.score=score;
	}
	public void showall() {
		System.out.println("이름:" + this.name);
		System.out.println("학과:" + this.major);
		System.out.println("학번:" + this.level);
		System.out.println("학점평균:" + this.score);
	}
	public String getname(){
		return this.name;
	}
}

public class Java {
	public static void main(String args[]) {
		Scanner sc = new Scanner(System.in);
		student[] student = new student[4];
		ArrayList<student> students = new ArrayList<student>();
		String name, major, level, score;
		String order;
		
		System.out.println("학생 이름, 학과, 학번, 학점평균 입력하세요.");
		for(int i = 0; i<4; i++) {
			System.out.print(">> ");
			String toke = sc.nextLine();
			StringTokenizer token = new StringTokenizer(toke, ",");
			name = token.nextToken().trim();
			major = token.nextToken().trim();
			level = token.nextToken().trim();
			score = token.nextToken().trim();
			student[i] = new student(name, major, level, score);
			students.add(student[i]);
		}
		System.out.println("----------------------------");
		for(int i = 0; i<4; i++) {
			student[i].showall();
			System.out.println("----------------------------");
		}
		while(true) {
			System.out.print("학생 이름 >> ");
			order = sc.next();
			if(order.equals("그만")) {
				break;
			}
			for(int i = 0; i < 4; i++) {
				if(order.equals(student[i].getname())) {
					student[i].showall();
				}				
			}
		}
	}
}

귀찮아서 마지막껀 그냥 이렇게 구현할꺼다~ 느낌만 냈다.

 

(2) ArrayList<Student> 대신, HashMap<String, Studnet> 해시맵을 이용하여 다시 작성하라. 해시맵에서 키는 학생 이름으로 한다.

import java.util.*;

class student{
	String name, major, level, score;
	public student(String name, String major, String level, String score) {
		this.name=name;this.major=major;this.level=level;this.score=score;
	}
	public void showall() {
		System.out.println("이름:" + this.name);
		System.out.println("학과:" + this.major);
		System.out.println("학번:" + this.level);
		System.out.println("학점평균:" + this.score);
	}
	public String getname() {
		return name;
	}
	public String getmajor() {
		return major;
	}
	public String getlevel() {
		return level;
	}
	public String getscore() {
		return score;
	}
	public void infor(String name) {
		if(name.equals(this.name)) {
			System.out.println(this.name + " " + this.major+" "+this.level+" "+this.score);
		}
	}

}

public class Java {
	public static void main(String args[]) {
		Scanner sc = new Scanner(System.in);
		student[] student = new student[4];
		HashMap<String, student> dic = new HashMap<String, student>(4);
		String name, major, level, score;
		String txt, order;
		
		System.out.println("학생 이름, 학과, 학번, 학점평균 입력하세요.");
		for(int i = 0; i < 4; i++) {
			System.out.print(">> ");
			txt = sc.nextLine();
			StringTokenizer token = new StringTokenizer(txt, ", ");
			name = token.nextToken().trim();
			major = token.nextToken().trim();
			level = token.nextToken().trim();
			score = token.nextToken().trim();
			student[i] = new student(name, major, level, score);
			dic.put(name, student[i]);			
		}
		
		Set<String> key = dic.keySet();
		Iterator<String> it = key.iterator();
		System.out.println("------------------------------");
		
		while(it.hasNext()) {
			order= it.next();
			student s = dic.get(order);
			System.out.println("이름: "+s.getname());
			System.out.println("학과: "+s.getmajor());
			System.out.println("학번: "+s.getlevel());
			System.out.println("학점평균: "+s.getscore());
			System.out.println("------------------------------");
		}
		
		while(true) {
			System.out.print("학생 이름 >> ");
			order = sc.next();
			if(order.equals("그만")) {
				break;
			}
			for(int i = 0; i < dic.size(); i++) {
				student[i].infor(order);
			}
		}
	}
}

 

Q6. 도시 이름, 위도, 경도 정보를 가진 Location 클래스를 작성하고, 도시 이름을 '키'로 하는 HashMap<String, Location> 컬렉션을 만들고, 사용자로부터 입력 받아 4개의 도시를 저장하라. 그리고 도시 이름으로 검색하는 프로그램을 작성하라.

도시, 경도, 위도를 입력하세요.

>> 서울, 37, 126

>> LA, 34, -118

>> 파리, 2, 48

>> 시드니, 151, -33

----------------------------------

서울 37 126

LA 34 -118

파리 2 48

시드니 151 -33

----------------------------------

도시 이름 >> 피리

피리는 없습니다.

도시 이름 >> 파리

파리 2 48

도시 이름 >> 그만

 

import java.util.*;

class Location{
	private String name, x, y;
	
	public Location(String name, String x, String y) {
		this.name = name; this.x = x; this.y = y;
	}
	public String getname(){
		return this.name;
	}
	public String getx() {
		return this.x;
	}
	public String gety() {
		return this.y;
	}	
	public void showall(String name) {
		if(name.equals(this.name)) {
		System.out.println(this.name + "  "+ this.x + "  "+ this.y);
		}
	}
}

public class Java {
	public static void main(String args[]) {
		Scanner sc = new Scanner(System.in);
		Location [] a = new Location[4];
		HashMap<String, Location> hm = new HashMap<String, Location>(4);
		String name, x, y;
		String str, order;
		
		System.out.println("도시, 경도, 위도를 입력하세요.");
		for(int i = 0; i < 4; i++) {
			System.out.print(">> ");
			str = sc.nextLine();
			StringTokenizer k = new StringTokenizer(str, ",");
			name = k.nextToken().trim();
			x = k.nextToken().trim();
			y = k.nextToken().trim();
			a[i] = new Location(name, x, y);
			hm.put(name, a[i]);
		}
		System.out.println("------------------------------");
		Set<String> key = hm.keySet();
		Iterator <String> it = key.iterator();
		while(it.hasNext()) {
			order = it.next();
			Location l = hm.get(order);
			System.out.println(l.getname()+"  "+l.getx()+"  "+l.gety());
		}
		System.out.println("------------------------------");
		while(true) {
			order = sc.next();
			if(order.equals("그만")) {
				break;
			}
			for(int i = 0; i < 4; i++) {
				a[i].showall(order);
			}
		}		
	}
}

 

Q7. 이름과 학점(4.5만점)을 5개 입력받아 해시맵에 저장하고, 장학생 선발 기준을 입력 받아 장학생 명단을 출력하라.

미래장학금관리시스템입니다.

이름과 학점 >> 적당히 3.1

이름과 학점 >> 나탈락 2.4

이름과 학점 >> 최고조 4.3

이름과 학점 >> 상당히 3.9

이름과 학점 >> 고득점 4.0

장학생 선발 학점 기준 입력 >> 3.2

장학생 명단 : 최고조 상당히 고득점

 

import java.util.*;

public class Java {
	public static void main(String args[]) {
		Scanner sc = new Scanner(System.in);
		HashMap<String, Double> hm = new HashMap<String, Double>(5);
		Vector<String> vt = new Vector<String>();
		String text; // 입력 이름과 점수
		String name, oname; //입력 이름, 나와야 하는 이름
		double score, oscore; //입력 점수, 기준 점수
		
		
		System.out.println("미래장학금관리시스템입니다.");
		for(int i  = 0; i < 5; i++) {
			System.out.print("이름과 학점>> " );
			text = sc.nextLine();
			StringTokenizer str = new StringTokenizer(text," ");
			name = str.nextToken().trim();
			score = Double.parseDouble(str.nextToken().trim());
			hm.put(name, score);
		}
		System.out.print("장학생 선발 학점 기준 입력>> ");
		oscore = sc.nextDouble();
		
		Set<String> key = hm.keySet();
		Iterator<String> it = key.iterator();
		
		while(it.hasNext()) {
			oname = it.next();
			if(hm.get(oname) >= oscore) {
				vt.add(oname);
			}
		}
		
		it = vt.iterator();
		System.out.print("장학생 명단 : ");
		while(it.hasNext()) {
			System.out.print(it.next() +" ");
		}
	}
}

 

Q8. 고객의 이름과 포인트 점수를 관리하는 프로그램을 해시맵을 이용하여 작성하라. 프로그램은 고객의 이름과 포인트를 함께 저장 관리하는데, 포인트는 추가될 때마다 누적하여 저장된다.

** 포인트 관리 프로그램입니다 **

이름과 포인트 입력 >> 이재문 40

(이재문,40)

이름과 포인트 입력 >> 황기태 50

(이재문,40)(황기태,50)

이름과 포인트 입력 >> 황기태 60

(이재문,40)(황기태,110)

이름과 포인트 입력 >> 김남윤 30

(이재문,40)(김남윤,30)(황기태,110)

이름과 포인트 입력 >> 이재문 20

(이재문,60)(김남윤,30)(황기태,110)

이름과 포인트 입력 >> 그만

 

import java.util.*;

public class Java {
	public static void main(String args[]) {
		Scanner sc = new Scanner(System.in);
		HashMap<String, Integer> hm = new HashMap<String, Integer>();
		String text; // 전체 문장
		String name, oname; // 해당 이름, 추가 이름
		int point; // 해당 포인트
		
		System.out.println("** 포인트 관리 프로그램 입니다 **");
		
		while(true) {
			System.out.print("이름과 포인트 입력>>");
			name = sc.next();
			if(name.equals("그만")) {
				break;
			}
			point = sc.nextInt();
			
			if(hm.get(name) == null) {
				hm.put(name, point);
			}
			else {
				hm.put(name, hm.get(name)+point);
			}			
			
			Set<String> key = hm.keySet();
			Iterator <String> it = key.iterator();
			while(it.hasNext()) {
				oname = it.next();
				System.out.print("(" + oname+","+hm.get(oname)+")");
			}
			System.out.println();
		}
	}
}

 

Q9. 다음 Istack 인터페이스가 있다.

interface IStack<T> {
	T pop();
	boolean push(T ob);
}

IStack<T> 인터페이스를 구현(implements)하는 MyStack<T> 클래스를 작성하라. 스택의 원소는 Vector<E>를 이용하여 저장하라. 다음은 MyStack<Integer>로 구체화한 정수 스택을 생성하고 활용하는 코드와 실행 결과이다.

public class StackManager {
	public static void main(String[] args) {
		IStack<Integer> stack = new MyStack<Integer>();
		for (int i=0; i<10; i++) stack.push(i);
		while(true) {
			Integer  n = stack.pop();
			if(n == null) break;
			System.out.print(n+" ");
		}
	}
}

 

class MyStack <T>implements IStack<T>{
	ArrayList<T> l = null;
	public MyStack() {
		l = new ArrayList<T>();
	}
	public T pop() {
		if(l.size() == 0) {
			return null;
		}
		else
			return l.remove(0);
	}
	public boolean push(T ob) {
		l.add(0, ob);
		return true;
	}
}

 

Q10. Vector<Shape>의 벡터를 이용하여 그래픽 편집기를 만들어보자. 본문 5.6절과 5.7절에서 사례로 든 추상 클래스 Shape과 Line, Rect, Circle 클래스 코드를 잘 완성하고 이를 활용하여 "삽입", "삭제", "모두 보기", "종료"의 4가지 그래픽 편집 기능을 프로그램을 작성하라. 6장 실습문제 6번을 Vector<Shape>을 이용하여 재작성하는 연습이다. Vector를 이용하면 6장 실습문제 6번보다 훨씬 간단히 작성됨을 경험할 수 있다.

그래픽 에디터 beauty을 실행합니다.

삽입(1), 삭제(2), 모두 보기(3), 종료(4) >> 1

Line(1), Rect(2), Circle(3) >> 2

삽입(1), 삭제(2), 모두 보기(3), 종료(4) >> 1

Line(1), Rect(2), Circle(3) >> 3

삽입(1), 삭제(2), 모두 보기(3), 종료(4) >> 2

삭제할 도형의 위치 >> 3

삭제할 수 없습니다.

삽입(1), 삭제(2), 모두 보기(3), 종료(4) >> 4

beauty을 종료합니다.

 

package Javava;
import java.util.*;

abstract class shape{
	public shape() {};
	public abstract void draw();
}

class line extends shape{
	public void draw() {
		System.out.println("line");
	}
}
class rect extends shape{
	public void draw() {
		System.out.println("rect");
	}
}
class circle extends shape{
	public void draw() {
		System.out.println("circle");
	}
}


public class StackManageer {
	public static void main(String args[]) {
		 Scanner sc = new Scanner(System.in);
		 Vector<shape> ve = new Vector<shape>();
		 Iterator<shape> it = ve.iterator();
	     int order;
		 
		 
		 System.out.println("그래픽 에디터 beauty을 실행합니다.");
		 while(true) {
			 System.out.print("삽입(1), 삭제(2), 모두 보기(3), 종료(4)>> ");
			 order = sc.nextInt();
			 if(order == 4) {
				 System.out.println("beauty을 종료합니다.");
				 break;
			 }
			 else if(order == 1) {
				 System.out.print("line(1), rect(2), circle(3)>>");
				 order = sc.nextInt();
				 if(order == 1) {
					 ve.add(new line());
				 }
				 else if(order == 2) {
					 ve.add(new rect());
				 }
				 else if(order == 3) {
					 ve.add(new circle());
				 }
			 }
			 else if(order == 2) {
				 System.out.print("삭제할 도형의 위치>>");
				 order = sc.nextInt();
				 if(order < 0|| order >= ve.size()) {
					 System.out.println("삭제할 수 없습니다.");
				 }
				 else {
					 ve.remove(order);
					 System.out.println("삭제 하였습니다.");
				 }
			 }
			 else if(order == 3) {
				 for(int i = 0; i < ve.size(); i++) {
					 ve.get(i).draw();
				 }
			 }
		 }
	}
}

 

Q11. 나라와 수도 맞추기 게임의 실행 예시는 다음과 같다.

**** 수도 맞추기 게임을 시작합니다. ****

입력:1, 퀴즈:2, 종료:3>> 1

현재 9개 나라와 수도가 입력되어 있습니다.

나라와 수도 입력10>> 한국 서울

나라와 수도 입력11>> 그리스 아테네

그리스는 이미 있습니다!

나라와 수도 입력11>> 호주 시드니

나라와 수도 입력12>> 이탈리아 로마

나라와 수도 입력13>> 그만

입력:1, 퀴즈:2, 종료:3>> 2

일본의 수도는? 동경

정답!!

스페인의 수도는? 하얼빈

아닙니다!!

프랑스의 수도는? 파리

정답!!

중국의 수도는? 베이징

정답!!

스페인의 수도는? 그만

입력:1, 퀴즈:2, 종료:3>> 3

게임을 종료합니다.

 

(1)

package Javava;
import java.util.*;

class Nation{
	String country, capital;
	
	public Nation(String country, String capital) {
		this.capital = capital; this.country = country;
	}
}

public class StackManageer {
	public static void main(String args[]) {
		Scanner sc = new Scanner(System.in);
		int order, count;
		String country, capital, total;
		Vector<Nation> nations = new Vector<Nation>();
		nations.add(new Nation("한국", "서울"));
		nations.add(new Nation("일본", "도쿄"));
		
		
		System.out.println("**** 수도 맞추기 게임을 시작합니다. ****");
		while(true) {
			System.out.print("입력:1, 퀴즈:2, 종료:3 >> ");
			order = sc.nextInt();
			if(order == 3) {
				System.out.println("종료하였습니다.");
				break;
			}
			else if(order == 1) {
				System.out.println("현재 " + nations.size() +"개 나라와 수도가 입력되어 있습니다.");
				while(true) {
					count = nations.size() + 1;
					System.out.print("나라와 수도 입력" + count + ">> ");
					total = sc.next();
					if(total.equals("그만")) {
						break;
					}
					else {
						StringTokenizer str = new StringTokenizer(total,",");
						country = str.nextToken().trim();
						System.out.println(country);
						capital = str.nextToken().trim();
						System.out.println(capital);
						for(int i = 0; i < nations.size(); i++) {
							if(country.equals(nations.elementAt(i).country)) {
								System.out.println(country +"는 이미 있습니다!");
								break;
							}
						}
						nations.add(new Nation(country, capital));
					}					
				}				
			}
			else if(order == 2) {
				for(int i = 0; i < nations.size(); i++) {
					System.out.print(nations.elementAt(i).country + "의 수도는? ");
					country = sc.next();
					if(country.equals(nations.elementAt(i).capital)) {
						System.out.println("정답");
					}
					else {
						System.out.println("아닙니다!!");
					}					
				}				
			}
		}
	}
}

(2)

package Javava;
import java.util.*;

public class StackManageer {
	public static void main(String args[]) {
		Scanner sc = new Scanner(System.in);
		int order, count;
		String country, capital, total;
		HashMap<String, String> hm = new HashMap<String, String> ();

		hm.put("한국", "서울"); hm.put("일본", "도쿄");
		
		System.out.println("**** 수도 맞추기 게임을 시작합니다. ****");
		while(true) {
			System.out.print("입력:1, 퀴즈:2, 종료:3 >> ");
			order = sc.nextInt();
			if(order == 3) {
				System.out.println("종료하였습니다.");
				break;
			}
			else if(order == 1) {
				System.out.println("현재 " + hm.size() +"개 나라와 수도가 입력되어 있습니다.");
				while(true) {
					count = hm.size() + 1;
					System.out.print("나라와 수도 입력" + count + ">> ");
					total = sc.next();
					if(total.equals("그만")) {
						break;
					}
					else {
						StringTokenizer str = new StringTokenizer(total,",");
						country = str.nextToken().trim();
						capital = str.nextToken().trim();
						for(int i = 0; i < hm.size(); i++) {
							if(null != hm.get(country)) {
								System.out.println(country +"는 이미 있습니다!");
								break;
							}
						}
						hm.put(country, capital);
					}					
				}				
			}
			else if(order == 2) {
				Set<String> key = hm.keySet();
				Iterator<String> it = key.iterator();
				while(it.hasNext()) {					
					String coun1 = it.next();
					System.out.print(coun1 + "의 수도는? ");
					country = sc.next();
					if(country.equals(hm.get(coun1))) {
						System.out.println("정답");
					}
					else {
						System.out.println("아닙니다!!");
					}					
				}				
			}
		}
	}
}