본문 바로가기
  • 코딩, 허쌤이 떠먹여 줄게
BackEnd/Java

8_3. 도서 관리시스템

by 허쌤 2026. 1. 20.

도서 관리 시스템 - 메뉴 기반 실습 문제

📚 문제 설명

도서 정보를 관리하는 메뉴 기반 프로그램을 작성하세요.
사용자가 메뉴를 선택하여 도서를 등록, 검색, 수정, 삭제, 전체 출력할 수 있도록 구현하세요.


📋 요구사항

1. Book 클래스 작성

  • 필드
    • title (String): 도서 제목
    • author (String): 저자 이름
  • 생성자
    • Book(String title, String author): 제목과 저자를 받는 생성자
  • 메서드
    • toString(): 도서 정보를 문자열로 반환
      • 형식: "Book{title='제목', author='저자'}"

2. BookApp 클래스 작성

2.1 메뉴 시스템

다음 메뉴를 반복해서 표시하고 사용자 입력을 받아 처리하세요:

------------------------
1. 도서 등록
2. 도서 검색
3. 도서 수정
4. 도서 삭제
5. 전체 출력
6. 종료
선택 > 

2.2 메뉴별 기능

1. 도서 등록

  • 제목과 저자를 입력받아 도서를 등록
  • 등록 완료 메시지 출력

2. 도서 검색

  • 검색할 제목을 입력받아 도서를 검색
  • 찾으면 도서 정보 출력, 없으면 "도서가 없습니다" 출력

3. 도서 수정

  • 수정할 제목과 새로운 저자를 입력받아 수정
  • 성공하면 "수정 완료", 실패하면 "해당 도서가 없습니다" 출력

4. 도서 삭제

  • 삭제할 제목을 입력받아 삭제
  • 성공하면 "삭제 완료", 실패하면 "삭제할 도서가 없습니다" 출력

5. 전체 출력

  • 등록된 모든 도서 정보 출력
  • 등록된 도서가 없으면 "등록된 도서가 없습니다" 출력

6. 종료

  • 프로그램 종료

2.3 예외 처리

  • 메뉴 선택 시 숫자가 아닌 값 입력 시 "숫자만 입력하세요" 출력 후 다시 메뉴 표시
  • 잘못된 메뉴 번호 입력 시 "1~6번 중에 선택하세요" 출력

2.4 필요한 메서드

다음 static 메서드들을 구현하세요:

// 도서 검색
static Book findBook(ArrayList<Book> list, String title)

// 도서 수정
static boolean updateBook(ArrayList<Book> list, String title, String newAuthor)

// 도서 삭제
static boolean deleteBook(ArrayList<Book> list, String title)

🎯 실행 결과 예시

------------------------
1. 도서 등록
2. 도서 검색
3. 도서 수정
4. 도서 삭제
5. 전체 출력
6. 종료
선택 > 1
제목 입력 : 자바의 정석
저자 입력 : 남궁성
도서 등록 완료
------------------------
1. 도서 등록
2. 도서 검색
3. 도서 수정
4. 도서 삭제
5. 전체 출력
6. 종료
선택 > 1
제목 입력 : 혼자 공부하는 자바
저자 입력 : 신용권
도서 등록 완료
------------------------
1. 도서 등록
2. 도서 검색
3. 도서 수정
4. 도서 삭제
5. 전체 출력
6. 종료
선택 > 5
Book{title='자바의 정석', author='남궁성'}
Book{title='혼자 공부하는 자바', author='신용권'}
------------------------
1. 도서 등록
2. 도서 검색
3. 도서 수정
4. 도서 삭제
5. 전체 출력
6. 종료
선택 > 2
검색할 제목 : 자바의 정석
Book{title='자바의 정석', author='남궁성'}
------------------------
1. 도서 등록
2. 도서 검색
3. 도서 수정
4. 도서 삭제
5. 전체 출력
6. 종료
선택 > 3
수정할 제목 : 자바의 정석
새 저자 입력 : 남궁성(개정판)
수정 완료
------------------------
1. 도서 등록
2. 도서 검색
3. 도서 수정
4. 도서 삭제
5. 전체 출력
6. 종료
선택 > 4
삭제할 제목 : 혼자 공부하는 자바
삭제 완료
------------------------
1. 도서 등록
2. 도서 검색
3. 도서 수정
4. 도서 삭제
5. 전체 출력
6. 종료
선택 > 5
Book{title='자바의 정석', author='남궁성(개정판)'}
------------------------
1. 도서 등록
2. 도서 검색
3. 도서 수정
4. 도서 삭제
5. 전체 출력
6. 종료
선택 > 6
프로그램 종료

