アカデミー20日目-Java


  • メソッドの作成
  • コードにカーソルを置き、F 3を押して定義位置
  • に要素を移動する.

    2021.04.23


    ArrayList

  • ArrayList->データセット->アレイ
  • の使用と同様
  • アレイとArrayList?
  • の長さは固定されていますか?(長さが固定されている場合はタイリング、固定されていない場合はArrayList)
  • 使いやすさ->ArrayList使いやすさ
  • import java.util.ArrayList;
    import java.util.Random;
    import java.util.Scanner;
    
    public class Ex62_ArrayList {
    	
    	
    	//학생 목록 - 여러 항목에 공용으로 쓰기 위해서 클래스 멤버변수로 사용한다.(main메서드에서 호출하려면 Static을 붙여야한다.)
    	//Student[] list = new Student[?]; //몇명을 넣을지 모르기 때문에 ArrayList 사용
    	private static ArrayList<Student> list;
    	private static Scanner scan;
    	
    	
    	//정적 생성자(Static 생성자)
    	static {
    		list = new ArrayList<Student>(); // 멤버는 생성자에서 초기화
    		scan = new Scanner(System.in);
    	}
    	
    	public static void main(String[] args) { //main메서드는 무조건 static, static 키워드에서는 this 사용 불가
    
    		//Ex62_ArrayList.java
    		
    		//ArrayList 사용 -> 데이터 집합 -> 배열 사용 유사
    		
    		//배열 vs ArrayList ?
    		// - 길이가 고정인가?
    		// - 사용 편의성 -> ArrayList 편함
    		
    		//학생 관리
    		// - 정원 5명
    		// - 추후 증가/감소
    		
    		//학생
    		// - 이름
    		// - 나이
    		// - 국어,영어,수학
    		
    		//학생 정보 관리
    		//메뉴(번호 선택)
    		//1. 학생 추가
    		//2. 학생 목록
    		//3. 학생 삭제
    		//4. 학생 검색
    
    		dummy();
    	
    		System.out.println("[학생 정보 관리]");
    		
    		boolean loop = true;
    		
    		while (loop) {
    			
    			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("================");
    			
    			System.out.print("선택: ");
    			String sel = scan.nextLine();
    			
    			if (sel.equals("1")) {
    				add(); //코드의 간결함을 위해 메소드로 분산시킴
    			} else if (sel.equals("2")) {
    				list();
    			} else if (sel.equals("3")) {
    				delete();
    			} else if (sel.equals("4")) {
    				search();
    			} else {
    				loop = false; //5를 입력하면 루프 탈출
    			}
    			
    		}//while
    		
    		System.out.println("프로그램을 종료합니다.");
    
    	}//main
    
    	private static void dummy() {
    		
    		//프로그램에서 사용할 임시 데이터 생성 메소드
    		Random rnd = new Random();
    		
    		String[] name = { "홍길동", "가가가", "나나나", "다다다", "라라라", "마마마", "바바바", "사사사", "아아아" };
    		
    		for (int i=0; i<5; i++) {
    			
    			Student s = new Student();
    			
    			s.setName(name[rnd.nextInt(name.length)]); //0~8
    			s.setAge(rnd.nextInt(5) + 15); //15~19
    			
    			Subject subject = new Subject();
    			subject.setKor(rnd.nextInt(40) + 61); //60~100
    			subject.setEng(rnd.nextInt(40) + 61);
    			subject.setMath(rnd.nextInt(40) + 61);
    			
    			s.setSubject(subject);
    			
    			list.add(s);
    			
    		}
    		
    	}
    
    	private static void add() {
    		
    		//학생 추가
    		System.out.println("[학생 추가]");
    		
    		System.out.print("이름: ");
    		String name = scan.nextLine();
    		
    		System.out.print("나이: ");
    		int age = scan.nextInt();
    		
    		System.out.print("국어: ");
    		int kor = scan.nextInt();
    		
    		System.out.print("영어: ");
    		int eng = scan.nextInt();
    		
    		System.out.print("수학: "); //100을 입력하면 -> 100\r\n -> \r\n을 남겨둔다.
    		int math = scan.nextInt(); //nextInt : 입력값에 포함된 엔터를 버리지 않고 남겨둔다.
    		
    		scan.skip("\r\n"); //남아있는 엔터가 다음 nextLine()에 영향을 주지 않도록 \r\n을 강제로 버퍼에서 지운다.★★
    		
    		//조립하는 방법
    		//Case A.
    		//Subject subject = new Subject(kor, eng, math);
    		//Student s = new Student(name, age, subject);
    				
    		//Case B.
    		Student s = new Student(name, age, kor, eng, math); //학생 정보 객체(생성자 내부에서 객체를 생성해주는 방법 선택)
    		
    		//목록에 추가하기
    		list.add(s);
    		
    		System.out.println("학생 추가가 완료되었습니다.");
    		
    		pause();
    		
    	}
    
    	private static void pause() {
    		System.out.println("계속 하시려면 엔터를 입력하세요."); //프로그램을 잠깐 멈춤(일시정지)
    		scan.nextLine();
    	}
    
    	private static void list() {
    		
    		System.out.println("=====================================");
    		System.out.println("[이름]\t[나이]\t[국어]\t[영어]\t[수학]");
    		System.out.println("=====================================");
    		
    		for (Student s : list) {
    			
    			System.out.printf("%s\t%5d\t%5d\t%5d\t%5d\n"
    								, s.getName()
    								, s.getAge()
    								//, s.getSubject().getKor()
    								, s.getKor()
    								, s.getEng()
    								, s.getMath());
    			
    		} //for
    		
    		pause();
    
    	}
    
    	private static void delete() {
    		
    		System.out.println("[학생 삭제]");
    		
    		System.out.print("이름: ");
    		String name = scan.nextLine();//이름이 중복되어도 첫번째를 지움. 
    		
    		//indexOf 사용 불가
    		// -> 직접 탐색
    		for (int i=0; i<list.size(); i++) {
    			
    			if (list.get(i).getName().equals(name)) {
    				list.remove(i);
    				break;
    			}
    			
    		}
    		
    		System.out.println("학생 삭제를 완료했습니다.");
    		pause();
    		
    	}
    
    	private static void search() {
    		
    		System.out.println("[학생 검색]");
    		
    		System.out.print("이름: ");
    		String name = scan.nextLine(); 
    		
    		
    		
    		System.out.println("=====================================");
    		System.out.println("[이름]\t[나이]\t[국어]\t[영어]\t[수학]");
    		System.out.println("=====================================");
    		
    		for (int i=0; i<list.size(); i++) {
    			
    			//정확한 이름 검색
    			//if (list.get(i).getName().equals(name)) {
    			
    			//부분 검색
    			//if (list.get(i).getName().indexOf(name) > -1) {
    			if (list.get(i).getName().contains(name)) {
    				
    				System.out.printf("%s\t%5d\t%5d\t%5d\t%5d\n"
    						, list.get(i).getName()
    						, list.get(i).getAge()
    						, list.get(i).getKor()
    						, list.get(i).getEng()
    						, list.get(i).getMath());
    
    			}
    			
    		}
    		
    		pause();
    		
    	}
    
    }//Ex62
    
    
    class Student {
    	
    	private String name;
    	private int age;
    	
    	//private int kor;
    	//private int eng;
    	//private int math;
    	
    	//private int[] subject; -> 배열이니까 몇번째방에 뭐가 들어있는지 알 수 없음
    	
    	private Subject subject; //배열대신 클래스 사용 (참조)
    	
        //생성자
    	public Student() {
    		this.name = "";
    		this.age = 0;
    		this.subject = null;
    	}
    	
        //생성자 오버로딩
    	public Student(String name, int age, Subject subject) {
    		this.name = name;
    		this.age = age;
    		this.subject = subject;
    	}
    	
        //생성자 오버로딩 - Subject subject를 매개변수로 받으면 밖에서 객체를 생성해줘야하기때문에 사용자 편의를 위해 안에서 객체 생성해줌.
    	public Student(String name, int age, int kor, int eng, int math) {
    		this.name = name;
    		this.age = age;
    		this.subject = new Subject(kor, eng, math);
    	}
    
    	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 Subject getSubject() {
    		return subject;
    	}
    
    	public void setSubject(Subject subject) {
    		this.subject = subject;
    	}
    	
        //나중에 사용할때 편리하게 하기 위해 각각 넣을 수 있게 해준다.(다양하게 선택권을 만들어두면 좋음.)
    	public void setKor(int kor) {
    		this.subject.setKor(kor);
    	}
    	
    	public void setEng(int eng) {
    		this.subject.setEng(eng);
    	}
    	
    	public void setMath(int math) {
    		this.subject.setMath(math);
    	}
    	
    	public int getKor() {
    		return this.subject.getKor();
    	}
    	
    	public int getEng() {
    		return this.subject.getEng();
    	}
    	
    	public int getMath() {
    		return this.subject.getMath();
    	}
    
    	@Override  //subject를 통째로 보여주면 보기 어렵기 때문에 국어영어수학으로 쪼개주면 알아보기 쉽다.
    	public String toString() {
    		return String.format("Student [name=%s, age=%d, kor=%d, eng=%d, math=%d]" 
    								, this.name
    								, this.age
    								, this.subject.getKor()
    								, this.subject.getEng()
    								, this.subject.getMath());
    	}
    	
    }
    
    class Subject {
    	
    	private int kor;
    	private int eng;
    	private int math;
    	
    	//생성자
    	public Subject() {
    		//this.kor = 0;
    		//this.eng = 0;
    		//this.math = 0;
    		this(0, 0, 0);
    	}
    	
    	public Subject(int kor, int eng, int math) {
    		this.kor = kor;
    		this.eng = eng;
    		this.math = math;
    	}
    
    	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;
    	}
    
    	@Override
    	public String toString() {
    		return "Subject [kor=" + kor + ", eng=" + eng + ", math=" + math + "]";
    	}
    	
    }

    ArrayListのエンティティ->内部構造

    import java.util.ArrayList;
    
    public class Ex63_ArrayList {
    
    	public static void main(String[] args) {
    		
    		
    		//ArrayList의 정체 (실체) -> 내부 구조
    		
    		//배열 : 배열의 길이가 불변이다.
    		//ArrayList :배열의 길이가 가변이다.
    		
    		
    		ArrayList<Integer> list =  new ArrayList<Integer>();
    
    //		for(int i=0; i<10000000; i++) {
    //			list.add(10);
    //			
    //		}
    		
    		list.add(100);
    		list.add(200);
    		list.add(300);
    		list.add(400);
    		//list.add(500); //IndexOutBoundException 발생해야하는데 안하는 이유?
    		
    		System.out.println(list.size());
    		
    		
    		//ArrayList<Integer> list2 = new ArrayList<Integer>();
    		
    		
    		ArrayList<Integer> list2 = new ArrayList<Integer>(1025); //initialCapacity : 처음 시작하는 배열의 길이를 지정할 수 있다. (초기값)
    		
    		//4칸 배열
    		
    		for(int i=0; i<1025; i++) {
    			
    			//4 -> 8 -> 8칸짜리 배열 생성 비용 발생 + 복사 비용 발생 + 4칸 짜리 배열 쓰레기 처리 비용 발생
    			//8 -> 16
    			//16 -> 32
    			//32-> 64
    			//64 -> 128
    			//128 -> 256
    			//256 -> 512
    			//512 -> 1024
    			//1024 -> 2048
    			list2.add(i);
    		}
    		
    		System.out.println(list2.size()); //1025 -> 실제 배열의 길이(1025)
    		
    		list.add(100);
    		
    		System.out.println(list2.size()); //1026 -> 실제 배열의 길이(2050)
    		
    		//난 더이상 add()를 쓸 일이 없다!! -> 1024방이 빈방으로 남게 된다.(잉여공간)
    		
    		//2050 -> 1026 줄여줌
    		list2.trimToSize(); //실제 배열의 길이를 데이터 갯수와 동일하게 줄여라!! (잉여공간을 제거해줌)
    	
    	}//main
    
    }
    
    class MyArrayList {
    	
    	private int[] list = new int[4]; // 처음에는 4개로 시작
    	
    	public void add(int n) {
    		
    		//ArrayList 길이가 늘어나는 것 처럼 보이는 이유? 
    		
    		//추가 작업 
    		//1. 배열이 꽉찼는가?
    		//	a.안찼다 > 빈방 존재 > 빈방에 요소를 추가
    		//	b.꽉찼다 > 이사를 간다 
    		//		a. 1.현존하는 배열의 x2 길이의 배열을 만든다.
    		//			- int[] temp = new int[8];
    		//		a. 2. 배열끼리 값을 복사한다.
    		//			- list -> temp 복사 //깊은 복사(Deep Copy)
    		//		a. 3. 멤버 변수를 교체한다.
    		//			- list를 temp로 바꾼다.
    		//			- this.list = temp;
    		
    		int[] temp = new int[8];
    		
    		//4칸짜리배열 -> (교체) -> 8칸 배열
    		this.list = temp;
    		
    		//8칸 배열 -> 0~3 (기존데이터그대로..)
    		
    		
    		list[4] = n; //에러안남,, 배열이 늘어난 것처럼 다룰 수 있음.
    		
    	}
    	
    }
    
    
    //class ArrayList<T> {
    //	
    //	private T[] list;
    //}