Java小例子:图书馆课程设计

用 Java 模拟一个图书馆。包括创建图书、创建读者、借书、还书、列出所有图书、 列出所有读者、列出已借出的图书、列出过期未还的图书等功能。每个读者最多只能借 3 本书,每个书最多只能借 3 个星期,超过就算过期。

下面是一个命令行下的实现。这个例子的主要目的是向初学者展示内部类的好处。 Command 及其子类都是 LibrarySimulator 的内部类。它们可以无阻碍的访问 LibrarySimulator 的成员。使用内部类,而不是大量的 if-else,让程序更容易扩展。

01.import java.io.BufferedReader;
02.import java.io.IOException;
03.import java.io.InputStreamReader;
04.import java.text.SimpleDateFormat;
05.import java.util.*;
06.
07./**
08. * 一个图书馆的课程设计。主要功能:
09. * 1. 创建图书
10. * 2. 创建读者
11. * 3. 借书
12. * 4. 还书
13. * 5. 列出所有书
14. * 6. 列出已借书
15. * 7. 列出超过日期未还的书
16. */
17.public class LibrarySimulator {
18.
19.    // 主菜单
20.    private static final String MAIN_MENU = "1. 列出所有的书\n" +
21.            "2. 列出已借出的书\n" +
22.            "3. 列出过期未还的书\n" +
23.            "4. 列出所有读者\n" +
24.            "5. 创建图书\n" +
25.            "6. 创建读者\n" +
26.            "7. 借书\n" +
27.            "8. 还书\n" +
28.            "9. 退出\n" +
29.            "请输入序号:";
30.
31.    // 选择图书类型的菜单。在借书和添加图书的时候都会用到
32.    private static final String TYPE_MENU;
33.
34.    // 表示一个数字的正则表达式
35.    private static final String DIGIT_CHOICE_PATTERN = "^\\d$";
36.
37.    // 表示非空字符串
38.    private static final String NOT_EMPTY_PATTERN = "\\S.*";
39.
40.    // 日期格式
41.    static final String DATE_PATTERN = "yyyy/MM/dd";
42.
43.    // 验证用户输入日期的正则表达式
44.    static final String DATE_FORMAT_PATTERN = "^\\d{4}/\\d{2}/\\d{2}$";
45.
46.    // 预定义的图书类型
47.    static HashMap<String, String> TYPES = new LinkedHashMap<String, String>();
48.
49.    static {
50.        TYPES.put("1", "科学类");
51.        TYPES.put("2", "文学类");  // 新的类别可以继续在后面添加
52.        TYPE_MENU = createTypeMenu();
53.    }
54.
55.    // 生成选择类别的菜单
56.    private static String createTypeMenu() {
57.        String str = "";
58.        for (String index : TYPES.keySet()) {
59.            str += index + ". " + TYPES.get(index) + "\n";
60.        }
61.        return str + "请选择书的类型:";
62.    }
63.
64.
65.    private HashMap<Integer, Command> commands = new HashMap<Integer, Command>();
66.
67.    private ArrayList<Book> books = new ArrayList<Book>();
68.
69.    private ArrayList<Reader> readers = new ArrayList<Reader>();
70.
71.    // 程序入口。这里创建一个 LibrarySimulator 用于模拟界面。
72.    public static void main(String[] args) {
73.        new LibrarySimulator().start();
74.    }
75.
76.    /**
77.     * 构造函数
78.     */
79.    public LibrarySimulator() {
80.        commands.put(1, new Command1());
81.        commands.put(2, new Command2());
82.        commands.put(3, new Command3());
83.        commands.put(4, new Command4());
84.        commands.put(5, new Command5());
85.        commands.put(6, new Command6());
86.        commands.put(7, new Command7());
87.        commands.put(8, new Command8());
88.    }
89.
90.    /**
91.     * 这里接受用户输入,执行操作,然后再等待用户输入,这样不停的循环。
92.     */
93.    private void start() {
94.        String index = prompt(MAIN_MENU, DIGIT_CHOICE_PATTERN);
95.
96.        while (!index.equals("9")) {
97.            executeCommand(index);
98.            index = prompt(MAIN_MENU, DIGIT_CHOICE_PATTERN);
99.        }
100.    }
101.
102.    // 根据序号执行命令
103.    private void executeCommand(String index) {
104.        Command command = commands.get(Integer.parseInt(index));
105.        if (command != null) {
106.            String result = command.execute();
107.            System.out.println(result + "\n");
108.        }
109.    }
110.
111.    // 打印一条提示信息,然后读取并返回用户输入
112.    private String prompt(String message, String pattern) {
113.        System.out.print(message);
114.        if (pattern == null) {
115.            return readInput();
116.        } else {
117.            String result = "";
118.            while (!result.matches(pattern)) {
119.                result = readInput();
120.            }
121.            return result;
122.        }
123.    }
124.
125.    // 读取用户输入
126.    private String readInput() {
127.        try {
128.            BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
129.            return reader.readLine();
130.        } catch (IOException e) {
131.            e.printStackTrace();
132.            return "";
133.        }
134.    }
135.
136.    // 根据名字查找读者。找不到则返回 null。
137.    private Reader getReaderByName(String readerName) {
138.        for (Reader reader : readers) {
139.            if (reader.getName().equals(readerName)) {
140.                return reader;
141.            }
142.        }
143.        return null;
144.    }
145.
146.    // 根据名字查找图书。找不到则返回 null。
147.    private Book getBookByName(String bookName) {
148.        for (Book book : books) {
149.            if (book.getName().equals(bookName)) {
150.                return book;
151.            }
152.        }
153.        return null;
154.    }
155.
156. /*===================================================================*/
157.
158.    /**
159.     * 代表命令的抽象类
160.     */
161.    private abstract class Command {
162.
163.        protected abstract String execute();
164.    }
165.
166.    /////////////////////////////////////////////////// 列出所有图书
167.    private class Command1 extends Command {
168.
169.        protected String execute() {
170.            for (Book book : getBooks()) {
171.                System.out.println(book);   // 这里会自动调用 book.toString()
172.            }
173.            return "命令完成。";
174.        }
175.
176.        private ArrayList<Book> getBooks() {
177.            ArrayList<Book> result = new ArrayList<Book>();
178.
179.            for (Book book : books) {
180.                if (isValid(book)) {
181.                    result.add(book);
182.                }
183.            }
184.            return result;
185.        }
186.
187.        // 考虑到第 1、2、3 条命令大体相同,这里提供了一个给子类覆写的方法
188.        protected boolean isValid(Book book) {
189.            return true;
190.        }
191.    }
192.
193.    ///////////////////////////////////////////////////// 列出已借出的书。
194.    // 注意它的父类不是 Command,而是 Command1。这样节省了很多重复代码
195.    private class Command2 extends Command1 {
196.
197.        @Override
198.        protected boolean isValid(Book book) {
199.            return book.isBorrowed();
200.        }
201.    }
202.
203.    //////////////////////////////////////////////////////// 列出过期未还的书
204.    private class Command3 extends Command1 {
205.
206.        @Override
207.        protected boolean isValid(Book book) {
208.            // 判断一本书接触过期与否的方法最好在 Book 类中去实现。
209.            return book.isExpired();
210.        }
211.    }
212.
213.    /////////////////////////////////////////////// 创建图书
214.    private class Command5 extends Command {
215.
216.        protected String execute() {
217.            String type = getType();
218.            String name = getName();
219.            if (getBookByName(name) == null) {
220.                books.add(new Book(type, name));
221.                return "图书添加成功。";
222.            } else {
223.                return "图书添加失败:名称已存在。";
224.            }
225.        }
226.
227.        // 获得用户输入的书名
228.        private String getName() {
229.            return prompt("请输入书名:", NOT_EMPTY_PATTERN);
230.        }
231.
232.        // 获得用户选择的图书类型
233.        private String getType() {
234.            return prompt(TYPE_MENU, DIGIT_CHOICE_PATTERN);
235.        }
236.    }
237.
238.    /////////////////////////////////////////////////////// 列出所有读者
239.    private class Command4 extends Command {
240.
241.        protected String execute() {
242.            for (Reader reader : readers) {
243.                System.out.println(reader);
244.            }
245.            return "命令完成。";
246.        }
247.    }
248.
249.    /////////////////////////////////////////////////////// 创建读者
250.    private class Command6 extends Command {
251.
252.        protected String execute() {
253.            String name = getName();
254.            if (getReaderByName(name) == null) {
255.                readers.add(new Reader(name));
256.                return "读者创建成功。";
257.            } else {
258.                return "读者创建失败:名字已经存在。";
259.            }
260.        }
261.
262.        public String getName() {
263.            return prompt("请输入读者名字:", NOT_EMPTY_PATTERN);
264.        }
265.    }
266.
267.    /////////////////////////////////////////////////////// 借书
268.    private class Command7 extends Command {
269.
270.        protected String execute() {
271.            Reader reader = getReader();
272.            if (reader == null) {
273.                System.out.println("命令取消。");
274.                return "";
275.            }
276.
277.            Book book = getBook();
278.            if (book == null) {
279.                System.out.println("命令取消。");
280.                return "";
281.            }
282.
283.            String borrowDate = getBorrowDate();
284.
285.            book.borrowBy(reader.getName(), borrowDate);
286.            reader.addBorrowCount();
287.
288.            return "成功借出。";
289.        }
290.
291.        private String getBorrowDate() {
292.            String now = new SimpleDateFormat(LibrarySimulator.DATE_PATTERN).format(new Date());
293.            String date = null;
294.            while (date == null || !date.matches(DATE_FORMAT_PATTERN)) {
295.                date = prompt("请输入结束日期(如" + now + ")", NOT_EMPTY_PATTERN);
296.            }
297.            return date;
298.        }
299.
300.        private Book getBook() {
301.            Book book = null;
302.            while (book == null || book.isBorrowed()) {
303.                String bookName = prompt("请输入图书名字:", null);
304.                if (bookName.equals("")) {
305.                    return null;
306.                }
307.
308.                book = getBookByName(bookName);
309.                if (book == null) {
310.                    System.out.println("图书不存在。");
311.                } else if (book.isBorrowed()) {
312.                    System.out.println("图书已经被借出。");
313.                }
314.            }
315.            return book;
316.        }
317.
318.        private Reader getReader() {
319.            Reader reader = null;
320.            while (reader == null || !reader.canBorrow()) {
321.                String readerName = prompt("请输入读者名字:", null);
322.                if (readerName.equals("")) {
323.                    return null;
324.                }
325.
326.                reader = getReaderByName(readerName);
327.                if (reader == null) {
328.                    System.out.println("读者不存在。");
329.                } else if (!reader.canBorrow()) {
330.                    System.out.println("该读者已经借了" + Reader.MAX_BORROW + " 本书,不能继续借了。");
331.                }
332.            }
333.            return reader;
334.        }
335.    }
336.
337.    ///////////////////////////////////////////// 还书
338.    private class Command8 extends Command {
339.
340.        protected String execute() {
341.            Reader reader = getReader();
342.            if (reader == null) {
343.                System.out.println("命令取消。");
344.                return "";
345.            }
346.
347.            Book book = getBook(reader);
348.            if (book == null) {
349.                System.out.println("命令取消。");
350.                return "";
351.            }
352.
353.            reader.reduceBorrowCount();
354.            book.returned();
355.            return "操作成功。";
356.        }
357.
358.        private Book getBook(Reader reader) {
359.            Book book = null;
360.            while (book == null || !reader.getName().equals(book.getBorrower())) {
361.                String bookName = prompt("请输入图书名字:", null);
362.                if (bookName.equals("")) {
363.                    return null;
364.                }
365.
366.                book = getBookByName(bookName);
367.                if (book == null) {
368.                    System.out.println("图书不存在。");
369.                } else if (!reader.getName().equals(book.getBorrower())) {
370.                    System.out.println("该读者没有借出这本书。");
371.                }
372.            }
373.            return book;
374.        }
375.
376.        private Reader getReader() {
377.            Reader reader = null;
378.            while (reader == null) {
379.                String readerName = prompt("请输入读者名字:", null);
380.                if (readerName.equals("")) {
381.                    return null;
382.                }
383.
384.                reader = getReaderByName(readerName);
385.                if (reader == null) {
386.                    System.out.println("读者不存在。");
387.                }
388.            }
389.            return reader;
390.        }
391.    }
392.}
393.
394.// 图书
395.class Book {
396.
397.    public static final int EXPIRE_DAYS = 21;   // 可借出天数,超过就算过期
398.
399.    private String type;
400.
401.    private String name;
402.
403.    private String borrowedBy = null;
404.
405.    private String borrowDate = null;
406.
407.    Book(String type, String name) {
408.        this.type = type;
409.        this.name = name;
410.    }
411.
412.    @Override
413.    public String toString() {
414.        String str = String.format("类别:%s  书名:%s", LibrarySimulator.TYPES.get(type), name);
415.        if (isBorrowed()) {
416.            str += "  借出人:" + borrowedBy + "  借出时间:" + borrowDate;
417.        }
418.        return str;
419.    }
420.
421.    public boolean isBorrowed() {
422.        return borrowedBy != null;
423.    }
424.
425.    public String getName() {
426.        return name;
427.    }
428.
429.    public String getBorrowDate() {
430.        return borrowDate;
431.    }
432.
433.    /**
434.     * 图书借出
435.     *
436.     * @param name 读者名字
437.     * @param date 借出日期。格式:参见 {@link LibrarySimulator#DATE_PATTERN}
438.     */
439.    public void borrowBy(String name, String date) {
440.        this.borrowedBy = name;
441.        this.borrowDate = date;
442.    }
443.
444.    public boolean isExpired() {
445.        if (borrowDate == null) {
446.            return false;   // 没有借出的书不出现在过期未还列表当中,所以这里返回 false。
447.        }
448.
449.        // 从当前时间往前推 3 个星期,如果还在借书日期之后,说明借书已经超过 3 个星期了
450.        String threeWksAgo = get3WeeksAgo();
451.        return threeWksAgo.compareTo(borrowDate) > 0;
452.    }
453.
454.    // 获得 3 个星期前的日期
455.    private String get3WeeksAgo() {
456.        SimpleDateFormat f = new SimpleDateFormat(LibrarySimulator.DATE_PATTERN);
457.        Calendar c = Calendar.getInstance();
458.        c.add(Calendar.DAY_OF_MONTH, -EXPIRE_DAYS);
459.        return f.format(c.getTime());
460.    }
461.
462.    public void returned() {
463.        this.borrowBy(null, null);
464.    }
465.
466.    public String getBorrower() {
467.        return borrowedBy;
468.    }
469.}
470.
471.// 读者
472.class Reader {
473.
474.    // 每位读者最多可同时借出 3 本书
475.    public static final int MAX_BORROW = 3;
476.
477.    private String name;
478.
479.    private int borowCount = 0;
480.
481.    public int getBorowCount() {
482.        return borowCount;
483.    }
484.
485.    Reader(String name) {
486.        this.name = name;
487.    }
488.
489.    public String getName() {
490.        return name;
491.    }
492.
493.    public void addBorrowCount() {
494.        borowCount++;
495.    }
496.
497.    public void reduceBorrowCount() {
498.        borowCount--;
499.    }
500.
501.    public boolean canBorrow() {
502.        return borowCount < MAX_BORROW;
503.    }
504.
505.    @Override
506.    public String toString() {
507.        return name;
508.    }
509.} 

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索图书
, string
, private
, execute方法未用到
, return
, 借书还书
, null
reader
,以便于您获取更多的相关知识。