💡 힌트

  1. Scanner 사용: Scanner sc = new Scanner(System.in);
  2. while 루프: boolean run = true;로 반복 제어
  3. 메뉴 입력 처리: Integer.parseInt(sc.nextLine()) 사용
  4. 예외 처리: try-catch로 숫자 입력 예외 처리
  5. 문자열 비교: equals() 메서드 사용
  6. 삭제 메서드: 인덱스가 필요하므로 일반 for문 사용

✅ 체크리스트

  • Book 클래스에 필드, 생성자, toString() 메서드 구현
  • 메뉴 시스템 구현 (while 루프)
  • Scanner를 사용한 사용자 입력 처리
  • 예외 처리 (숫자 입력, 잘못된 메뉴)
  • findBook() 메서드 구현
  • updateBook() 메서드 구현
  • deleteBook() 메서드 구현
  • 각 메뉴별 기능 구현
  • 프로그램 종료 기능

📝 추가 도전 과제 (선택사항)

  1. 같은 저자의 도서를 모두 찾는 메뉴 추가 (7번)
  2. 도서 개수를 출력하는 기능 추가
  3. 도서 제목으로 정렬하는 기능 추가
  4. 도서 정보를 파일로 저장/불러오기 기능 추가

도서 관리 시스템 - 메뉴 기반 정답

📁 Book.java

package a0120;

public class Book {
    String title;   // 제목
    String author;  // 저자

    // 생성자
    public Book(String title, String author) {
        this.title = title;
        this.author = author;
    }

    // toString() 메서드: 객체를 문자열로 변환
    @Override
    public String toString() {
        return "Book{title='" + title + "', author='" + author + "'}";
    }
}

📁 BookApp.java

package a0120;

import java.util.ArrayList;
import java.util.Scanner;

public class BookApp {
    public static void main(String[] args) {

        ArrayList<Book> list = new ArrayList<>();
        Scanner sc = new Scanner(System.in);
        boolean run = true;

        while (run) {
            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.print("선택 > ");

            int menu;
            try {
                menu = Integer.parseInt(sc.nextLine());
            } catch (Exception e) {
                System.out.println("숫자만 입력하세요");
                continue;
            }

            switch (menu) {
                case 1: // 등록
                    System.out.print("제목 입력 : ");
                    String title = sc.nextLine();

                    System.out.print("저자 입력 : ");
                    String author = sc.nextLine();

                    list.add(new Book(title, author));
                    System.out.println("도서 등록 완료");
                    break;

                case 2: // 검색
                    System.out.print("검색할 제목 : ");
                    title = sc.nextLine();

                    Book b = findBook(list, title);
                    if (b != null) {
                        System.out.println(b);
                    } else {
                        System.out.println("도서가 없습니다");
                    }
                    break;

                case 3: // 수정
                    System.out.print("수정할 제목 : ");
                    title = sc.nextLine();

                    System.out.print("새 저자 입력 : ");
                    author = sc.nextLine();

                    if (updateBook(list, title, author)) {
                        System.out.println("수정 완료");
                    } else {
                        System.out.println("해당 도서가 없습니다");
                    }
                    break;

                case 4: // 삭제
                    System.out.print("삭제할 제목 : ");
                    title = sc.nextLine();

                    if (deleteBook(list, title)) {
                        System.out.println("삭제 완료");
                    } else {
                        System.out.println("삭제할 도서가 없습니다");
                    }
                    break;

                case 5: // 전체 출력
                    if (list.isEmpty()) {
                        System.out.println("등록된 도서가 없습니다");
                    } else {
                        for (Book book : list) {
                            System.out.println(book);
                        }
                    }
                    break;

                case 6: // 종료
                    run = false;
                    System.out.println("프로그램 종료");
                    break;

                default:
                    System.out.println("1~6번 중에 선택하세요");
            }
        }
        sc.close();
    }

