• Java 小样例:图书馆课程设计(Java 8 版)


    用 Java 模拟一个图书馆。包含创建图书、创建读者、借书、还书、列出全部图书、列出全部读者、列出已借出的图书、列出过期未还的图书等功能。

    每一个读者最多仅仅能借 3 本书,每一个书最多仅仅能借 3 个星期,超过就算过期。

    这个样例跟 http://blog.csdn.net/yidinghe/article/details/3940437 相比,添加了 Java 8 特有的语法,包含:Lambda 表达式,java.time 日期 API,streaming API 等。功能也比前者略微完好了些。体积有所减小。

    import java.time.LocalDate;
    import java.time.format.DateTimeFormatter;
    import java.time.temporal.ChronoUnit;
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
    import java.util.Scanner;
    import java.util.concurrent.atomic.AtomicInteger;
    import java.util.function.Supplier;
    import java.util.stream.Collectors;
    
    /**
     * 图书馆样例 Java 8 版本号
     * created at 2014/11/4
     *
     * @author Yiding
     */
    public class LibraryManager {
    
        public static final Scanner SCANNER = new Scanner(System.in);
    
        public static final String NUMBERS_ONLY = "^\d+$"; // 表示仅仅同意输入数字
    
        public static final String ANY_CONTENT = "^\S+$";  // 表示能够输入不论什么内容
    
        public static void main(String[] args) {
            new LibraryManager().start();
        }
    
        ////////////////////////////////////////////////////////////////
    
        private Library library = new Library();
    
        private ArrayList<Command> commands = new ArrayList<>();
    
        private String mainMenu;
    
        /**
         * 构造方法
         */
        public LibraryManager() {
            initCommands();
            initStudents();
            initBooks();
        }
    
        private void initBooks() {
            this.library.addBook("论程序猿的自我修养", "带鱼", BookType.科学类.toString());
            this.library.addBook("印度四大名著全集", "阿达木", BookType.文学类.toString());
            this.library.addBook("睡眠的优点", "程序猿阿迪", BookType.科学类.toString());
            this.library.addBook("架构师2014年10月刊", "漂亮女人网", BookType.杂志.toString());
        }
    
        private void initStudents() {
            this.library.students.add(new Student("张三"));
            this.library.students.add(new Student("李四"));
            this.library.students.add(new Student("王五"));
        }
    
        /**
         * 初始化命令和主菜单
         */
        private void initCommands() {
            addCommand(new ListCommand<>("全部图书:", () -> library.books), "查询全部图书");
            addCommand(new ListCommand<>("全部学生:", () -> library.students), "查询全部学生");
            addCommand(new AddBookCommand(), "加入图书");
            addCommand(new DeleteBookCommand(), "删除图书");
            addCommand(new BorrowBookCommand(), "借阅图书");
            addCommand(new ReturnBookCommand(), "归还图书");
            addCommand(new ListCommand<>("全部借阅过期的图书:", library::expiredBooks), "查询借阅过期的图书");
            addCommand(new ExitCommand(), "退出");
    
            this.mainMenu = toMenu("请输入命令", this.commands);
        }
    
        private void addCommand(Command command, String title) {
            command.title = title;
            this.commands.add(command);
        }
    
        /**
         * 開始运行交互
         */
        private void start() {
            CommandResult result;
    
            // 在 while 条件中推断命令的运行结果是否表示要退出程序
            // 仅仅有 ExitCommand 的运行结果是 CommandResult.EXIT
            do {
    
                try {
                    String command = prompt(mainMenu, NUMBERS_ONLY); // 选择命令
                    result = executeCommand(command);                // 运行命令
                } catch (CommandCancelException e) {
                    result = CommandResult.FAIL;
                }
    
                System.out.println(result.prompt + "
    ");
            } while (result != CommandResult.EXIT);
        }
    
        /**
         * 打印一条提示消息并返回用户的输入
         *
         * @param prompt  提示消息
         * @param pattern 指定格式,假设用户的输入不符合格式则会重复提示又一次输入。为空则不检查用户输入
         *
         * @return 用户的输入
         */
        private String prompt(String prompt, String pattern) {
            String userInput;
    
            // 在 while 条件中推断用户输入的内容是否符合 pattern 指定的格式
            // 假设 pattern 为 null 则不做推断
            do {
                System.out.print(prompt);
                userInput = SCANNER.nextLine();
    
                // 用户直接回车时,表示取消命令运行
                if (userInput.equals("")) {
                    throw new CommandCancelException();
                }
    
            } while (pattern != null && !userInput.matches(pattern));
    
            return userInput;
        }
    
        // 打印一组选项并返回用户选择的选项内容
        private String prompt(String prompt, List<?> options) {
            int index = promptIndex(prompt, options);
            return options.get(index - 1).toString();
        }
    
        // 打印一组选项并返回用户选择的位置
        private int promptIndex(String prompt, List<?

    > options) { String menu = toMenu(prompt, options); int index; do { index = Integer.parseInt(prompt(menu, NUMBERS_ONLY)); } while (index == 0 || index > options.size()); return index; } /** * 生成菜单内容 * * @param prompt 提示,在列出全部选项后打印出来 * @param options 选项 * * @return 主菜单内容 */ private <T> String toMenu(String prompt, List<T> options) { final ArrayList<String> lines = new ArrayList<>(); final AtomicInteger counter = new AtomicInteger(); options.forEach((t) -> { int index = counter.incrementAndGet(); String line = index + ": " + t.toString(); lines.add(line); }); return String.join(" ", lines) + " " + prompt + "(1-" + lines.size() + "):"; } /** * 运行用户命令 * * @param command 用户命令序号 * * @return 运行结果 */ private CommandResult executeCommand(String command) { int index = Integer.parseInt(command); if (index > 0 && index <= commands.size()) { return commands.get(index - 1).execute(); } else { return CommandResult.OK; } } //////////////////////////////////////////////////////////////// static enum CommandResult { OK("命令已完毕。"), FAIL("命令已取消。"), EXIT(""); public String prompt; // 在每一个命令结束时打印出来 CommandResult(String prompt) { this.prompt = prompt; } } static enum BookType {文学类, 科学类, 杂志} // 表示用户取消命令的异常 static class CommandCancelException extends RuntimeException { } static class Book { public static final int EXPIRE_BORROW_DAYS = 21; public String name; public String author; public String type; public String borrowedBy; public String borrowDate; Book(String name, String author, String type) { this.name = name; this.author = author; this.type = type; } public boolean isBorrowed() { return this.borrowedBy != null; } @Override public String toString() { return name + ",作者:" + author + "。" + type + (isBorrowed() ? " -- 已被'" + borrowedBy + "'于" + borrowDate + "借出" : ""); } public boolean isExpired() { if (!isBorrowed()) { return false; } // 从当前时间反推过期的借阅时间。假设实际借阅时间在过期的借阅时间之前,则表示过期了 LocalDate maxBorrowDate = LocalDate.now().minus(EXPIRE_BORROW_DAYS, ChronoUnit.DAYS); String maxBorrowDateStr = DateTimeFormatter.ofPattern("yyyyMMdd").format(maxBorrowDate); return this.borrowDate.compareTo(maxBorrowDateStr) < 0; } } static class Student { public static final int MAX_BORROW = 3; public String name; Student(String name) { this.name = name; } @Override public String toString() { return name; } } //////////////////////////////////////////////////////////////// class Library { private List<Book> books = new ArrayList<>(); private List<Student> students = new ArrayList<>(); /** * 加入书籍 * * @param bookName 书名 * @param author 作者 * @param type 类型 * * @return 运行结果 */ public CommandResult addBook(String bookName, String author, String type) { if (books.stream().anyMatch((b) -> b.name.equals(bookName))) { System.out.println("加入失败:书名已存在"); return CommandResult.FAIL; } this.books.add(new Book(bookName, author, type)); return CommandResult.OK; } public List<Book> availableBooks() { return this.books.stream().filter((b) -> !b.isBorrowed()).collect(Collectors.toList()); } public List<Book> borrowedBooks() { return this.books.stream().filter(Book::isBorrowed).collect(Collectors.toList()); } public List<Book> expiredBooks() { return this.books.stream().filter(Book::isExpired).collect(Collectors.toList()); } /** * 删除书籍 * * @param index 序号 * * @return 运行结果 */ public CommandResult deleteBook(int index) { this.books.remove(index); return CommandResult.OK; } public int countBorrowedBooks(String student) { return (int) this.books.stream().filter((b) -> student.equals(b.borrowedBy)).count(); } } //////////////////////////////////////////////////////////////// /** * 表示命令的抽象类 */ static abstract class Command { public String title; // 命令标题,将显示在主菜单中 abstract CommandResult execute(); @Override public String toString() { return title; } } // 列出满足要求的对象 class ListCommand<T> extends Command { private Supplier<List<T>> supplier; // 查询满足要求的对象的方法 private String title; // 输出标题 ListCommand(String title, Supplier<List<T>> supplier) { this.title = title; this.supplier = supplier; } @Override CommandResult execute() { System.out.println(" " + title); supplier.get().forEach(System.out::println); return CommandResult.OK; } } // 加入图书 class AddBookCommand extends Command { @Override CommandResult execute() { return library.addBook( prompt("请输入书名:", ANY_CONTENT), prompt("请输入作者:", ANY_CONTENT), prompt("请选择书籍类型:", Arrays.asList(BookType.values())) ); } } // 删除图书 class DeleteBookCommand extends Command { @Override CommandResult execute() { if (library.books.isEmpty()) { System.out.println("没有可删除的书籍。"); return CommandResult.FAIL; } int index = promptIndex("请选择书籍序号", library.books); return library.deleteBook(index - 1); } } // 借阅图书 class BorrowBookCommand extends Command { @Override CommandResult execute() { List<Book> availableBooks = library.availableBooks(); if (availableBooks.isEmpty()) { System.out.println("没有可借阅的图书。"); return CommandResult.FAIL; } int index = promptIndex("请选择要借阅的图书", availableBooks); Book book = availableBooks.get(index - 1); String student = prompt("请选择借阅者:", library.students); if (library.countBorrowedBooks(student) >= Student.MAX_BORROW) { System.out.println("该同学不能借阅很多其它图书了。"); return CommandResult.FAIL; } String bDate = prompt("请输入借阅日期(YYYYMMDD):", "^\d{8}$"); book.borrowedBy = student; book.borrowDate = bDate; return CommandResult.OK; } } // 归还图书 class ReturnBookCommand extends Command { @Override CommandResult execute() { List<Book> borrowedBooks = library.borrowedBooks(); if (borrowedBooks.isEmpty()) { System.out.println("没有图书须要归还。

    "); return CommandResult.FAIL; } int index = promptIndex("请选择已借阅的图书", borrowedBooks); Book book = borrowedBooks.get(index - 1); book.borrowedBy = null; book.borrowDate = null; System.out.println("图书已归还。"); return CommandResult.OK; } } // 退出程序 class ExitCommand extends Command { @Override CommandResult execute() { return CommandResult.EXIT; } } }



  • 相关阅读:
    柱状图最大的矩形
    单词搜索
    最小覆盖子串
    颜色分类
    编辑距离
    X的平方根
    二进制求和
    最大子序和
    N皇后
    java8-14-时间API
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/5159259.html
Copyright © 2020-2023  润新知