private String input(Scanner scan) {
String data = scan.next();
return data;
}
private void output(String text) {
System.out.print(text);
}
콘솔창에서 이용할 입력값(scanner)과 출력을 시켜줄 메소드를 input과 output으로 만들어주었다.
보안을 위해 접근권한자로 private을 이용했다.
void는 리턴을 받지않는 메소드.
그리고 input은 입력을 받아서 그 값을 보내줘야하기때문에 return으로 저장시켜주었다.
@리턴값을 받는 메소드 받지않는 메소드, 리턴은 언제 해줘야하는지 모른다@
스캐너 생성자를 호출하는 법*
Scanner scan = new Scanner(System.in);
생성자를 사용하는 법은 익숙해졌다.
@하지만 아직 어색하고 모르는건(생성자에 국한된것은 아니고) 필드밖으로 빼줘야하는건지, 그안에서만 사용한다고 생각해서 안에서만 사용할지가 아직 확신이없다.@
scan이 항상 노란줄이 떳는데(Resource leak: 'scan' is never closed)스캔이 항상 열려있기때문에 불필요한 데이터를 잡아먹었다, 안내창에서 말해줬던것처럼 닫아주면 해결.
하지만 닫아주니까 그 다음의 스캔값을 받지못하는 문제가 생겼고 (system.in 때문에 다시 켜줘야하는 문제가있다) > 메소드 안에 만들어줬던 생성자호출을 바깥으로 빼줬다. 그리고 스캔을 받는 메소드에 scan.close();를 넣어 닫아주었다.
private String ExpressBus(String menu) {
StringBuffer tittle = new StringBuffer();
tittle.append("\n");
tittle.append("*===========================*\n");
tittle.append("\n");
tittle.append("\n" + menu + "\n");
tittle.append("\n");
tittle.append("*===========================*\n");
return tittle.toString();
}
private String ExpressBus1(String menu) {
StringBuffer tittle = new StringBuffer();
tittle.append("\n");
tittle.append("\n");
tittle.append(menu + "\n");
tittle.append("\n");
tittle.append("===================선택\n");
return tittle.toString();
}
private String ExpressBus2(String page) {
StringBuffer tittle = new StringBuffer();
tittle.append("[");
tittle.append(page + "]");
return tittle.toString();
}
자주 사용하던 출력메소드는 System.out.print(text); <-스트링값을 직접 더하는 형태
String은 새로운 값을 할당할때마다 새롭게 생성되기 때문에 힙메모리 영역에 필요없는 데이터들이 축적이된다.
그래서 stringBuffer를 이용하여 임시저장소에 출력값을 저장해주고,
임시저장된 값들을 .append로 버퍼의 끝에 문자열을 추가,(더해준뒤) 한뒤 return tittle.toString으로 저장해준다.
.toString 문자열이 아닌 데이터형의 값을 문자형으로 바꾸어준다.
blog Stack과 heap 설명
blog Stringbuffer 설명
Controller Class에서 가장 중요하고 가장 이용할 메소드,
흐름을 제어하고 Reservation Class에서 정제된 값들을 이용해 출력해주는 역활
String appTitle = this.ExpressBus("버스예약");
String code;
Reservation reservation;
Scanner scan = new Scanner(System.in);
while (true) {
output(appTitle);
output(ExpressBus1("1.예약 \t2.예약확인\n \t0.종료"));
output(ExpressBus2(">"));
code = input(scan);
if (code.equals("1") || code.equals("2") || code.equals("0"))
break;
}
출력된 값
StringBuffer로 만들어주었던 메뉴들을 output메소드를 사용하여 만들어주었다.
parameter를 변동시켜 동적인(안의 출력문들을 원하는 문자로 바꿀수있게) 메뉴로 만들 수 있다.
While : 반복문
if : 조건문
만약(if) 입력값(code)가 1 ||(or) 2 ||(or) 0 과 같을 때(equals) break, 그외 값이 입력된다면 다시(While) 같은 부분이 출력되게 만들어 주었다.
@아래 if(!code.equals("0")) 을 줌으로써 0과 같지않을경우는 Reservation 클래스로 들어가 1과 2의 값을 출력하게 만들어주었다. 0일 경우 종료 (if문 조건에 0,1,2중 0이 걸려서 break;에 걸려서 들어감) 다른 숫자를 입력할 경우 반복이 되는 이유는 0-2의 숫자가 아니면 if문은 자동적으로 통과되어서 작동이 되지않고 while문으로 반복작동 됨@
설명들으면서 적은건데 다시 보니까 왜 이해가 안될까
programmers While 반복문의 이해 기본] (https://programmers.co.kr/learn/courses/5/lessons/120)
programmers While 사용해보기
wikidocs While 반복문의 이해 응용
boolean을 사용해 true false을 주기도하는데, 그 부분은 이해하지못했다.
맞다. 조건을 주고 braek를(조건문을 이용하거나 braek;사용) 제대로 주지못하면 무한반복이 진행된다. 이 부분을 주의할것
programmers 조건문 If
wikidocs 조건문 If
if elseif else 중첩if
if라는 그것이 웃기고 유용해서 좋아한다. 하지만 if문에서 조건을 만드는 법이 너무 어렵게 느껴진다.
and(&&), or(||), not(!)
x || y - x와 y 둘 중 적어도 하나가 참이면 참이다
x && y - x와 y 모두 참이어야 참이다
!x - x가 거짓이면 참이다
이게 사용하다보면 은근히 헷갈린다.
and와 or는 한번씩 더 생각해서 사용★
equls은 문자열일때의 and와 같은 역활을 한다.
code를 string으로 선언해주었기 때문에 equals사용.
메소드기때문에 객체끼리 내용을 비교할수도있다
생활코딩 equals
if (!code.equals("0")) {
reservation = new Reservation();
String list = reservation.backController(Integer.parseInt(code));
output(this.appTitle());
output(this.ExpressBus1("출발지 선택"));
output(this.ExpressBus2(list));
code = input(scan);
list = reservation.backController(Integer.parseInt(code) + 10);
output(this.appTitle());
output(this.ExpressBus1("도착지 선택"));
output(this.ExpressBus2(list));
code = input(scan);
list = reservation.backController(Integer.parseInt(code) + 100);
output(this.appTitle());
output(this.ExpressBus1("시간표 선택"));
output(this.ExpressBus2(list));
code = input(scan);
list = reservation.backController(Integer.parseInt(code) + 1000);
boolean check = true;
while (check) {
String[] seatInfo = new String[2];
output(this.appTitle());
output(this.ExpressBus2("좌석 선택"));
output(this.ExpressBus1(list));
seatInfo[0] = input(scan);
output(this.ExpressBus2("좌석 타입"));
output(this.ExpressBus1("1.성인 \t 2.청소년 \t 3.어린이"));
seatInfo[1] = input(scan);
output(this.ExpressBus2("추가구매"));
output(this.ExpressBus1("1.추가 \t 2.결제"));
if (input(scan).equals("2"))
check = false;
/* 2020.08.14 End */
list = reservation.backController(seatInfo);
}
}
만약(if) 입력받은 값이(code) 0이랑 같지않을때(!=)
만약(if) code값을 1로 받았을 때
출발지리스트출력 →입력→ 도착지리스트출력 →입력→ 버스시간표출력 →입력→ 좌석선택메뉴출력 →입력→ 좌석타입선택 →입력→ 추가구매 →입력→ 결제 까지 쭉 이루어질수있게 만듦.
String list = reservation.backController(Integer.parseInt(code));
reservation class에 있는 backController((String을 Int로 바꾼 code)parameter)를 list에 저장, 그리고 이를 위해 backController로 이동해 작업해준다.
시간표 선택까지는 패턴을 이용해 코드를 만들었지만,
배열변수 좌석과 타입 두개를 사용자에게 받아야하기 때문에 배열을 사용해 우리가 필요한것을 원할때 뺄수있게 만들어줌
Integer.parseInt(code) 코드를 String에서 Int로 바꿔주었다.
@형변환 cast stack영역의 데이터 사이즈가 다른 변수끼리의 데이터 저장
(형변환 int short car . . .)
int i = 10; short s = 10; i = s; s = (short) i;
//다운캐스트는 꼭 풀어서 명시를 해줘야 사용가능
parse heap데이터(string) ->Stack(숫자) Integer.parseInt(); integer. 형변환은 시간이 걸리기때문에 적재적소에 사용하는 것을 권장한다.@
역시 내가 쓴거지만 지금 다시보니 이해불가
String[] seatInfo = new String[2];
인덱스가 3개인 배열선언,
인덱스 0번에 입력값(스캔)저장
인덱스 1번에 입력값(스캔)저장
인덱스 2번에 입력값(스캔)저장