时间: 2024-09-21 11:30:51

Java小例子:图书馆课程设计的相关文章

Java小例子

想当年学 BASIC 的时候,获取用户输入多简单,就一个 input:后来学 C, 也挺简单,一个 scanf():后来学 c++,同样简单,一个 cin <<:到了 Java 这里,麻烦来了. 1.简单的获取用户输入 下面是一个基本的例子,包含解释: 1.import java.io.BufferedReader; 2.import java.io.InputStreamReader; 3.import java.io.IOException; 4. 5.public class Basic

java ee-软件工程课程设计!!!求指导

问题描述 软件工程课程设计!!!求指导 使用java,jsp ,数据库,ajax,等等技术,开发一款电子商务平台,能够进行正常的运转,不要求最先进的技术,但要完成最基本的需求.. 解决方案 http://www.jb51.net/books/292002.html 解决方案二: 这种系统一般用mvc三层结构比较好做

Java小例子:按指定的编码读取文本文件内容

InputStreamReader 的构造函数提供了一个参数,用于指定通过什么编码将 读取到的字节流转换成字符.下面是一个例子: 01./** 02. * 读取指定的文本文件,并返回内容 03. * 04. * @param path 文件路径 05. * @param charset 文件编码 06. * 07. * @return 文件内容 08. * 09. * @throws IOException 如果文件不存在.打开失败或读取失败 10. */ 11.private static S

