객체 배열

김찬희·2023년 2월 20일
0

KH정보교육원

목록 보기
7/27

▶ 객체배열

  • 객체 : new 연산자에 의해 클래스에 정의된 내용대로 메모리에 할당된 것
  • 배열 : 같은 자료형을 묶음으로 다루는 것

객체 참조형 변수를 저장하는 배열로 배열의 자료형을 클래스명(사용자 정의 자료형)으로 지정하여 활용

▶ 객체배열 선언과 할당

√ 선언
클래스명[] 배열명;
클래스명 배열명[];

ex) Academy[] arr;
	Academy arr[];

√ 할당
배열명 = new 클래스명[배열크기];

ex) arr = new Academy[5];

√ 선언과 동시에 할당
클래스명 배열명[] = new 클래스명[배열크기];

ex) Academy[] arr = new Academy[5];

▶ 객체배열 초기화

√ 인덱스를 이용한 초기화
배열명[i] = new 클래스명();

ex)
arr[0] = new Academy(1, "KH정보교육원");
arr[1] = new Academy(2, "케이에이치");

√ 선언과 동시에 할당 및 초기화
클래스명 배열명[] = {new 클래스명(), new 클래스명()};

ex)
Academy arr[] = {new Academy(1, "KH정보교육원"), new Academy(2, "케이에이치")};

▶ 객체배열 구조

Example arr[] = new Example[2];
arr[0] = new Example();
arr[1] = new Example();

package edu.kh.objectarray.run;

import edu.kh.objectarray.view.StudentView;
// 실행 클래스
public class StudentRun {

	public static void main(String[] args) {
		StudentView view = new StudentView();
		view.displayMenu();
		
//		1. static 읽기
//		2. main() 메서드 실행
//		3. StudentView() 객체 생성
//		4. Scanner, StudentService 객체 생성
//		5. Student[5] 배열 생성
//		기본 생성자 내용 수행
//		→ Student 객체 3개 생성 후
//		0, 1, 2 인덱스에 주소 대입
	}
}
package edu.kh.objectarray.dto;
// 학생 클래스
public class Student {

	// 필드 (캡슐화 원칙에 의해 모두 private)
	private int grade; // 학년
	private int classRoom;  // 반
	private int number;  // 번호
	private String name;  // 이름
	
	private int kor;  // 국어 점수
	private int eng;  // 영어 점수
	private int math;  // 수학 점수
	
	// 생성자
	public Student() {}  // 기본 생성자
	
	// 매개변수 생성자(오버로딩 적용)
	public Student(int grade, int classRoom, int number, String name) {
		// this 참조변수
		this.grade = grade;
		this.classRoom = classRoom;
		this.number = number;
		this.name = name;
	}
	
	// getter
	public int getGrade() {
		return grade;
	}
	// setter
	public void setGrade(int grade) {
		this.grade = grade;
	}
	
	public int getClassRoom() {
		return classRoom;
	}
	public void setClassRoom(int classRoom) {
		this.classRoom = classRoom;
	}
	
	public int getNumber() {
		return number;
	}
	public void setNumber(int number) {
		this.number = number;
	}
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	
	public int getKor() {
		return kor;
	}
	public void setKor(int kor) {
		this.kor = kor;
	}
	
	public int getEng() {
		return eng;
	}
	public void setEng(int eng) {
		this.eng = eng;
	}

	public int getmath() {
		return math;
	}
	public void setMath(int math) {
		this.math = math;
	}
	
	// 객체의 필드 값을 하나의 문자열 형태로 반환하는 메서드
	public String toString() {
		return String.format("%d학년 %d반 %d번 %s [%d, %d, %d]", grade, classRoom, number, name, kor, eng, math);
	}
}
package edu.kh.objectarray.view;

import java.util.Scanner;

import edu.kh.objectarray.dto.Student;
import edu.kh.objectarray.service.StudentService;

public class StudentView {
		
	// 필드
	private Scanner sc = new Scanner(System.in);
		
	private StudentService service = new StudentService(); 
		
		
		
