JavaAir 항공 예약 시스템 - 전체 프로그램
목차
시스템 개요
JavaAir는 항공편 예약을 관리하는 콘솔 기반 Java 애플리케이션입니다.
주요 기능
- ✅ 항공편 목록 조회
- ✅ 항공편 예매 (국내선/국제선)
- ✅ 예약 조회
- ✅ 티켓 파일 저장
- ✅ 항공편 일정 업로드
시스템 특징
- 국제선 제한: 만 15세 이상만 예약 가능
- 좌석 선택: 20개 좌석 중 선택
- 비밀번호 인증: 예약 조회 시 비밀번호 확인
- 파일 입출력: 예약 정보 파일 저장 및 일정 업로드
프로젝트 구조
a0402.javaair
├── Passenger.java (승객 정보 관리)
├── Flight.java (항공편 정보 관리)
├── FlightManager.java (항공편 예약 관리)
├── FileC.java (파일 입출력 처리)
└── FlightReservationMain.java (메인 클래스)
전체 소스 코드
Passenger.java
package a0402.javaair;
import java.time.LocalDate;
import java.time.Period;
public class Passenger {
private String name;
private int birthDate;
private String pw;
private String seat;
public Passenger(String name, int birthDate) {
this.name = name;
this.birthDate = birthDate;
}
public Passenger(String name, int birthDate, String pw) {
this.name = name;
this.birthDate = birthDate;
this.pw = pw;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getBirthDate() {
return birthDate;
}
public void setBirthDate(int birthDate) {
this.birthDate = birthDate;
}
public String getPw() {
return pw;
}
public void setPw(String pw) {
this.pw = pw;
}
public String getSeat() {
return seat;
}
public void setSeat(String seat) {
this.seat = seat;
}
//15세 이상만 국제선 예약이 가능
public boolean man15(Passenger p){
int y = p.birthDate / 10000;// 831016이라면 83만 남음
int m = (p.birthDate % 10000) /100; // 1016에 100나눠서 10만 남음
int d = p.birthDate % 100; //16만 남음
if(y > 0 && y <= 25){
y = y +2000;
} else {
y += 1900;
}
//1983/10/16
LocalDate birthDate2 = LocalDate.of(y, m, d);//생년월일
LocalDate currentDate = LocalDate.now();//오늘 년월일
int age = Period.between(birthDate2, currentDate).getYears();//생년월일과 오늘의 년월일을 비교해서 연도만 빼서 연령을 구함
return age > 15;
}
/*
public boolean isEligibleForInternationalFlight() {
int y = birthDate / 10000;
int m = (birthDate % 10000) / 100;
int d = birthDate % 100;
y = (y > 0 && y <= 24) ? y + 2000 : y + 1900;
LocalDate birthDate2 = LocalDate.of(y, m, d);
LocalDate currentDate = LocalDate.now();
int age = Period.between(birthDate2, currentDate).getYears();
return age > 15;
}
*/
}
주요 메서드:
man15(Passenger p): 만 15세 이상인지 확인하는 메서드- 생년월일을 연/월/일로 분리
- 연도 변환 (00~25는 2000년대, 그 외는 1900년대)
LocalDate와Period로 나이 계산
Flight.java
package a0402.javaair;
import java.text.DecimalFormat;
import java.util.ArrayList;
public class Flight {
//목적지, 비행시간, 금액
private String destination;
private String time;
private int price;
private DecimalFormat priceFormat = new DecimalFormat("#,###원");
private Boolean internationalFlight; //국제여부
private ArrayList<String> seats; //좌석
public Flight(String destination, String time, int price, Boolean internationalFlight) {
this.destination = destination;
this.time = time;
this.price = price;
this.internationalFlight = internationalFlight;
seats = new ArrayList<String>();
for(int i = 1; i <= 20; i++){
seats.add(i+"");//숫자를 문자열로 넣기위해""한거임
}
}
public String getDestination() {
return destination;
}
public void setDestination(String destination) {
this.destination = destination;
}
public String getTime() {
return time;
}
public void setTime(String time) {
this.time = time;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public DecimalFormat getPriceFormat() {
return priceFormat;
}
public void setPriceFormat(DecimalFormat priceFormat) {
this.priceFormat = priceFormat;
}
public Boolean getInternationalFlight() {
return internationalFlight;
}
public void setInternationalFlight(Boolean internationalFlight) {
this.internationalFlight = internationalFlight;
}
public ArrayList<String> getSeats() {
return seats;
}
public void setSeats(ArrayList<String> seats) {
this.seats = seats;
}
@Override
public String toString() {
String priceComma = priceFormat.format(price);
return ". "+"목적지 : " + destination + ", 출발시간 : " + time + ", 가격 : " + priceComma;
}
//좌석정보 출력(좌석을 4개씩 출력하여 가로로 배열)
public void seatToString(){
for(int i = 0; i < seats.size()-3; i+=4){
System.out.printf("| [%2s]\t\t[%2s][%2s]\t\t[%2s] |\n", seats.get(i),seats.get(i+1),seats.get(i+2),seats.get(i+3));
}
}
}
/*
| [ 1] [ 2][ 3] [ 4] |
| [ 5] [ 6][ 7] [ 8] |
| [ 9] [10][11] [12] |
| [13] [14][15] [16] |
| [17] [18][19] [20] |
*/
주요 메서드:
toString(): 항공편 정보를 문자열로 반환 (가격 포맷팅 포함)seatToString(): 좌석 배치도를 출력 (4개씩 그룹화)
FlightManager.java
package a0402.javaair;
import java.time.DateTimeException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.InputMismatchException;
import java.util.Map;
import java.util.Scanner;
public class FlightManager {
private static ArrayList<Flight> flights; //항공편 정보를 저장 ArrayList
private static ArrayList<Passenger> passengers; //예약된 승객정보
//승객을 키로하고, 예약된 항공편을 값으로 가지는 Map
private static Map<String, Flight> reservationMap = new HashMap<>();
private static FileC fc = new FileC(); //파일 관련작업
Scanner sc = new Scanner(System.in);
public FlightManager(){
flights = new ArrayList<>();
flights.add(new Flight("제주","11:55", 78000, false));
flights.add(new Flight("이스탄불","17:10",1200000,true));
flights.add(new Flight("방콕","21:35",280000,true));
passengers = new ArrayList<>();
Flight sf = flights.get(0);
reservationMap.put("테스트", sf);
}
public String airplane = " | \n" + " _|_ \n" + " /_____\\ \n" + " /oo oo\\ \n" + " \\_________________\\ /_________________/\n" + " `-------|---|-----\\_____/-----|---|-------'\n" + " ( ) ( ) O|OOo|oOO|O ( ) ( ) \n";
public void displayFlightList(String str) {
//항공편 목록이 출력 -> flight 에서 toString 이용해서
System.out.println("=========================== "+str+ " =========================" );
int count = 1;
for(Flight flight: flights){
System.out.println(count + ""+ flight);
count++;
}
System.out.println("============================================================");
}
public void bookFlight() throws InterruptedException {
//국제선 - 사용자이름, 생년월일 받아서 나이확인하고 만 15미만 예약거절
for(;;){//무한루프
displayFlightList("항공편예매");
System.out.print("예매할 항공편 입력 > ");
try {
int bookNum = Integer.parseInt(sc.next());
if(bookNum > flights.size() || bookNum < 1){
//예약할 수 있는 목록의 갯수보다 크거나 목록이 없으면
System.out.println("잘못되 입력입니다.");
continue;
//유요하지 않은 입력은 받은 경우 루프 다음을 반복
//사용자에게 올바른 입력을 다시 요청
}
System.out.println("선택한 항공편");
System.out.println("============================================================");
System.out.println(bookNum + "" + flights.get(bookNum-1));
System.out.println("============================================================");
Flight sf = flights.get(bookNum-1);
if(flights.get(bookNum-1).getInternationalFlight()){//국제선이면
System.out.println("국제선은 만15세이상 예매가능");
passengerInfo(sf);
}else{
passengerInfo(sf);
}
if(passengers != null && !passengers.isEmpty()){
String seatNum = Integer.toString(seatSelection(sf)); //좌석
passengers.get(passengers.size()-1).setSeat(seatNum);
// 현재 passengers 리스트에서 가장 마지막에 추가된 승객 좌석 번호를 설정
System.out.println("예약중입니다.");
Thread.sleep(2000); //2초후 실행
System.out.println("==================================================");
System.out.println("예약에 성공했습니다.");
System.out.println("[" + passengers.get(passengers.size()-1).getName()+"] 님의 예약정보");
System.out.println(bookNum + "" + sf);
System.out.println("==================================================");
System.out.println("잠시후 메인 화면으로 이동합니다.");
Thread.sleep(2000);
reservationMap.put(passengers.get(passengers.size()-1).getName(),sf);
break;
}
} catch (NumberFormatException e) {
System.out.println("잘못된 입력입니다.");
}
}
}
private int seatSelection(Flight flight) { //좌석예약
int seatNum =-1;
while(true){
try {
System.out.println("========================================");
flight.seatToString(); //빈좌석이 보이는 print
System.out.println("좌선번호를 선택하세요");
System.out.print("선택>");
int seatInt= sc.nextInt() - 1;
sc.nextLine();
if(seatInt+1 < 1 || seatInt+1 > 20){//좌석 1~20
System.out.println("존재하지 않는 좌석입니다.");
}else if(flight.getSeats().get(seatInt).equals("XX")){
System.out.println("이미 예약된 좌석입니다.");
}else{
// 좌석이 비어있으면
flight.getSeats().set(seatInt, "XX"); //좌석수정
//"XX"로 좌석을 표시
System.out.println("좌석 선택이 완료되었습니다.");
seatNum = seatInt;
break;
}
} catch (InputMismatchException e) {
System.out.println("잘못된 입력입니다.");
sc.nextLine();
}
}
return seatNum;
}
private void passengerInfo(Flight flight) {// 사용자 입력해서 예약
System.out.println("예매자 정보를 입력하세요");
System.out.print("이름 : ");
String name = sc.next();
System.out.printf("생년월일(6자리):");
try {
int birthDate = Integer.parseInt(sc.next());
Passenger p = new Passenger(name, birthDate);
if(!p.man15(p) && flight.getInternationalFlight()){
//왼쪽 과 오른쪽 true 이여야만 실행 - 15미만이고 국제선이면
System.out.println("만 15미만은 국제선 예약불가입니다.");
}else{
System.out.println("결제 비밀 번호");
String pw = sc.next();
p = new Passenger(name,birthDate,pw);
passengers.add(p); //항공 예약 명단에 추가
}
} catch (DateTimeException e) {
System.out.println("생년월일을 6자리로 입력해주세요 ex)010225");
}
}
public void checkReservation() {
int index = search("예약확인");
checkPassword(index);
}
private void checkPassword(int index) {
for(;;){
if(index !=-1){
System.out.println("결제 비밀번호");
String pw = sc.next();//비밀번호 키보드 입력
System.out.println();
if(passengers.get(index).getPw().equals(pw)){
System.out.println("비밀번호가 일치합니다.");
System.out.println(ticketPrint(reservationMap, passengers.get(index).getName()));
break;
}
}
}
}
String ticketPrint(Map<String, Flight> reservationMap, String name) {
int index = -1;
if(passengers != null){
for(int i = 0; i < passengers.size();i++){
if(passengers.get(i).getName().equals(name)){
index = i;
}
}
}
//reservationMap("이름정보", Flight("항공권명","항공시간",가격,"국제여부"))
int seat = Integer.parseInt(passengers.get(index).getSeat())+1;
return "ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ\n\n" +
"\t" + name + "님의 티켓정보" +
"| 좌석 : " + seat + "번\n"+
"." + reservationMap.get(name) + "\n\n" +
"ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ";
}
private int search(String str) {
System.out.println("===================== " + str + " =====================");
System.out.print("예약자 이름: ");
String name = sc.next();
sc.nextLine();
int index = -1;
if(passengers != null){
for(int i = 0; i < passengers.size();i++){
if(passengers.get(i).getName().equals(name)){
index = i;
}
}
}
return index;
}
public void ticketSave() {
int index = search("티켓조회");
checkPassword(index);
fc.ticketSaveFile(reservationMap, passengers.get(index).getName());
}
public static ArrayList<Flight> getFlights() {
return flights;
}
//항공편 목록을 외부에서 접근하는 getter메소드
public static Map<String, Flight> getReservationMap() {
return reservationMap;
}
//예약정보를 외부에서 접근하는 getter 메소드
}
주요 메서드:
displayFlightList(String str): 항공편 목록 출력bookFlight(): 항공편 예매 처리seatSelection(Flight flight): 좌석 선택 처리passengerInfo(Flight flight): 승객 정보 입력checkReservation(): 예약 조회checkPassword(int index): 비밀번호 확인ticketPrint(): 티켓 정보 출력ticketSave(): 티켓 파일 저장
FileC.java
package a0402.javaair;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Map;
public class FileC {
private FlightManager fm = new FlightManager();
public void ticketSaveFile(Map<String, Flight> reservationMap, String name) {
//이어 작성하기 구현 및 폴더 까지 생성 구현
// try {
// File file = new File("d:\\ticket\\ticket.txt");
// BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(file));
// //BufferedWriter를 사용하여 file에 데이터를 쓸 준비하는것
// //FileWriter는 기본적으로 기존 파일을 덮어씀
// if(file.isFile() && file.canWrite()){
// //.canWrite - 쓰기 권한이 있는지 확인 true - 쓰기 권한 있음
// bufferedWriter.write(fm.ticketPrint(reservationMap, name));//티겟 정보를 file에 작성
// bufferedWriter.flush();//버퍼에 있는 데이터를 파일에 저장
// System.out.println("파일 저장 성공");
// bufferedWriter.close();//버퍼 닫기
// } else {
// file = new File("d:\\ticket");
// file.mkdir();// 디렉토리에 폴더 생성
// file = new File("d:\\ticket"+"\\"+"ticket.txt");
// file.createNewFile();
// }
// } catch (IOException e) {
// System.out.println("파일 저장 실패");
// }
try {
File dir = new File("d:\\ticket");
if (!dir.exists()) {
dir.mkdir(); // 폴더가 없으면 생성
}
File file = new File(dir, "ticket.txt");
boolean isNewFile = file.createNewFile(); // 파일이 없으면 생성
// append 모드 활성화
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(file, true));
if (file.canWrite()) {
// 기존 파일이 있으면 개행 후 추가
if (!isNewFile) {
bufferedWriter.newLine();
}
bufferedWriter.write(fm.ticketPrint(reservationMap, name));
bufferedWriter.flush();
System.out.println("파일 저장 성공");
}
bufferedWriter.close();
} catch (IOException e) {
System.out.println("파일 저장 실패: ");
}
}
public void upload() {
try {
File file = new File("d:\\ticket\\schedule.txt");
// BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(file),"UTF-8"));
String line;
System.out.println("===============================================================");
while ((line = bufferedReader.readLine()) != null) {
System.out.println(line);
String[] flight = line.split("/");// (/)로 끊어서 배열로 만들고 그 정보를 Flight에 넣는것
FlightManager.getFlights().add(new Flight(flight[0], flight[1], Integer.parseInt(flight[2]), Boolean.parseBoolean(flight[3])));
}
} catch (FileNotFoundException e) {
System.out.println("schedule.txt 파일이 존재하지 않음");
} catch (IOException e) {
System.out.println("파일 읽기 실패");
}
}
}
주요 메서드:
ticketSaveFile(): 티켓 정보를 파일에 저장 (append 모드)upload(): 항공편 일정 파일 읽기 (UTF-8 인코딩)
FlightReservationMain.java
package a0402.javaair;
import java.util.Scanner;
public class FlightReservationMain {
public static void main(String[] args) {
FlightManager fm = new FlightManager();
//FlightManager 객체가 생성 과 동시에 더미 데이터 들어갈 예정
Scanner sc = new Scanner(System.in);
FileC fc = new FileC();
System.out.println(fm.airplane);
System.out.println("==============JavaAir 에 오신걸 환영합니다.==============");
Outter:while(true){
System.out.println("1. 항공편 목록\n2. 항공편 예매\n3. 예약 조회\n4. 티켓 저장\n5. 항공편 업로드 \n0.종료\n");
System.out.print("메뉴입력>");
String menuStr = sc.next();
sc.nextLine(); //버퍼 비우기
int menu = -1;
try {
menu = Integer.parseInt(menuStr);
} catch (NumberFormatException e) {
menu = 9;
}
switch (menu) {
case 1:
fm.displayFlightList("항공편목록");
break;
case 2:
try {
fm.bookFlight();
} catch (InterruptedException e) {
e.printStackTrace();
}
break;
case 3:
fm.checkReservation();
break;
case 4:
fm.ticketSave();
break;
case 5:
fc.upload();
break;
case 0:
System.out.println("프로그램을 종료합니다.");
sc.close();
break Outter;
default:
break;
}
}
}
}
주요 기능:
- 메인 메뉴 시스템
- 라벨이 붙은 무한 루프
- 예외 처리 (NumberFormatException, InterruptedException)
실행 방법
1. 프로젝트 구조 생성
프로젝트 루트/
└── a0402/
└── javaair/
├── Passenger.java
├── Flight.java
├── FlightManager.java
├── FileC.java
└── FlightReservationMain.java
2. 컴파일 및 실행
# 컴파일
javac a0402/javaair/*.java
# 실행
java a0402.javaair.FlightReservationMain
3. 파일 준비 (선택사항)
항공편 업로드 기능을 사용하려면 다음 파일을 준비하세요:
d:\ticket\schedule.txt
도쿄/14:30/350000/true
부산/09:15/65000/false
런던/22:00/1500000/true
파일 형식: 목적지/출발시간/가격/국제선여부
주요 기능
1. 항공편 목록 조회
- 메뉴에서 1번 선택
- 등록된 모든 항공편 정보 출력
2. 항공편 예매
- 메뉴에서 2번 선택
- 항공편 선택
- 국제선이면 만 15세 이상 확인
- 승객 정보 입력 (이름, 생년월일, 비밀번호)
- 좌석 선택 (1~20번)
- 예약 완료
3. 예약 조회
- 메뉴에서 3번 선택
- 예약자 이름 입력
- 비밀번호 확인
- 티켓 정보 출력
4. 티켓 저장
- 메뉴에서 4번 선택
- 예약 조회 후 비밀번호 확인
d:\ticket\ticket.txt파일에 저장
5. 항공편 업로드
- 메뉴에서 5번 선택
d:\ticket\schedule.txt파일 읽기- 항공편 목록에 추가
핵심 개념
1. 생년월일 처리
- 형식: YYMMDD (6자리)
- 연도 변환: 00~25는 2000년대, 그 외는 1900년대
LocalDate와Period로 나이 계산
2. 좌석 관리
- 좌석 번호: 1~20 (사용자)
- 배열 인덱스: 0~19 (내부 처리)
- 예약 표시: "XX"
3. 파일 입출력
- Append 모드:
FileWriter(file, true) - UTF-8 인코딩:
InputStreamReader(new FileInputStream(file), "UTF-8")
4. 예외 처리
NumberFormatException: 숫자 변환 실패InputMismatchException: 잘못된 입력 타입InterruptedException: Thread.sleep() 관련IOException: 파일 입출력 관련
5. 컬렉션
ArrayList<Flight>: 항공편 목록ArrayList<Passenger>: 승객 목록HashMap<String, Flight>: 예약 정보
6. 라벨이 붙은 루프
Outter:while(true) { ... }break Outter;로 외부 루프 탈출
데이터 구조
초기 항공편 데이터
new Flight("제주","11:55", 78000, false) // 국내선
new Flight("이스탄불","17:10",1200000,true) // 국제선
new Flight("방콕","21:35",280000,true) // 국제선
좌석 구조
- 총 20개 좌석 (1번~20번)
- 예약된 좌석은 "XX"로 표시
- 좌석 배치도: 4개씩 그룹화하여 출력
작성일: 2026-01-30
프로젝트: JavaAir 항공 예약 시스템
버전: 1.0
'BackEnd > Java' 카테고리의 다른 글
| 2024년 정보처리기사 실기 2회 복원 문제 해설 (0) | 2026.02.17 |
|---|---|
| JavaAir 항공 예약 시스템 - 해설 (0) | 2026.02.14 |
| JavaAir 항공 예약 시스템 - 코딩 문제 (0) | 2026.02.14 |
| 버블 정렬, 삽입 정렬, 선택 정렬 (1) | 2026.02.11 |
| String 주요 메서드 예제 (0) | 2026.02.09 |