컬렉션
List<Student> studentList = new ArrayList<Student>();
List<Student> studentList = new LinkedList<Student>();
List.add(Object e): 리스트에 객체 추가
(여러 타입의 데이터 저장할 수 있음) (add() 무조건 true 값)
배열에서
arr[i] = new Person(......)과 비슷한 역할
studentList.add(new Student ("유저일", 22, "인천시 계양구", 'M', 50));
studentList.add(sc);
List.get(index i): i번째 인덱스에 있는 값 반환
배열에서
print(arr[i])와 비슷한 역할
studentList.get(0)
int List.size(): List에 저장된 데이터 개수 얻어오기
배열에서
배열명.length와 비슷한 역할
if(studentList.size() == 0)
List.isEmpty(): List가 비어있으면 true
List.get(index i) == null 쓰지 않음
if(studentList.isEmpty())
List.set(int index, 자료형 e): List의 i번째 요소를 전달받은 e로 변경
-> 반환값에는 변경 전 객체가 담겨있음
Student temp = studentList.set(index, new Student(name, age, region, gender, score)); //기존 정보 temp에 담기
List.remove(int index): List에서 index번째 요소 제거 (이때 제거된 요소 반환)
-> List는 중간에 비어있는 인덱스를 없게 하기 위해 remove() 동작 시 뒤쪽 요소를 한 칸씩 당겨온다.
Student temp = studentList.remove(index); //기존 정보 temp에 담기
String.contains(문자열): String에 문자열이 포함되어 있으면 true, 아니면 false (사용 시 순서 주의)
std.getName().contains(input)
향상된 for문
컬렉션, 배열의 모든 요소를 순차적(0번 인덱스부터 마지막 요소까지 인덱스를 1씩 증가)으로 반복, 접근할 수 있는 for문
[작성법]
for(컬렉션 or 배열에서 꺼낸 한 개의 요소를 저장할 변수 : 컬렉션명 or 배열명) {}
package edu.kh.collection.model.vo;
public class Student {
//필드
private String name;
private int age;
private String region;
private char gender;
private int score;
//생성자
public Student() {}
public Student(String name, int age, String region, char gender, int score) {
this.name = name;
this.age = age;
this.region = region;
this.gender = gender;
this.score = score;
}
//메소드
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getRegion() {
return region;
}
public void setRegion(String region) {
this.region = region;
}
public char getGender() {
return gender;
}
public void setGender(char gender) {
this.gender = gender;
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
//toString() 오버라이딩 자동완성
//alt shift S S(Generate toString()) enter
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + ", region=" + region + ", gender=" + gender + ", score="
+ score + "]";
}
}
package edu.kh.collection.model.service;
import java.util.ArrayList;
import java.util.InputMismatchException;
import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;
import edu.kh.collection.model.vo.Student;
public class StudentService {
//필드
private Scanner sc = new Scanner(System.in);
//학생 정보를 저장할 List(객체 배열의 Upgrade 버전)
//import java.util.List; 인터페이스: List에 반드시 필요한 필수 기능을 모아둔 인터페이스
// *인터페이스는 객체 생성 불가 , but 부모 참조변수로 사용 가능
// List studentList = new List();
//인터페이스는 모든 메소드가 추상 메소드(미완성 메소드)
//미완성된 부분이 존재하는 클래스이기 때문에 객체 생성 불가
//ArrayList() 기본생성자: 기본 크기가 10칸짜리 리스트 생성
// --> 하지만 리스트는 크기가 변동하기 때문에 큰 의미 없음
//ArrayList(용량): 용량만큼의 리스트를 생성
// --> 너무 큰 값을 작성하면 메모리를 많이 소모함
// private List<Student> studentList = new ArrayList<Student>(); //검색(조회)에 효율적
private List<Student> studentList = new LinkedList<Student>(); //추가 수정 삭제에 효율적
//Student로 저장되는 타입이 제한된 리스트 생성
// == Student만 저장 가능 == 모든 게 Student
// == Student 임을 검사할 필요 없음
public StudentService() {
studentList.add(new Student ("박서준", 25, "서울시 중구", 'M', 90));
studentList.add(new Student ("정해인", 23, "서울시 강남구", 'M', 80));
studentList.add(new Student ("박보영", 20, "서울시 종로구", 'F', 90));
studentList.add(new Student ("김민서", 33, "대전 서구", 'F', 100));
studentList.add(new Student ("유저일", 22, "인천시 계양구", 'M', 50));
}
public void ex() {
//List 테스트
//List.add(Object e): 리스트에 객체를 추가
// *매개변수 타입이 Object == 모든 객체를 매개변수로 전달할 수 있다.
// (매개변수 Object == 최상위 부모 참조 변수 == 다형성 적용 가능)
studentList.add(new Student()); //0번 인덱스
// studentList.add(sc); //1번 인덱스
// studentList.add("문자열"); //2번 인덱스
// studentList.add( new Object()); //3번 인덱스
// -> 컬렉션 특징: 여러 타입의 데이터 저장할 수 있다.
//(반환형)
//Object List.get(index i): 리스트에서 i번째 인덱스에 있는 객체(Object)를 반환
//반환형이 Object == 모든 객체를 반환할 수 있다.
System.out.println(studentList.get(0)/*.toString()*/);
//결과: Student [name=null, age=0, region=null, gender=
// 실행 전: java.lang.Object.toString() == 정적 바인딩
// 실행 후: 0번째에는 Student 객체이고, toString()이 오버라이딩 되어있다.
// -> Student의 toString()이 수행됨 == 동적 바인딩
//Student의 이름만 얻어오기
//Student 객체가 맞는지 확인하고 다운 캐스팅을 해야
//Student 기능을 사용할 수 있다.
if(studentList.get(0) instanceof Student) {
System.out.println("Student 타입 맞아요");
}
// -> 길고 복잡
// --> 컬렉션의 장점인 여러 객체 저장이 코딩에 방해됨
//=========> 제네릭스 (Generics)
//(보통은 제네릭이라고 함) <>
//[제일 중요한 역할]
// -> 컬렉션에 저장되는 객체 타입을 한 가지로 제한해줌
System.out.println(studentList.get(0).getName()); //제네릭 후
System.out.println(((Student)studentList.get(0)).getName()); //제네릭 전
//getName은 Student 메소드라서 Student로 강제 형변환 (다운 캐스팅)
//(.은 우선 연산자라 () 괄호로 묶음)
}
//메소드 설명용 주석
/**
* 메뉴 출력용 메소드
* @author user1
* */
public void displayMenu() { //alt shift J 누르면 설명용 주석 자동 완성
int menuNum = 0;
do {
System.out.println("\n====학생 관리 프로그램====");
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.print("\n메뉴 번호 선택 >> ");
try {
menuNum = sc.nextInt();
System.out.println();
switch(menuNum) {
case 1 : System.out.println(addStudent()); break;
case 2 : selectAll(); break;
case 3 : System.out.println(upDateStudent()); break;
case 4 : System.out.println(removeStudent()); break;
case 5 : searchName1(); break;
case 6 : searchName2(); break;
case 0 : System.out.println("<프로그램 종료>"); break;
default : System.out.println("메뉴에 작성된 번호만 입력해주세요.");
}
}catch(InputMismatchException e) {
System.out.println("\nerror: 입력 형식이 유효하지 않습니다. 다시 시도해주세요.");
sc.nextLine(); //입력버퍼에 잘못 입력된 문자열 비우기
menuNum = -1;
//첫 반복 시 잘못 입력하는 경우, menuNum 값이 0이라서 종료되는데
//이를 방지하기 위해 -1 대입
}
}while(menuNum != 0);
}
/**
* 1. 학생 정보 추가 메소드
* - 추가 성공 시 "성공", 실패 시 "실패" 문자열 반환
*/
public String addStudent() throws InputMismatchException {
System.out.println("=====학생 정보 추가=====");
System.out.print("이름: ");
String name = sc.next();
System.out.print("나이: ");
int age = sc.nextInt();
sc.nextLine();
System.out.print("사는 곳: ");
String region = sc.nextLine();
System.out.print("성별(M/F): ");
char gender = sc.next().charAt(0);
// String -> char
System.out.print("점수: ");
int score = sc.nextInt(); //정수가 아닌 값 입력 InputMismatchException
// 이미 displayMenu(호출한 곳)에서 동일 예외 처리하고 있으니 throws로 던져줌
//Student 객체 생성 후 List에 추가
if(studentList.add(new Student(name, age, region, gender, score))) {
//boolean java.util.List.add(Student e)
//(반환형) --> 제네릭 <Student> 때문에 List 타입이 Student로 제한됨
//add() 무조건 true를 반환하기 때문에
//실패하는 경우는 없음
//대신, 예외가 발생해서 add() 수행 전 메소드가 종료될 순 있음
return "성공";
}else {
return "실패";
}
}
/**
* 2. 학생 전체 조회 메소드
*/
public void selectAll() {
//-List는 인덱스가 있다.(0부터)
//-List에 저장된 데이터의 개수를 얻어오는 방법: int List.size()
//cf) 배열명.length 대신 사용
//List가 비어있는지 확인하는 방법
//boolean List.isEmpty(): 비어있으면 true 반환
System.out.println("=====학생 전체 조회=====");
//studentList가 비어있는 경우 "학생 정보가 없습니다." 출력
// if(studentList.size() == 0) { //null 쓰지 않음
if(studentList.isEmpty()) {
System.out.println("학생 정보가 없습니다.");
return; //현재 메소드를 종료하고 호출한 곳으로 돌아감
//단, 반환값은 없음(void)
//else 대신 작성
}
/* 일반적인 for문
for(int i =0; i<studentList.size(); i++) {
System.out.println(studentList.get(i));
//studentList에서 i번째 인덱스 요소 출력
}
*/
//향상된 for문(for each문)
//-컬렉션, 배열의 모든 요소를 순차적으로 반복 접근할 수 있는 for문
// (순차적: 0번 인덱스부터 마지막 요소까지 인덱스를 1씩 증가)
//[작성법]
// for(컬렉션 또는 배열에서 꺼낸 한 개의 요소를 저장할 변수: 컬렉션명 or 배열명) {}
int index = 0;
for(Student std : studentList) {
//std에는 for문 반복마다 0, 1, 2, ... 인덱스 요소들 한 번씩 저장
System.out.print((index++)+ "번: ");
System.out.println(std);
}
}
/**
* 3. 학생 정보 수정 메소드
*/
public String upDateStudent() throws InputMismatchException{
// -Student List.set(int index, Student e)
// -> List의 i번째 요소를 전달받은 e로 변경
// -> 반환값 Student == 변경 전 Student 객체가 담겨있음
System.out.println("=====학생 정보 수정=====");
System.out.print("인덱스 번호 입력: ");
int index = sc.nextInt();
sc.nextLine();
//1) 학생 정보가 studentList에 있는가?
if(studentList.isEmpty()) { //비어있을 경우
return "입력된 학생 정보가 없습니다.";
//2) 입력된 숫자가 0보다 작은가?(음수 검사)
} else if(index<0) {
return "음수는 입력할 수 없습니다.";
//3) 만약 문자열을 입력한 경우 -> throws로 예외 처리
//4) 입력받은 숫자가 studentList 범위 내 인덱스 번호인가?
} else if(index>=studentList.size()) {
return "범위를 넘어선 값을 입력할 수 없습니다.";
} else {
//수정 코드 작성
System.out.println(index + "번째 인덱스에 저장된 학생 정보");
System.out.println(studentList.get(index));
//전에 저장되어 있던 정보 출력
System.out.print("이름 : ");
String name = sc.next();
System.out.print("나이 : ");
int age = sc.nextInt();
sc.nextLine(); // 입력 버퍼 개행 문자 제거
System.out.print("사는곳 : ");
String region = sc.nextLine();
System.out.print("성별(M/F) : ");
char gender = sc.next().charAt(0);
// String -> char
System.out.print("점수 : ");
int score = sc.nextInt(); // InputMismatchException
//입력받은 index번째에 새로운 학생 정보로 수정
//이때 index번째에 있던 기존 학생 정보가 반환된다.
Student temp = studentList.set(index, new Student(name, age, region, gender, score));
return temp.getName() + "님의 정보가 변경되었습니다.";
}
}
/**
* 4. 학생 정보 제거 메소드
*/
public String removeStudent() throws InputMismatchException{
// - Student List.remove(int index)
// 리스트에서 index번째 요소를 제거
// 이때, 제거된 요소 반환
// *List는 중간에 비어있는 인덱스가 없게 하기 위해
// remove() 동작 시 뒤쪽 요소를 한 칸씩 당겨온다.
System.out.println("=====학생 정보 제거=====");
System.out.print("인덱스 번호 입력: ");
int index = sc.nextInt();
sc.nextLine();
//1) 학생 정보가 studentList에 있는가?
if(studentList.isEmpty()) { //비어있을 경우
return "입력된 학생 정보가 없습니다.";
//2) 입력된 숫자가 0보다 작은가?(음수 검사)
} else if(index<0) {
return "음수는 입력할 수 없습니다.";
//3) 만약 문자열을 입력한 경우 -> throws로 예외 처리
//4) 입력받은 숫자가 studentList 범위 내 인덱스 번호인가?
} else if(index>=studentList.size()) {
return "범위를 넘어선 값을 입력할 수 없습니다.";
} else {
//학생 정보 제거
System.out.print("정말 삭제하시겠습니까? (Y/N): ");
char ch = sc.next().toUpperCase().charAt(0);
//String -> 대문자 String -> 0번째 인덱스 문자
//String.toUpperCase(): 문자열을 대문자로 변경
if(ch == 'Y') {
Student temp = studentList.remove(index);
return temp.getName() + "님의 정보가 제거되었습니다.";
} else {
return "취소";
}
}
}
/**
* 5. 이름이 일치하는 학생을 찾아서 조회하는 메소드
*/
public void searchName1() {
System.out.println("=====학생 검색(이름 일치)=====");
System.out.print("검색할 이름 입력: ");
String input = sc.next();
boolean flag = true;
//향상된 for문
for(Student std : studentList) {
if(std.getName().equals(input)) { //이름이 일치하는 경우
//일치하는 학생의 정보 출력
System.out.println(std);
flag = false;
}
}
if (flag) { //flag가 true인 경우 == for문 내에 있는 if가 수행된 적 X
// == 검색 결과가 없다.
System.out.println("검색 결과가 없습니다.");
}
}
/**
* 6. 이름에 특정 문자열이 포함되는 학생을 찾아서 조회하는 메소드
*/
public void searchName2() {
//contains: 포함
//boolean String.contains(문자열): String에 문자열이 포함되어 있으면 true, 아니면 false
System.out.println("=====학생 이름(문자열 포함)=====");
System.out.print("이름에 포함되는 문자열 입력: ");
String input = sc.next();
boolean flag = true;
//향상된 for문
for(Student std : studentList) {
if(std.getName().contains(input)) { //순서 바뀌면 안 됨!!!!!!!!!!!!
System.out.println(std);
flag = false;
}
}
if (flag) {
System.out.println("검색 결과가 없습니다.");
}
}
}
package edu.kh.collection.run;
import edu.kh.collection.model.service.StudentService;
public class StudentRun {
public static void main(String[] args) {
StudentService service = new StudentService();
service.displayMenu();
// service.ex();
}
}