	public void displayMenu() {
			
			int input = 0;
			
			do {
				System.out.println("---- [학생 관리 프로그램] -----");
				System.out.println("1. 학생 추가");
				System.out.println("2. 학생 전체 조회");
				System.out.println("3. 학생 정보 조회(인덱스)");
				System.out.println("4. 학생 정보 조회(이름)");
				System.out.println("5. 학생 정보 수정(인덱스)");
				System.out.println("6. 점수 합계, 평균, 최고점, 최저점");
				System.out.println("0. 종료");
				System.out.println("-------------------------------");
				
				System.out.print("메뉴 선택 : ");
				input = sc.nextInt();
				
				System.out.println();
				
				switch(input) {
				case 1: addStudent(); break;
				case 2: selectAll(); break;
				case 3: selectIndex(); break;
				case 4: selectName(); break;
				case 5: updateStudent(); break;
				case 6: sumAvgMaxMin(); break;
				case 0: System.out.println("[프로그램 종료됩니다.]"); break;
				default: System.out.println("[잘못 입력 하셨습니다.]");
				}
				System.out.println();
				
			}while(input != 0);
		}

	/** 1. 학생 추가 */ 
	private void addStudent() {
		
		System.out.println("[학생 추가]");
		
		System.out.print("학년 : ");
		int grade = sc.nextInt();
		
		System.out.print("반 : ");
		int classRoom = sc.nextInt();
		
		System.out.print("번호 : ");
		int number = sc.nextInt();
		
		System.out.print("이름 : ");
		String name = sc.next();
		
		// 학생 추가 서비스 호출
		boolean result = service.addStudent(grade, classRoom, number, name);
		if(result) {  // true인 경우 == 학생 추가 성공
			System.out.println(name + "학생이 추가되었습니다!");
		} else {  // false인 경우 == 학생 추가 실패
			System.out.println("더 이상 학생을 추가할 수 없습니다.");
		}
	}
	
	/** 2. 학생 전체 조회 */
	private void selectAll() {
		
		System.out.println("[학생 전체 조회]");
		
		// service가 참조하는 객체의 필드 중 studentArr를 반환 받아
		// 각 배열 요소를 화면에 출력
		
		// ************************************************
		// 매개변수, 반환값으로 참조변수가 사용될 경우
		// 참조하고 있는 주소가 복사된다! → 얕은 복사
		// ************************************************
		Student[] studentList = service.selectAll();
		for(int i=0;i<studentList.length;i++) {

			if(studentList[i] == null) {
				break;  // 참조하는 객체가 없으면 반복 종료
			}
				
			// Student 객체가 가지고 있는 toString() 메서드를 호출해서
			// 학생 정보를 문자열로 반환 받아 출력
			System.out.println(studentList[i].toString());
			
			// NullPointException
			// → 참조하고 있는 객체가 없는
			//   참조변수를 이용해서
			//   필드/메서드를 호출할 때 발생하는 에러(예외)
			
			// 해결방법 : 참조변수가 null인지 여부를 먼저 검사
		}
	} 

	/** 3. 학생 정보 조회(인덱스) */
	private void selectIndex() {
		System.out.println("[학생 정보 조회(인덱스)]");
		
		System.out.print("조회할 학생의 인덱스 번호를 입력하세요 : ");
		int index = sc.nextInt();
		
		// index에 해당하는 배열요소를 얻어와 저장
		Student std = service.selectIndex(index);
		
		// 반환받은 index번째 요소가 null이 아닐 경우(학생 정보 있을 경우)
		// → NullPointerException 방지 처리
		
		if(std != null) {
			System.out.println(std.toString());
		} else {
			System.out.println("해당 인덱스에 학생 정보가 존재하지 않습니다.");
		}
		
	}
	
