관리 메뉴

거니의 velog

230824_컬렉션 프레임워크 3 본문

대덕인재개발원_자바기반 애플리케이션

230824_컬렉션 프레임워크 3

Unlimited00 2023. 8. 24. 19:09

[ListSortTest02.java]

package kr.or.ddit.basic;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

public class ListSortTest02 {

	public static void main(String[] args) {
		
		ArrayList<Member> memList = new ArrayList<Member>();
		
		memList.add(new Member(1, "홍길동", "010-1111-1111"));
		memList.add(new Member(5, "이순신", "010-2222-1111"));
		memList.add(new Member(9, "성춘향", "010-3333-1111"));
		memList.add(new Member(3, "강감찬", "010-4444-1111"));
		memList.add(new Member(6, "일지매", "010-5555-1111"));
		memList.add(new Member(2, "변학도", "010-6666-1111"));
		
		System.out.println("정렬전...");
		for(Member mem : memList) {
			System.out.println(mem);
		}
		
		System.out.println("--------------------------------------------");
		
		// Member의 num값의 내림차순으로 정렬하는 외부 정렬 기준 클래스를 이용하여 정렬하시오.
		// (클래스명 : SortNumDesc)
		
		// 외부 정렬 기준 클래스를 지정해서 정렬하기
		Collections.sort(memList, new SortNumDesc());
		
		System.out.println("num 기준 내림차순 정렬후...");
		for(Member mem : memList) {
			System.out.println(mem);
		}
		
		System.out.println("--------------------------------------------");
		
		Collections.sort(memList); 
		// 정렬 기준이 없는 상태에서, 멤버 변수가 3개라 오류
		// 각각의 정렬 기준이 있어야 한다.
		// class Member implements Comparable<Member> 로 정의하여 시작.
		// public int compare(Member mem1, Member mem2)를 재정의하면 오류 사라짐.
		
		System.out.println("이름 기준 오름차순 정렬후...");
		for(Member mem : memList) {
			System.out.println(mem);
		}
		
	}

}

// Member의 회원이름(name)을 기준으로 오름차순이 되도록 내부 정렬 기준 추가하기.
class Member implements Comparable<Member> {
	
	private int num;
	private String name;
	private String tel;
	
	// 생성자, alt+shift+s로 자동 생성.
	public Member() {}
	public Member(int num, String name, String tel) {
		this.num = num;
		this.name = name;
		this.tel = tel;
	}
	
	// getter, setter, alt+shift+s로 자동 생성.
	public int getNum() {
		return num;
	}
	
	public void setNum(int num) {
		this.num = num;
	}
	
	public String getName() {
		return name;
	}
	
	public void setName(String name) {
		this.name = name;
	}
	
	public String getTel() {
		return tel;
	}
	
	public void setTel(String tel) {
		this.tel = tel;
	}
	
	@Override
	public String toString() {
		return "Member [num=" + num + ", name=" + name + ", tel=" + tel + "]";
	}
	
	// 재정의 해야 할 내용 추가.
	// 내부 정렬 기준을 정해주는 메서드 (name의 오름차순 정렬 기준 만들기)
	// this로 자기 자신과 매개 변수를 비교.
	@Override
	public int compareTo(Member mem) {
		
//		if(this.getName().compareTo(mem.getName()) > 0) {
//			return 1;
//		}else if(this.getName().compareTo(mem.getName()) < 0) {
//			return -1;
//		}else {
//			return 0;
//		}
		
		return this.getName().compareTo(mem.getName());
		
	}
	
}

// SortNumDesc
class SortNumDesc implements Comparator<Member> {
	
	// compare() 메서드의 매개변수는 서로 인접한 2개의 데이터가 저장된다고 가정하여 처리한다.
	
	// compare() 메서드의 반환값의 의미
	// 반환값이 '0'이라면 두 값이 같다. (순서는 바뀌지 않는다.)
	// 반환값이 양수일 경우에는 앞, 뒤의 순서를 바꾼다.
	// 반환값이 음수일 경우에는 순서를 바꾸지 않는다.
	