    // 도서 검색
    static Book findBook(ArrayList<Book> list, String title) {
        for (Book b : list) {
            if (b.title.equals(title)) {
                return b;
            }
        }
        return null;
    }

    // 도서 수정
    static boolean updateBook(ArrayList<Book> list, String title, String newAuthor) {
        for (Book b : list) {
            if (b.title.equals(title)) {
                b.author = newAuthor;
                return true;
            }
        }
        return false;
    }

    // 도서 삭제
    static boolean deleteBook(ArrayList<Book> list, String title) {
        for (int i = 0; i < list.size(); i++) {
            if (list.get(i).title.equals(title)) {
                list.remove(i);
                return true;
            }
        }
        return false;
    }
}

🔍 코드 설명

1. Book 클래스

  • 필드: 도서의 제목과 저자 정보를 저장
  • 생성자: 제목과 저자를 받아 객체 초기화
  • toString() 메서드: 객체를 문자열로 표현하여 출력에 사용

2. BookApp 클래스 - 메인 구조

2.1 변수 선언

ArrayList<Book> list = new ArrayList<>();  // 도서 목록 저장
Scanner sc = new Scanner(System.in);       // 사용자 입력 받기
boolean run = true;                        // 프로그램 실행 제어

2.2 메뉴 반복 구조

while (run) {
    // 메뉴 출력
    // 사용자 입력 받기
    // 메뉴에 따라 기능 실행
}

2.3 예외 처리

try {
    menu = Integer.parseInt(sc.nextLine());
} catch (Exception e) {
    System.out.println("숫자만 입력하세요");
    continue;  // 다시 메뉴로 돌아감
}

📊 메뉴별 동작 원리

1️⃣ 도서 등록 (case 1)

사용자 입력:
  - 제목: "자바의 정석"
  - 저자: "남궁성"
    ↓
list.add(new Book("자바의 정석", "남궁성"))
    ↓
ArrayList에 Book 객체 추가
    ↓
"도서 등록 완료" 출력

2️⃣ 도서 검색 (case 2)

사용자 입력:
  - 검색할 제목: "자바의 정석"
    ↓
findBook(list, "자바의 정석") 호출
    ↓
리스트를 순회하며 제목이 일치하는 Book 찾기
    ↓
찾으면: Book 객체 반환 → 출력
못 찾으면: null 반환 → "도서가 없습니다" 출력

3️⃣ 도서 수정 (case 3)

사용자 입력:
  - 수정할 제목: "자바의 정석"
  - 새 저자: "남궁성(개정판)"
    ↓
updateBook(list, "자바의 정석", "남궁성(개정판)") 호출
    ↓
제목으로 도서 찾기
    ↓
찾으면: author 필드 수정 → true 반환 → "수정 완료"
못 찾으면: false 반환 → "해당 도서가 없습니다"

4️⃣ 도서 삭제 (case 4)

사용자 입력:
  - 삭제할 제목: "혼자 공부하는 자바"
    ↓
deleteBook(list, "혼자 공부하는 자바") 호출
    ↓
인덱스로 순회하며 제목이 일치하는 Book 찾기
    ↓
찾으면: list.remove(i) 실행 → true 반환 → "삭제 완료"
못 찾으면: false 반환 → "삭제할 도서가 없습니다"

5️⃣ 전체 출력 (case 5)

list.isEmpty() 체크
    ↓
비어있으면: "등록된 도서가 없습니다"
    ↓
비어있지 않으면:
  for (Book book : list) {
      System.out.println(book);  // toString() 자동 호출
  }

6️⃣ 종료 (case 6)

run = false 설정
    ↓
while (run) 조건이 false가 됨
    ↓
루프 종료
    ↓
"프로그램 종료" 출력
    ↓
sc.close()로 Scanner 닫기

🔄 전체 실행 흐름도

프로그램 시작
    ↓
ArrayList<Book> list 생성
Scanner sc 생성
boolean run = true
    ↓