	/** 4. 학생 정보 조회(이름) */
	private void selectName() {
		System.out.println("[학생 정보 조회(이름)]");
		
		System.out.print("조회할 학생의 이름 : ");
		String inputName = sc.next();
		
		// 학생 정보 조회(이름) 서비스 호출
		Student[] resultArr = service.selectName(inputName);
		
		// 이름이 일치하는 학생이 있을 경우
		if(resultArr != null) {
			
			// * 향상된 for문 *
			// for(배열에 꺼낸 요소 하나를 저장할 변수 : 배열명) {}
			// → 배열에서 꺼내는 순서는 0부터 1씩 증가하여 마지막 인덱스까지
			// == 순차 접근(반복 접근)
			//    → 모든 요소에 접근
			
			for(Student s : resultArr) {
				// s : resultArr의 요소가 for문 반복마다 하나씩 저장되는 변수
				if(s == null) break;
				// if/ else if / else / for / while 등
				// {} 블록을 작성하는 구문에서 {} 블록을 생략하면
				// 다음 한 줄에만 해당 구문을 적용!
				// (한 줄의 기준은 세미콜론 전 까지)
				System.out.println(s.toString());
			}
			
			
		} else {  // 없을 경우
			System.out.println("이름이 일치하는 학생이 없습니다.");
		}
		
	}

	/** 5. 학생 정보 수정(인덱스) */
	private void updateStudent() {
		
		System.out.println("[5. 학생 정보 수정(인덱스)]");
		System.out.print("인덱스 : ");
		int index = sc.nextInt();
		
		System.out.print("국어 : ");
		int kor = sc.nextInt();
		
		System.out.print("영어 : ");
		int eng = sc.nextInt();
		
		System.out.print("수학 : ");
		int math = sc.nextInt();
		
		// 입력 받은 index 번째 학생의 점수를 수정하는 서비스 호출
		// - 수정 성공 시 true / 아니면 false
		
		boolean result = service.updateStudent(index, kor, eng, math);
		
		// 수정 결과에 따라 출력 구문 제어하기
		if(result) System.out.println("수정되었습니다.");
		else System.out.println("해당 인덱스에 학생이 존재하지 않습니다.");
		
	}
	
	/** 6. 점수 합계, 평균, 최고점, 최저점 */
	private void sumAvgMaxMin() {
		System.out.println("[점수 합계, 평균, 최고점, 최저점]");
		
		int[] arr = service.sumAvgMaxMin();
		// 0번 인덱스 : 합계
		// 1번 인덱스 : 평균
		// 2번 인덱스 : 최고점
		// 3번 인덱스 : 최저점
		
		System.out.println("합계 : " + arr[0]);
		System.out.println("평균 : " + arr[1]);
		System.out.println("최고점 : " + arr[2]);
		System.out.println("최저점 : " + arr[3]);
	}

}
package edu.kh.objectarray.service;

import java.util.Arrays;
import java.util.Random;

import edu.kh.objectarray.dto.Student;

// 기능 제공용 클래스(비즈니스 로직 처리)
public class StudentService {

	// ctrl + shift + o : import 자동 추가
	
	// Student 객체 참조변수 5개짜리 배열을 생성해서 studentArr 참조
	private Student[] studentArr = new Student[5];
	
	// StudentService 기본 생성자
	public StudentService() {
		
		// studentArr 배열의 각 요소는 Student 참조 변수
		studentArr[0] = new Student(3, 5, 17, "홍길동");
		studentArr[1] = new Student(2, 3, 11, "김철수");
		studentArr[2] = new Student(1, 7, 3, "최미영");
		
	    // 학생 랜덤 점수 추가
	    Random random = new Random();
	    for(Student s : studentArr) {
	         
		    if(s == null) break;
		         
		    // (int)(Math.random() * 101) == random.nextInt(101);
		    s.setKor(random.nextInt(101));
		    s.setEng(random.nextInt(101));
		    s.setMath(random.nextInt(101));
	    }
	      
		
	}
	
	// param(parameter) : 매개변수
	
	/** 1. 학생 추가 서비스 
	 * @param grade : int
	 * @param classRoom : int
	 * @param number : int
	 * @param name : String
	 * 
	 * @return result : boolean (학생 추가 성공 시 true)
	 * */
	public boolean addStudent(int grade, int classRoom, int number, String name) {
		// studentArr에서 비어있는 인덱스를 찾아
		// 해당 인덱스에 매개변수를 이용해서 생성된 Student 객체 주소를 대입
		// → true 반환
		for(int i=0;i<studentArr.length;i++) {
			
			//배열 요소가 참조하는 주소가 없을 경우 = 비어있다고 판단
			if(studentArr[i] == null) {
				// 비어있는 배열 요소에
				// 매개변수를 이용해서 새 학생 객체를 만들어 주소 대입
				studentArr[i] = new Student(grade, classRoom, number, name);
				return true;
			}
		}
		// 만약 비어있는 인덱스가 없을 경우
		// → false 반환
		return false;
	}
	