	// 예) 오름차순 정렬일 경우 ==> 앞의 값이 크면 양수, 같으면 0, 앞의 값이 작으면 음수를 반환하도록 구현한다.
	@Override
	public int compare(Member mem1, Member mem2) {
		
//		Integer num1 = mem1.getNum();
//		Integer num2 = mem2.getNum();
//		
//		// 내림차순으로 구현하려 한다.
//		if(num1.compareTo(num2) > 0) {
//			return -1; // 앞의 수가 크고 뒤의 수가 작으므로 내림차순일 경우 순서를 바꾸면 안 된다.
//		}else if(num1.compareTo(num2) < 0) {
//			return 1; // 앞의 수가 작고 뒤의 수가 크므로 내림차순일 경우 순서를 바꿔야 한다.
//		}else {
//			return 0; // 두 값이 같으므로 순서를 바꾸지 않는다.
//		}
		
		/////////////////////////////////////////////
		
		// Member의 num 값으로 내림차순 정렬
//		if(mem1.getNum() > mem2.getNum()) {
//			return -1;
//		}else if(mem1.getNum() < mem2.getNum()) {
//			return 1;
//		}else {
//			return 0;
//		}
		
		// Wrapper클래스를 이용하는 방법1
//		return new Integer(mem1.getNum()).compareTo(new Integer(mem2.getNum())) * -1;
		
		// Wrapper클래스를 이용하는 방법2
		return Integer.compare(mem1.getNum(), mem2.getNum()) * -1;
		
	}
	
}


[StudentTest.java]

package kr.or.ddit.basic;

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

/*
 * 문제) 학번(int), 이름, 국어점수, 영어점수, 수학점수, 총점, 등수를 멤버로 갖는 Student 클래스를 만든다.
 *      이 클래스의 생성자에서는 학번, 이름, 국어점수, 영어점수, 수학점수만 매개변수로 받아서 초기화한다.
 *      (이 때 총점은 세 과목의 점수를 이용해서 초기화한다.)
 *      
 *      이 Student객체는 List에 저장하여 관리한다.
 *      
 *      List에 저장된 데이터들을 학번의 오름차순으로 정렬할 수 있는 내부 정렬 기준을 구현하고,
 *      총점의 역순으로 정렬하는데 총점이 같으면 이름의 오름차순으로 정렬이 되는 외부 정렬 기준 클래스를 작성하여
 *      정렬한 결과를 출력하시오.
 *      
 *      (등수는 List에 전체 데이터가 추가된 후에 구해서 저장한다.) ==> StudentTest클래스에서 처리한다.
 */
public class StudentTest {
	
	// 등수를 구하는 메서드
	public void createRank(List<Student> list) {
		for(Student std1 : list) { // 등수를 구할 기준 데이터를 구하기 위한 반복문
			int rank = 1; // 처음에는 1등으로 설정해 놓고 시작한다.
			for(Student std2 : list) { // 비교 대상을 나타내는 반복문
				if(std1.getSum() < std2.getSum()) { // 기준값보다 큰 값을 만나면 rank변수의 값을 1씩 증가시킨다.
					rank++;
				}
			}
			// 구해진 등수를 기준 데이터의 rank 변수에 저장한다.
			std1.setRank(rank);
		}
	}

	public static void main(String[] args) {
		
		ArrayList<Student> studentList = new ArrayList<Student>();
		
		studentList.add(new Student(1, "홍길동", 100, 90, 80));
		studentList.add(new Student(9, "성춘향", 80, 70, 60));
		studentList.add(new Student(6, "일지매", 1, 5, 2));
		studentList.add(new Student(5, "이순신", 80, 70, 60));
		studentList.add(new Student(2, "변학도", 99, 100, 100));
		studentList.add(new Student(3, "강감찬", 12, 35, 67));
		studentList.add(new Student(7, "박서방", 80, 70, 60));
		
		// 등수를 구하는 메서드 호출하기
		new StudentTest().createRank(studentList);
		
		System.out.println("정렬 전...");
		for(Student stu : studentList) {
			System.out.println(stu);
		}
		
		System.out.println("--------------------------------------------");
		
		Collections.sort(studentList);
		
		System.out.println("학번의 오름차순 정렬 후...");
		for(Student stu : studentList) {
			System.out.println(stu);
		}
		
		System.out.println("--------------------------------------------");
		
		Collections.sort(studentList, new StudentSumDesc());
		
		System.out.println("총점의 내림차순 정렬 후... 동점일 경우 이름의 오름차순 정렬 후...");
		for(Student stu : studentList) {
			System.out.println(stu);
		}
		
	}

}