┌─────────────────────────┐
│   while (run) 루프      │
│                         │
│   1. 메뉴 출력           │
│   2. 사용자 입력 받기    │
│   3. 예외 처리           │
│   4. switch문으로 분기   │
│      - case 1: 등록     │
│      - case 2: 검색     │
│      - case 3: 수정     │
│      - case 4: 삭제     │
│      - case 5: 전체출력  │
│      - case 6: 종료     │
│                         │
└─────────────────────────┘
         ↑              │
         │              │
         └──────────────┘
      (run이 false가 될 때까지 반복)
    ↓
Scanner 닫기
프로그램 종료

📐 메서드별 상세 설명

🔎 findBook() - 검색

static Book findBook(ArrayList<Book> list, String title) {
    for (Book b : list) {              // 향상된 for문으로 리스트 순회
        if (b.title.equals(title)) {    // 제목이 일치하면
            return b;                   // 해당 Book 객체 반환
        }
    }
    return null;                        // 찾지 못하면 null 반환
}

동작 순서:

  1. 리스트의 첫 번째 요소부터 마지막까지 순회
  2. 각 Book 객체의 title 필드와 검색할 title 비교
  3. 일치하는 객체를 찾으면 즉시 반환 (선형 검색)
  4. 찾지 못하면 null 반환

⚠️ 주의사항:

  • 문자열 비교는 equals() 사용 (== 사용 금지)
  • null 체크 필요 (호출하는 쪽에서 처리)

✏️ updateBook() - 수정

static boolean updateBook(ArrayList<Book> list, String title, String newAuthor) {
    for (Book b : list) {              // 리스트 순회
        if (b.title.equals(title)) {    // 제목이 일치하면
            b.author = newAuthor;       // author 필드 직접 수정
            return true;                // 성공
        }
    }
    return false;                       // 실패 (해당 제목의 도서 없음)
}

동작 순서:

  1. 리스트를 순회하며 제목이 일치하는 Book 찾기
  2. 찾은 객체의 author 필드를 newAuthor로 변경
  3. 성공/실패 여부를 boolean으로 반환

⚠️ 주의사항:

  • ArrayList에 저장된 것은 객체의 참조(주소)
  • 참조를 통해 필드를 수정하면 원본 객체가 수정됨

🗑️ deleteBook() - 삭제

static boolean deleteBook(ArrayList<Book> list, String title) {
    for (int i = 0; i < list.size(); i++) {      // 인덱스로 순회
        if (list.get(i).title.equals(title)) {     // 제목 일치 확인
            list.remove(i);                       // 인덱스 i의 요소 제거
            return true;                          // 성공
        }
    }
    return false;                                 // 실패
}

동작 순서:

  1. 인덱스 0부터 시작하여 순회 (일반 for문 필요)
  2. 해당 인덱스의 Book 제목이 일치하면
  3. list.remove(i)로 해당 인덱스의 요소 제거
  4. 제거 후 뒤의 요소들이 자동으로 앞으로 이동

⚠️ 왜 일반 for문을 사용하나요?

  • 삭제 시 인덱스가 필요하기 때문
  • 향상된 for문에서는 현재 인덱스를 알 수 없음

🎯 핵심 포인트

1. 메뉴 기반 프로그램 구조

  • while 루프: 프로그램이 종료될 때까지 반복
  • boolean 변수: run으로 프로그램 실행 제어
  • switch문: 메뉴 선택에 따른 기능 분기

2. 사용자 입력 처리

  • Scanner: Scanner sc = new Scanner(System.in);
  • nextLine(): 한 줄 전체를 문자열로 읽기
  • Integer.parseInt(): 문자열을 정수로 변환

3. 예외 처리

  • try-catch: 숫자 입력 시 예외 처리
  • continue: 예외 발생 시 다시 메뉴로 돌아가기
  • default: switch문에서 잘못된 메뉴 번호 처리

4. ArrayList 활용

  • 동적 크기: 필요에 따라 크기가 자동으로 변함
  • 객체 참조 저장: 실제 객체가 아닌 참조(주소)를 저장
  • isEmpty(): 리스트가 비어있는지 확인

5. 객체 지향 개념

  • 클래스와 객체: Book 클래스로 도서 정보 표현
  • 캡슐화: 필드와 메서드를 하나의 클래스로 묶음
  • toString(): 객체를 문자열로 표현

🔍 실행 결과 예시