	/** 2. 학생 전체 조회 서비스
	 * @return StudentArr : Student[]
	 * */
	public Student[] selectAll() {
		// studentArr를 반환
		return studentArr;
	}
	
	/**3. 학생 정보 조회(인덱스) 
	 * @param index : int
	 * 
	 * @return studentArr[index] : Student 참조변수
	 * */
	public Student selectIndex(int index) {
		// index 값이 0~4 사이가 아니면
		// 배열 범위를 초과 했다는 ArrayIndexOutOfBoundsException 발생
		
		// 해결 방법 : 배열 범위가 넘어선 경우에 대한 별도 처리
		
		//if(index<0||index>=studentArr.length)
		if(!(index>=0 && index<=4)) {
			return null;
		}
		return studentArr[index];
	}
	
	/** 4. 학생 정보 조회(이름) 서비스
	 * @param inputName : String
	 * 
	 * @return resultArr : Student[] (조회된 학생이 없을 경우 null)
	 * */
	public Student[] selectName(String inputName) {

		// 이름이 일치하는 학생 모두를 저장할 객체배열 선언 및 초기화
		Student[] resultArr = new Student[studentArr.length];
		
		int index = 0;  // resultArr에 값을 대입할 인덱스를 나타내는 변수
		
		// studentArr에서 이름이 일치하는 학생 찾기
		for(int i=0;i<studentArr.length;i++) {
			
			// studentArr[i]가 null인지 검사
			if(studentArr[i] == null) {
				break;  // NullPointerException 방지를 위해 반복 종료
			}
			
			// i번째 요소의 name과 입력 받은 inputName이 같을 경우
			if(studentArr[i].getName().equals(inputName)) {
				
				// resultArr에 studentArr[i]의 값(주소)를 대입 (얕은 복사)
				resultArr[index++] = studentArr[i];
				// → studentArr[i] 값 대입 후 index 값 증가(후위 연산)
			}
		}
		if(index == 0) {
			return null;  // null 반환
		}
		
		return resultArr;
	}
	
	/** 5. 학생 정보 수정(인덱스) 서비스
	 * @param index : int
	 * @param kor : int
	 * @param eng : int
	 * @param math : int
	 * 
	 * @return 수정 성공 시 true / 실패 시 false
	 * */
	public boolean updateStudent(int index, int kor, int eng, int math) {
		if(index<0||index>4||studentArr[index] == null) return false;
		// 문제가 없을 경우 index번째 학생의 점수를 수정 후 true 반환
		studentArr[index].setKor(kor);
		studentArr[index].setEng(eng);
		studentArr[index].setMath(math);
		return true;
	}
	
	/** 6. 학생 총점 합계, 평균, 최고점, 최저점
	 * @return arr : int[] (인덱스 순서대로 합계, 평균, 최고점, 최저점 
	 * */
	
	public int[] sumAvgMaxMin() {
		int[] arr = new int[4];
		int index = 0;
		while(studentArr[index] != null) {
			index++;
		}
		int[] score = new int[index];
		for(int i=0;i<score.length;i++) {
			if(studentArr[i]==null) {
				break;
			}
			score[i] = studentArr[i].getKor() + studentArr[i].getEng() + studentArr[i].getmath();
			arr[0] += score[i];
		}
		arr[1] = arr[0]/score.length;
		arr[2] = score[0];
		arr[3] = score[0];
		for(int i=0;i<score.length;i++) {
			if(score[i]>arr[2]) {
				arr[2] = score[i];
			}
			if(score[i]<arr[3]) {
				arr[3] = score[i];
			}
		}
		System.out.println(Arrays.toString(score));
		return arr;
	}
}
profile
김찬희입니다.

0개의 댓글