class Student implements Comparable<Student> {
	
	private int stuNo;
	private String stuNm;
	private int korScore;
	private int engScore;
	private int mathScore;
	private int sum;
	private int rank;
	
	public Student() {}
	public Student(int stuNo, String stuNm, int korScore, int engScore, int mathScore) {
		this.stuNo = stuNo;
		this.stuNm = stuNm;
		this.korScore = korScore;
		this.engScore = engScore;
		this.mathScore = mathScore;
		sum = korScore + engScore + mathScore;
	}
	
	public int getStuNo() {
		return stuNo;
	}
	
	public void setStuNo(int stuNo) {
		this.stuNo = stuNo;
	}
	
	public String getStuNm() {
		return stuNm;
	}
	
	public void setStuNm(String stuNm) {
		this.stuNm = stuNm;
	}
	
	public int getKorScore() {
		return korScore;
	}
	
	public void setKorScore(int korScore) {
		this.korScore = korScore;
	}
	
	public int getEngScore() {
		return engScore;
	}
	
	public void setEngScore(int engScore) {
		this.engScore = engScore;
	}
	
	public int getMathScore() {
		return mathScore;
	}
	
	public void setMathScore(int mathScore) {
		this.mathScore = mathScore;
	}
	
	public int getSum() {
		return sum;
	}
	
	public void setSum(int sum) {
		this.sum = sum;
	}
	
	public int getRank() {
		return rank;
	}
	
	public void setRank(int rank) {
		this.rank = rank;
	}
	
	@Override
	public String toString() {
		return "Student [stuNo=" + stuNo + ", stuNm=" + stuNm + ", korScore=" + korScore + ", engScore=" + engScore
				+ ", mathScore=" + mathScore + ", sum=" + sum + ", rank=" + rank + "]";
	}
	
	// 학번의 오름차순으로 정렬하는 내부 정렬 기준 구현
	@Override
	public int compareTo(Student stu) {
		return Integer.compare(this.getStuNo(), stu.getStuNo());
	}
	
}

class StudentSumDesc implements Comparator<Student> {
	
	@Override
	public int compare(Student stu1, Student stu2) {
		if(stu1.getSum() == stu2.getSum()) {
			return stu1.getStuNm().compareTo(stu2.getStuNm()); // 이름 기준 오름차순
		}else {
			return Integer.compare(stu1.getSum(), stu2.getSum()) * -1; // 총점 기준 내림차순
		}
	}
	
}


[SetTest.java]

package kr.or.ddit.basic;

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

public class SetTest {