Java小例子:根据Map对象的内容创建JavaBean

Java 提供 java.beans.Introspector 类,帮助我们分析 JavaBean 类当中 有哪些属性,通过它可以方便的对 JavaBean 对象属性进行取值和赋值操作.下 面是一个例子,根据 Map 对象中的内容创建 JavaBean 对象. 01.import java.beans.BeanInfo; 02.import java.beans.IntrospectionException; 03.import java.beans.Introspector; 04.impor

Java小例子:通过Socket发送和接收文件

这是一个简单的包含发送端和接收端的例子.发送端向接收端发送文件名和文件内容 ,接收端将收到的文件保存在磁盘上.接收端可以同时接收多个发送端传来的文件,但没 有处理文件同名的情况. 这个例子中设计了一个简单的协议.发送的内容是这样的: 文件名长度(4字节)-文件名-文件内容长度(4字节)-文件内容 . 接收端也按照这个结构进行解析.建议先看 Client 类,再看 Server 类. 01.import java.io.*; 02.import java.net.ServerSocket; 03.

Java小例子:输出格式化数字

我们经常要将数字进行格式化,比如取2位小数,这是最常见的.Java 提供 DecimalFormat 类,帮你用最快的速度将数字格式化为你需要的样子.下面是 一个例子: import java.text.DecimalFormat; public class TestNumberFormat { public static void main(String[] args) { double pi = 3.1415927; // 圆周率 // 取一位整数 System.out.println(ne

Java小例子:分解质因数

这个例子演示如何利用递归来完成分解质因数. import java.util.List; import java.util.ArrayList; /** * 分解质因数 */ public class GetFactor { public static void main(String[] args) { List<Long> factors = getFactors(5555566666L, 2); System.out.println(factors); } /** * 通过递归实现分解质

Java小例子:打印一个金字塔

这是最基础的例子了,每个初学者都会要做这个题目.这个题目的目的是熟悉循环特 别是嵌套循环的使用.但是如果对 Java 足够熟悉,回头来再写这个程序,就完全不是这 么写的了. 嵌套循环是非常复杂的逻辑.特别是写得很长的嵌套循环,一个不小心把 j 写成 i, 就够你调试半天的.所以嵌套循环应该尽量避免.怎么避免?将内部循环提取成一个方法 .这样每个方法里都只有一层循环,容易看,容易改,而且不容易出错. import java.util.Arrays; /** * 打印一个字符组成的金字塔 */ pu

Java小例子:创建一个可拖拽图片的面板

今天在论坛上看到帖子希望能在 Swing 中实现像拖地图一样拖拽图片.这里是一个最 简单的实现,提供了一个基本思路. import javax.swing.*; import javax.swing.filechooser.FileNameExtensionFilter; import java.awt.*; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.M