------------------------
1. 도서 등록
2. 도서 검색
3. 도서 수정
4. 도서 삭제
5. 전체 출력
6. 종료
선택 > 1
제목 입력 : 자바의 정석
저자 입력 : 남궁성
도서 등록 완료
------------------------
1. 도서 등록
2. 도서 검색
3. 도서 수정
4. 도서 삭제
5. 전체 출력
6. 종료
선택 > 1
제목 입력 : 혼자 공부하는 자바
저자 입력 : 신용권
도서 등록 완료
------------------------
1. 도서 등록
2. 도서 검색
3. 도서 수정
4. 도서 삭제
5. 전체 출력
6. 종료
선택 > 5
Book{title='자바의 정석', author='남궁성'}
Book{title='혼자 공부하는 자바', author='신용권'}
------------------------
1. 도서 등록
2. 도서 검색
3. 도서 수정
4. 도서 삭제
5. 전체 출력
6. 종료
선택 > 2
검색할 제목 : 자바의 정석
Book{title='자바의 정석', author='남궁성'}
------------------------
1. 도서 등록
2. 도서 검색
3. 도서 수정
4. 도서 삭제
5. 전체 출력
6. 종료
선택 > 3
수정할 제목 : 자바의 정석
새 저자 입력 : 남궁성(개정판)
수정 완료
------------------------
1. 도서 등록
2. 도서 검색
3. 도서 수정
4. 도서 삭제
5. 전체 출력
6. 종료
선택 > 5
Book{title='자바의 정석', author='남궁성(개정판)'}
Book{title='혼자 공부하는 자바', author='신용권'}
------------------------
1. 도서 등록
2. 도서 검색
3. 도서 수정
4. 도서 삭제
5. 전체 출력
6. 종료
선택 > 4
삭제할 제목 : 혼자 공부하는 자바
삭제 완료
------------------------
1. 도서 등록
2. 도서 검색
3. 도서 수정
4. 도서 삭제
5. 전체 출력
6. 종료
선택 > 5
Book{title='자바의 정석', author='남궁성(개정판)'}
------------------------
1. 도서 등록
2. 도서 검색
3. 도서 수정
4. 도서 삭제
5. 전체 출력
6. 종료
선택 > 7
1~6번 중에 선택하세요
------------------------
1. 도서 등록
2. 도서 검색
3. 도서 수정
4. 도서 삭제
5. 전체 출력
6. 종료
선택 > abc
숫자만 입력하세요
------------------------
1. 도서 등록
2. 도서 검색
3. 도서 수정
4. 도서 삭제
5. 전체 출력
6. 종료
선택 > 6
프로그램 종료

🎓 학습 포인트

✅ 이해해야 할 개념

  1. 메뉴 기반 프로그램 구조

    • while 루프로 반복 실행
    • switch문으로 기능 분기
  2. 사용자 입력 처리

    • Scanner 클래스 사용법
    • nextLine() vs next() 차이
  3. 예외 처리

    • try-catch 문법
    • NumberFormatException 처리
  4. ArrayList 활용

    • 동적 리스트 관리
    • CRUD 작업 구현
  5. 객체 지향 프로그래밍

    • 클래스와 객체
    • 메서드 분리와 재사용

✅ 주의할 점

  1. Scanner 사용

    • sc.nextLine() 사용 시 주의 (버퍼 문제)
    • 프로그램 종료 시 sc.close() 호출
  2. 문자열 비교

    • == 연산자 사용 금지
    • equals() 메서드 사용 필수
  3. null 체크

    • findBook() 결과가 null일 수 있음
    • null 체크 후 사용
  4. 인덱스 관리

    • 삭제 시 일반 for문 사용
    • 향상된 for문은 인덱스 접근 불가

✅ 개선 가능한 부분

  1. 캡슐화

    • Book 클래스의 필드를 private로 변경
    • Getter/Setter 메서드 추가
  2. 예외 처리 강화

    • 빈 문자열 입력 체크
    • 더 구체적인 예외 처리
  3. 기능 확장

    • 같은 저자의 도서 검색
    • 도서 정렬 기능
    • 파일 저장/불러오기
  4. 코드 구조화

    • 메서드 분리
    • 상수 정의 (메뉴 번호 등)