	public static void main(String[] args) {
		
		/*
		 * - List와 Set의 차이점
		 * 1. List
		 * 	  - 데이터의 순서(index)가 있다. 
		 *    - 중복되는 데이터를 저장할 수 있다.
		 *    
		 * 2. Set
		 * 	  - 데이터의 순서(index)가 없다.
		 *    - 중복되는 데이터를 저장할 수 없다.
		 */
		
		HashSet hs1 = new HashSet();
		
		// Set에 데이터 추가하기 ==> add()메서드를 이용한다.
		hs1.add("DD");
		hs1.add("AA");
		hs1.add(2);
		hs1.add("CC");
		hs1.add("BB");
		hs1.add(1);
		hs1.add(3);
		
//		System.out.println("set 데이터 ==> " + hs1.toString()); // set 데이터 ==> [DD, AA, CC, BB, 1, 2, 3]
		System.out.println("set 데이터 ==> " + hs1); // 출력하는 순서를 보면 추가한 순서와 분명 다르다.
		System.out.println("set의 개수 ==> " + hs1.size()); // set의 개수 ==> 7
		
		System.out.println();
		System.out.println("--------------------------------------");
		System.out.println();
		
		// Set에 중복되는 데이터를 추가하면 false를 반환하고 데이터는 추가되지 않는다.
		boolean isAdd = hs1.add("FF");
		System.out.println("중복되지 않을 때 isAdd = " + isAdd); // 중복되지 않을 때 isAdd = true
		System.out.println("set 데이터 ==> " + hs1); // set 데이터 ==> [DD, AA, CC, BB, FF, 1, 2, 3]
		System.out.println();
		
		isAdd = hs1.add("CC");
		System.out.println("중복될 때 isAdd = " + isAdd); // 중복될 때 isAdd = false
		System.out.println("set 데이터 ==> " + hs1); // set 데이터 ==> [DD, AA, CC, BB, FF, 1, 2, 3]
		
		System.out.println();
		System.out.println("--------------------------------------");
		System.out.println();
		
		// Set의 데이터를 수정하려면 수정하려는 명령이 따로 없기 때문에 
		// 해당 자료를 삭제한 후 추가해 주는 방법을 사용한다.
		
		// 삭제하는 메서드 ==> remove(삭제할자료)
		//				    반환값 : 삭제성공(true), 삭제실패(false)
		// 전체 자료 삭제   ==> clear()
		
		// "FF"데이터를 "EE"로 변경하기
		hs1.remove("FF");
		System.out.println("삭제 후 set 데이터 ==> " + hs1); // 삭제 후 set 데이터 ==> [DD, AA, CC, BB, 1, 2, 3]
		hs1.add("EE");
		System.out.println("set 데이터 ==> " + hs1); // set 데이터 ==> [DD, AA, CC, BB, EE, 1, 2, 3]
		
//		hs1.clear();
//		System.out.println("clear명령 후 set 데이터 ==> " + hs1); // clear명령 후 set 데이터 ==> []
		
		System.out.println();
		System.out.println("--------------------------------------");
		System.out.println();
		
		/*
		 * Set의 데이터는 순서(index)가 없기 때문에 List처럼 index로 데이터를 하나씩 불러올 수 없다.
		 * 그래서 데이터를 하나씩 차례로 얻기 위해서는 Iterator형 객체로 변환해야 한다.
		 * 
		 * - Set형의 데이터들을 Iterator형의 객체로 변환하는 메서드 ==> iterator()
		 */
		
		Iterator it = hs1.iterator(); // Set 데이터를 Iterator로 변환하기
		
		// Iterator객체의 hasNext()메서드
		// 			==> Iterator의 포인터가 가리키는 곳 다음 번째에 데이터가 있는지 검사한다.
		//			    (데이터가 있으면 true, 데이터가 없으면 false를 반환한다.)
		System.out.println("Iterator를 이용한 데이터 출력하기...");
		while(it.hasNext()) {
			// Iterator객체의 next()메서드
			//	==> Iterator의 포인터를 다음번째 위치로 이동한 후, 이동한 위치의 데이터를 반환한다.
			System.out.println(it.next());
		}
		
//		Iterator를 이용한 데이터 출력하기...
//		DD
//		AA
//		CC
//		BB
//		EE
//		1
//		2
//		3
		
		System.out.println();
		System.out.println("향상된 for문 이용하기...");
		for(Object obj : hs1) {
			System.out.println(obj);
		}
		
//		향상된 for문 이용하기...
//		DD
//		AA
//		CC
//		BB
//		EE
//		1
//		2
//		3
		
		System.out.println();
		System.out.println("--------------------------------------");
		System.out.println();
		
		// 우리반 학생들 중 번호를 이용하여 추첨하는 프로그램을 작성해 보자
		// 번호는 1번부터 23번까지 있고, 추첨할 인원은 3명이다.
		// 당첨 번호를 출력해 보시오.
		
		// 최소값 부터 최대값 사이의 정수형 난수값 만들기
		// (int)(Math.random() * (최대값-최소값+1) + 최소값)
		
		HashSet<Integer> testSet = new HashSet<Integer>();
		while(testSet.size() < 3) {
			testSet.add((int)(Math.random() * 23 + 1));
		}
		System.out.println("당첨자 번호 : " + testSet); // 당첨자 번호 : [20, 9, 11], 난수이므로 실행 될 때마가 값이 다르다.
		
		System.out.println();
		System.out.println("--------------------------------------");
		System.out.println();
		
		// Set유형의 자료를 List형으로 변환하기
		ArrayList<Integer> testList = new ArrayList<Integer>(testSet);
		System.out.println("List 데이터 출력...");
		for(int i=0; i<testList.size(); i++) {
			System.out.println(i + "번째 자료 ==> " + testList.get(i));
		}
		
//		당첨자 번호 : [7, 10, 15]
//		List 데이터 출력...
//		0번째 자료 ==> 7
//		1번째 자료 ==> 10
//		2번째 자료 ==> 15
		
	}

}

