Java从零开始 第15.5讲 常用库类的习题课
在开始进行本次习题课之前,让我们回忆一下在上一节习题课中的Book类:
创建一个书籍类Book类,其中包含书籍的名字和书籍的页码数,其中包含书名和页码数的get和set方法,和detail方法用于打印书籍的信息。(要求:输入页码数如果少于200,则提示并默认设置为200)
本节课中我们将对此习题进行延伸,题目可能有一定难度,在查看答案前请至少先进行尝试
给Book类添加多几个参数
首先让我们更改一下Book类的几个参数,它们分别为:
1.图书的名字
2.图书的价格
3.记录书的出版日期的date参数(要求构造函数中传入date对象,在显示时用则不同方法展示)
然后让我们给Book类添加几个方法,
1.重写toString方法和equals方法,要求toString能够以中文显示提示信息,equals则通过判断书名和日期来确定两本书是不是同一本
2.书店此时正在打折,所有书打八折,但是要收取0.1元的发票费,写一个能够计算折扣后价格的getDiscount方法,如果打八折出现两以上位小数,则对第二位及以后的小数进行四舍五入(提示:回想我们之前提到的小数运算可能产生的问题)
3.三参的构造方法
4.所有成员属性的get和set方法
class Book{
private String name;
private int price;
private Date date;
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
Book(String name, int price, Date date){
this.name = name;
this.price = price;
this.date = date;
}
@Override
public String toString(){
return "[书名:"+name+",价格:"+price+",出版日期:"+simpleDateFormat.format(date)+"]";
}
@Override
public boolean equals(Object obj) {
Book book1 = (Book)obj;
if(this.name.isEmpty() || book1.getName().isEmpty())
return false;
return this.name.equals(book1.getName()) && this.price == book1.getPrice();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
}
用类集存储多个Book对象的ELibrary类
创建一个ELibrary类,在ELibrary类中使用类集存储Book对象(可自由选择合适的类集)
在ELibrary类中添加对图书信息进行增删改查的方法,要求查询所有图书有价格增序,价格降序,日期降序三种方法
并且创建一个mainInterface方法来作为服务器后端,效果要求如图所示
此题答案和下一题一起给出
给ELibrary类添加I/O操作
给ELibrary类添加I/O操作,即在服务器开启时读取本地数据获得图书信息,在服务器关闭时将图书信息保存为本地文件
import java.io.*;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
public class StLibrary {
public static void main(String[] args) {
File file = new File("library record.txt");//相对路径
try {
file.createNewFile();//创建本地文件
ELibrary el = new ELibrary();
} catch (IOException e){
System.out.println("IO Exception founded");
System.exit(-2);
}
}
}
class ELibrary{
File file = new File("library record.txt");
FileReader fr = new FileReader(file);
Scanner scanner = new Scanner(System.in);
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
Set<Book> book= new HashSet<>();//使用hashSet类集存储数据
ELibrary() throws IOException {
file.createNewFile();
StringBuilder bookInfo = new StringBuilder();
while(true){
int a = fr.read();
bookInfo.append((char) (a));
if(a == ']') {
int b = bookInfo.indexOf(":");
int c = bookInfo.indexOf(",");
String name = bookInfo.substring(b+1,c);
b = bookInfo.substring(b+1).indexOf(":") + b+1;
c = bookInfo.substring(c+1).indexOf(",") + c+1;
int price = Integer.parseInt(bookInfo.substring(b+1,c));
b = bookInfo.substring(b+1).indexOf(":") + b+1;
c = bookInfo.substring(c+1).indexOf("]") + c+1;
Date date = this.parseExceptionHandle(bookInfo.substring(b+1,c));
bookInfo = new StringBuilder();
Book book1 = new Book(name, price, date);
//以上为我自定的方法,逻辑比较简单
book.add(book1);//将book1对象作为一个元素添加到book这个hashSet中
}
if(a == -1)
break;//读取结束
}
System.out.println("=====欢迎使用E图书馆=====");
System.out.println("请输入您的权限码");
if(scanner.next().equals("qazwsx"))
this.mainInterface();
else
System.out.println("抱歉,您没有访问资格");
}
void mainInterface() throws IOException {
System.out.println("请选择操作:1-新增图书 2-修改图书 3-删除图书 4-查找图书 5-查看所有图书 6-退出");
int userChoice = this.intInputException();
if (userChoice == 1)
this.add();
else if (userChoice == 2) {
System.out.println("请输入要修改图书名称");
String str1 = scanner.next();
Book book1 = this.findByName(str1);
this.alter(book1);
} else if (userChoice == 3) {
System.out.println("请输入要删除图书名称");
String str1 = scanner.next();
Book book1 = this.findByName(str1);
this.delete(book1);
} else if (userChoice == 4) {
System.out.println("请输入要查找图书名称");
String str1 = scanner.next();
Book book1 = this.findByName(str1);
if(book1 != null)
System.out.println("为您查找到"+book1);
} else if (userChoice == 5) {
System.out.println("请选择查看顺序:1-价格降序 2-价格增序 3-日期降序");
userChoice = this.intInputException();
if (userChoice == 1)
this.sortByPriceDESC();
else if (userChoice == 2)
this.sortByPriceASC();
else if (userChoice == 3)
this.sortByDate();
} else if (userChoice == 6) {
FileWriter fw = new FileWriter(file);
fw.write("藏书信息如下\n");
for (Book book1: book) {
fw.write(book1.toString()+"\n");
}
fw.write("最后更新于:" + simpleDateFormat.format(new Date()));
fw.close();
fr.close();
System.out.println("感谢使用E图书馆");
System.exit(0);
}else
System.out.println("Invalid input");
this.mainInterface();
}
void add(){
System.out.println("请输入图书名称");
String str1 = scanner.next();
System.out.println("请输入图书价格");
int price = this.intInputException();
System.out.println("请输入图书出版时间,使用-连接,如2008-12-06");
String time = scanner.next();
Date date = this.parseExceptionHandle(time);
Book book1 = new Book(str1, price, date);
book.add(book1);
}
void alter(Book book1){
this.delete(book1);
this.add();
}
void delete(Book book1){
for (Book book2 : book) {
if (book2!=null && book2.getName().equals(book1.getName())) {
book.remove(book2);
return;
}
}
System.out.println("图书未找到");
}
Book findByName(String str){
for (Book book1 : book) {
if (book1.getName().contains(str))
return book1;
}
System.out.println("图书未找到");
return null;
}
void sortByPriceDESC(){
Book[] books = book.toArray(new Book[] {});
for (int i = 0; i < books.length; i++){
for (int j = 0; j < i; j++){
if (books[j].getPrice() < books[i].getPrice()){
books[i].setPrice(books[j].getPrice() - books[i].getPrice());
books[j].setPrice(books[j].getPrice() - books[i].getPrice());
books[i].setPrice(books[i].getPrice() + books[j].getPrice());
//此为将books数组排序
}
}
}
for (Book value : books) {
System.out.println(value);
}
}
void sortByPriceASC(){
Book[] books = book.toArray(new Book[] {});
for (int i = 0; i < books.length; i++){
for (int j = 0; j < i; j++){
if (books[j].getPrice() < books[i].getPrice()){
books[i].setPrice(books[j].getPrice() - books[i].getPrice());
books[j].setPrice(books[j].getPrice() - books[i].getPrice());
books[i].setPrice(books[i].getPrice() + books[j].getPrice());
}
}
}
for (int x = books.length; x > 0; x--) {
System.out.println(books[x-1]);
}
}
void sortByDate(){
Book[] books = book.toArray(new Book[] {});
for (int i = 0; i < books.length; i++){
for (int j = 0; j < i; j++){
if (books[j].getDate().getTime() < books[i].getDate().getTime()){
books[i].setDate(new Date(books[j].getDate().getTime() - books[i].getDate().getTime()));
books[j].setDate(new Date(books[j].getDate().getTime() - books[i].getDate().getTime()));
books[i].setDate(new Date(books[i].getDate().getTime() + books[j].getDate().getTime()));
}
}
}
for (Book value : books) {
System.out.println(value);
}
}
int intInputException(){
//专门定义处理异常的类,方便整理代码
int userChoice = -1;
try {
userChoice = Integer.parseInt(scanner.next());
} catch (NumberFormatException e){
System.out.println("Please input an integer");
this.intInputException();
}
return userChoice;
}
Date parseExceptionHandle(String time){
Date date = null;
try {
date = simpleDateFormat.parse(time);
} catch (ParseException e) {
System.out.println("Please follow the required structure");
this.parseExceptionHandle(scanner.next());
}
return date;
}
}
让ELibrary类支持服务器和多线程操作
1.让ELibrary类支持服务器操作,即可以通过ELibraryClient类访问ELibrary服务器,对书籍信息进行增删改差
2.让ELibrary类支持服务器操作的同时支持多线程操作,即可以通过多个ELibraryClient类访问ELibrary服务器
服务器端代码:
package Network;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
public class LibraryServer {
public static void main(String[] args) {
File file = new File("library record.txt");
try {
file.createNewFile();
ServerSocket ss = new ServerSocket(8000);
System.out.println("Server started");
while (true) {
Socket socket = ss.accept();
System.out.println("A client has connected");
new Thread(new Runnable() {
@Override
public void run() {
try {
ELibrary eLibrary = new ELibrary(socket);
} catch (IOException e) {
System.out.println("A client disconnected");
}
}
}).start();
}
} catch (IOException e) {
//e.printStackTrace();
System.out.println("IO Exception founded");
}
}
}
class ELibrary{
File file = new File("library record.txt");
FileReader fr = new FileReader(file);
OutputStream os;
PrintStream ps;
InputStream is;
BufferedReader br;
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
Set<Book> book= new HashSet<>();
ELibrary(Socket socket) throws IOException {
os = socket.getOutputStream();
ps = new PrintStream(os);
is = socket.getInputStream();
br = new BufferedReader(new InputStreamReader(is));
//从此处开始,后面的代码其实区别不大,只是将输出的System.out.println全部改成了 ps.println,输入的语句改为了br.readLine
StringBuilder bookInfo = new StringBuilder();
while(true){
int a = fr.read();
bookInfo.append((char) (a));
if(a == ']') {
int b = bookInfo.indexOf(":");
int c = bookInfo.indexOf(",");
String name = bookInfo.substring(b+1,c);
b = bookInfo.substring(b+1).indexOf(":") + b+1;
c = bookInfo.substring(c+1).indexOf(",") + c+1;
int price = Integer.parseInt(bookInfo.substring(b+1,c));
b = bookInfo.substring(b+1).indexOf(":") + b+1;
c = bookInfo.substring(c+1).indexOf("]") + c+1;
Date date = this.parseExceptionHandle(bookInfo.substring(b+1,c));
bookInfo = new StringBuilder();
Book book1 = new Book(name, price, date);
book.add(book1);
}
if(a == -1)
break;
}
ps.println("1=====欢迎使用E图书馆=====");
ps.println("2请输入您的权限码");
if(br.readLine().equals("qazwsx"))
this.mainInterface();
else
ps.println("1抱歉,您没有访问资格");
}
void mainInterface() throws IOException {
ps.println("2请选择操作:1-新增图书 2-修改图书 3-删除图书 4-查找图书 5-查看所有图书 6-退出");
int userChoice = this.intInputException();
if (userChoice == 1)
this.add();
else if (userChoice == 2) {
ps.println("2请输入要修改图书名称");
String str1 = br.readLine();
Book book1 = this.findByName(str1);
this.alter(book1);
} else if (userChoice == 3) {
ps.println("2请输入要删除图书名称");
String str1 = br.readLine();
Book book1 = this.findByName(str1);
this.delete(book1);
} else if (userChoice == 4) {
ps.println("2请输入要查找图书名称");
String str1 = br.readLine();
Book book1 = this.findByName(str1);
if(book1 != null)
ps.println("1为您查找到"+book1);
} else if (userChoice == 5) {
ps.println("2请选择查看顺序:1-价格降序 2-价格增序 3-日期降序");
userChoice = this.intInputException();
if (userChoice == 1)
this.sortByPriceDESC();
else if (userChoice == 2)
this.sortByPriceASC();
else if (userChoice == 3)
this.sortByDate();
} else if (userChoice == 6) {
FileWriter fw = new FileWriter(file);
fw.write("藏书信息如下\n");
for (Book book1: book) {
fw.write(book1.toString()+"\n");
}
fw.write("最后更新于:" + simpleDateFormat.format(new Date()));
fw.close();
fr.close();
ps.println("3感谢使用E图书馆");
}else
ps.println("1Invalid input");
this.mainInterface();
}
void add() throws IOException {
ps.println("2请输入图书名称");
String str1 = br.readLine();
ps.println("2请输入图书价格");
int price = this.intInputException();
ps.println("2请输入图书出版时间,使用-连接,如2008-12-06");
String time = br.readLine();
Date date = this.parseExceptionHandle(time);
Book book1 = new Book(str1, price, date);
book.add(book1);
}
void alter(Book book1) throws IOException {
this.delete(book1);
this.add();
}
void delete(Book book1){
for (Book book2 : book) {
if (book1 != null && book2!=null && book2.getName().equals(book1.getName())) {
book.remove(book2);
return;
}
}
ps.println("1图书未找到");
}
Book findByName(String str){
for (Book book1 : book) {
if (book1.getName().contains(str))
return book1;
}
ps.println("1图书未找到");
return null;
}
void sortByPriceDESC(){
Book[] books = book.toArray(new Book[] {});
for (int i = 0; i < books.length; i++){
for (int j = 0; j < i; j++){
if (books[j].getPrice() < books[i].getPrice()){
books[i].setPrice(books[j].getPrice() - books[i].getPrice());
books[j].setPrice(books[j].getPrice() - books[i].getPrice());
books[i].setPrice(books[i].getPrice() + books[j].getPrice());
}
}
}
for (Book value : books) {
ps.println("1"+value);
}
}
void sortByPriceASC(){
Book[] books = book.toArray(new Book[] {});
for (int i = 0; i < books.length; i++){
for (int j = 0; j < i; j++){
if (books[j].getPrice() < books[i].getPrice()){
books[i].setPrice(books[j].getPrice() - books[i].getPrice());
books[j].setPrice(books[j].getPrice() - books[i].getPrice());
books[i].setPrice(books[i].getPrice() + books[j].getPrice());
}
}
}
for (int x = books.length; x > 0; x--) {
ps.println("1" + books[x-1]);
}
}
void sortByDate(){
Book[] books = book.toArray(new Book[] {});
for (int i = 0; i < books.length; i++){
for (int j = 0; j < i; j++){
if (books[j].getDate().getTime() < books[i].getDate().getTime()){
books[i].setDate(new Date(books[j].getDate().getTime() - books[i].getDate().getTime()));
books[j].setDate(new Date(books[j].getDate().getTime() - books[i].getDate().getTime()));
books[i].setDate(new Date(books[i].getDate().getTime() + books[j].getDate().getTime()));
}
}
}
for (Book value : books) {
ps.println("1" +value);
}
}
int intInputException() throws IOException {
int userChoice = -1;
while (userChoice == -1) {
try {
userChoice = Integer.parseInt(br.readLine());
} catch (NumberFormatException e){
System.out.println("2Please input an integer");
}
}
return userChoice;
}
Date parseExceptionHandle(String time) throws IOException {
Date date = null;
try {
date = simpleDateFormat.parse(time);
} catch (ParseException e) {
ps.println("2Please follow the required structure");
this.parseExceptionHandle(br.readLine());
}
return date;
}
}
客户端代码:
import java.io.*;
import java.net.Socket;
import java.util.Scanner;
public class LibraryClient {
public static void main(String[] args) {
try {
Socket socket = new Socket("127.0.0.1",8000);
OutputStream os = socket.getOutputStream();
PrintStream ps = new PrintStream(os);
InputStream is = socket.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
Scanner scanner = new Scanner(System.in);
int instructor = br.read();
while (instructor != 51){//当读取的数字不为3
instructor = br.read();
if (instructor == 49){//当读取的数字为2,直接读下一行
String text = br.readLine();
System.out.println(text);
} else if (instructor == 50){//当读取的数字为1,要求输入一个数
String text = br.readLine();
System.out.println(text);
ps.println(scanner.next());
}
}
} catch (IOException e) {
e.printStackTrace();
System.out.println("IO Exception founded");
}
}
}
附加题:将ELibrary类中的Book信息存储为XML和JSON形式
在服务器关闭时将图书信息保存为本地文件,但是将保存的文件转化为XML形式,以及JSON形式
此题难度较低,答案就不给出了