[BaseBallTest.java]

package kr.or.ddit.basic;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Scanner;

/*
 * 문제 ) Set을 이용하여 숫자 야구 게임 프로그램을 작성하시오.
 * 		==> 컴퓨터의 숫자는 난수를 이용하여 구한다. (1 ~ 9 사이의 난수 3개)
 * 			(스트라이크는 S, 볼은 B로 나타낸다.)
 * 
 * 예시 ) 
 * 		컴퓨터의 난수 ==> 9 5 7
 * 		
 * 실행예시 )
 * 		숫자입력 >> 3 5 6
 * 		3 5 6 ==> 1S 0B
 * 		숫자입력 >> 7 8 9
 * 		7 8 9 ==> 0S 2B
 * 		숫자입력 >> 9 7 5
 * 		9 7 5 ==> 1S 2B
 * 		숫자입력 >> 9 5 7
 * 		9 5 7 ==> 3S 0B
 * 		
 * 		축하합니다...
 * 		당신은 4번만에 정답을 맞췄습니다...
 * 
 **************************************************
 * 
 * 		- 플레이어1 : 1, 2, 3
 * 		- 플레이어2 : 2, 4, 3
 * 		- 값이 같고 위치도 같으면 스트라이크
 * 		- 값이 같고 위치가 다르면 볼
 * 		- 1s 1b
 * 
 * 		- 플레이어1 : 2, 3, 1
 * 		- 0s 3b
 * 
 * 		- 플레이어1 : 1, 2, 3
 * 		- 3s 0b로 게임 종료.
 * 
 * 		- 컴퓨터가 문제를 내고 사람이 맞추는 방식으로 바꾸는 것.
 * 		- 컴퓨터는 1~9 사이의 서로 다른 숫자를 3개 만들어야 한다.
 */
public class BaseBallTest {

	static Scanner sc = new Scanner(System.in);
	
	public static void main(String[] args) {
		
		ComputerThrowBall cpu = new ComputerThrowBall();
		ArrayList<Integer> randBall = cpu.randThrowBall();
		
		System.out.println(randBall.toString()); // 테스트 코드
		
		int cnt = 0;
		while(true) {
			int strike = 0;
			int ball = 0;
			ArrayList<Integer> userBall = new ArrayList<Integer>();
			System.out.print("숫자입력 >> ");
			String userStr = sc.nextLine();
			String[] userSplitStr = userStr.split(" ");
			for(String userBallNum : userSplitStr) {
				userBall.add(Integer.parseInt(userBallNum));
			}
//			System.out.println(userBall); // 테스트 코드
			
			for(int i=0; i<randBall.size(); i++) {
				for(int j=0; j<userBall.size(); j++) {
					if(randBall.get(i).equals(userBall.get(j))) {
						if(randBall.indexOf(userBall.get(j)) == userBall.indexOf(randBall.get(i))) {
//							System.out.println("스트라이크 ");
							strike++;
//							System.out.println("strike : " + strike);
						}else {
//							System.out.println("볼 ");
							ball++;
//							System.out.println("ball : " + ball);
						}
					}
				}
			}
			cnt++;
			
//			System.out.println("cnt : " + cnt);
			System.out.println(userBall.get(0) + " " + userBall.get(1) + " " + userBall.get(2) + " ==> " + strike + "S " + ball + "B");
			if(strike == 3 && ball == 0) break;
		}
		
		System.out.println("축하합니다...");
		System.out.println("당신은 "+cnt+"번만에 정답을 맞췄습니다...");
		
	}

}

class ComputerThrowBall {
	
	public ArrayList<Integer> randThrowBall() {
		HashSet<Integer> ballSet = new HashSet<Integer>();
		while(ballSet.size() < 3) {
			ballSet.add((int)(Math.random() * 9 + 1));
		}
		ArrayList<Integer> ballList = new ArrayList<Integer>(ballSet);
		return ballList;
	}
	
}