作业总结
第四次作业总结
1.前言
本次作业是在作业3的基础上增加了多余的功能,包括菜单中的特色菜,以及菜谱信息与订单信息混合,应忽略夹在订单信息中的菜谱信息。输出:"invalid dish"
桌号所带时间格式合法(格式见输入格式部分说明,其中年必须是4位数字,月、日、时、分、秒可以是1位或2位数),数据非法,比如:2023/15/16 ,输出桌号+" date error"
重复删除,重复的删除记录输出"deduplication :"+序号。
2.设计与分析
1.分析
该菜单系列是在前一次的基础上增加了新的功能,同时也完善了错误输入的提示,同时本次作业加入了时间格式的合法性的判断
对于折扣以及营业时间需要进行判断,判断是否在营业的时间以及不同时间段的不同折扣
对于特色菜的输入格式需要进行保存还需修改最后输出的格式
2.设计
使用text中SimpleDateFormat来自定义输入日期的格式,dateTime.getDay() 获取星期几(0表示周日,1表示周一,2表示周二,以此类推)
使用HashMap来保存table的数据,通过equals()来判断输入
3.采坑心得
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
public class Main {
static SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH/mm/ss");
static DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/M/d");
static LocalDate startDate = LocalDate.parse("2022/1/1", formatter);
static LocalDate endDate = LocalDate.parse("2023/12/31", formatter);
static String p1 = "^\\S+\\s+\\d+"; //menu
static String p2 = "^table\\s+\\d+\\s+\\d{4}/\\d{1,2}/\\d{1,2}\\s+\\d{1,2}/\\d{1,2}/\\d{1,2}";
static String p3 = "^\\d+\\s+\\S+\\s+\\d+\\s+\\d+";
static String p4 = "^\\d+\\s+delete";
static String p5 = "^\\d+\\s+\\d+\\s+\\S+\\s+\\d+\\s+\\d+";
static String p6 = "^\\S+\\s+\\d+\\s+T";// 油淋生菜 9 T
public static int inputType(String s) {
if (Pattern.matches(p1, s) && !s.contains(".")) return 1;
if (Pattern.matches(p2, s)) return 2;
if (Pattern.matches(p3, s)) return 3;
if (Pattern.matches(p4, s)) return 4;
if (Pattern.matches(p5, s)) return 5;
if (Pattern.matches(p6, s)) return 6;
return 0;
}
public static float checkTime(String dateTimeStr) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH/mm/ss");
try {
Date dateTime = sdf.parse(dateTimeStr);
int weekDay = dateTime.getDay(); // 获取星期几(0表示周日,1表示周一,2表示周二,以此类推)
if (weekDay >= 1 && weekDay <= 5) { // 周一至周五
Date startTime1 = sdf.parse(dateTimeStr.split(" ")[0] + " 10/30/00"); // 起始时间(10:30)
Date endTime1 = sdf.parse(dateTimeStr.split(" ")[0] + " 14/30/00"); // 结束时间(14:30)
Date startTime2 = sdf.parse(dateTimeStr.split(" ")[0] + " 17/00/00"); // 起始时间(17:00)
Date endTime2 = sdf.parse(dateTimeStr.split(" ")[0] + " 20/30/00"); // 结束时间(20:30)
if ((dateTime.after(startTime1) || dateTime.equals(startTime1)) &&
(dateTime.before(endTime1) || dateTime.equals(endTime1))) { // 在10:30~14:30之间
return 0.6f;
} else if ((dateTime.after(startTime2) || dateTime.equals(startTime2)) &&
(dateTime.before(endTime2) || dateTime.equals(endTime2))) { // 在17:00~20:30之间
return 0.8f;
}
} else if (weekDay == 6 || weekDay == 0) { // 周六和周日
Date startTime = sdf.parse(dateTimeStr.split(" ")[0] + " 09/30/00"); // 起始时间(17:00)
Date endTime = sdf.parse(dateTimeStr.split(" ")[0] + " 21/30/00"); // 结束时间(20:30)
if ((dateTime.after(startTime) || dateTime.equals(startTime)) &&
(dateTime.before(endTime) || dateTime.equals(endTime))) {
return 1.0f;
}
}
} catch (ParseException e) {
e.printStackTrace();
}
return 0.0f; // 其它时间返回0.0
}
public static void main(String[] args) {
sdf.setLenient(false);
Boolean ifMenu = true;
Boolean ifTable = false;
Scanner sc = new Scanner(System.in);
Menu menu = new Menu();
Calendar cal = Calendar.getInstance();
int oFlag = 1;
List<Table> tableList = new ArrayList<>();
int tcd = 0;
Table table = null;
while (true) {
String ipt = sc.nextLine();
if (ipt.equals("end")) break;
int type = inputType(ipt);
if (type == 0) {
if (ipt.contains("a") && !ifTable) {
System.out.println("wrong format");
break;
}
System.out.println("wrong format");
if (ifTable || ifMenu) {
continue;
}
}
String[] s = ipt.split(" ");
if (type == 4 && ifTable) {
//7 delete
int i = Integer.parseInt(s[0]);
if (!table.checkIfDelete(i)) {
System.out.println("deduplication " + i);
continue;
} else {
if (table.del(i) || table.otherMap.remove(i) != null) {
continue;
}
System.out.println("delete error;");
}
} else if (type == 2) {
ifMenu = false;
//table 2 2022/12/3 15/03/02
tcd = Integer.parseInt(s[1]);
try {
String s1 = s[2] + " " + s[3];
sdf.parse(s1);
} catch (Exception e) {
System.out.println(tcd + " date error");
continue;
}
LocalDate date = LocalDate.parse(s[2], formatter);
if (!((date.isAfter(startDate) || date.isEqual(startDate)) && (date.isBefore(endDate) || date.isEqual(endDate)))) {
System.out.println("not a valid time period");
continue;
}
if (tcd > 55 || tcd < 1) {
System.out.println(tcd + " table num out of range");
continue;
}
if (s[1].charAt(0) == '0') {
System.out.println("wrong format");
continue;
}
boolean ifExist = false;
if (checkTime(s[2] + " " + s[3]) == 0) {
System.out.println("table " + tcd + " out of opening hours");
continue;
}
table = new Table(tcd, s[2] + " " + s[3]);
tableList.add(table);
ifTable = true;
oFlag = 1;
System.out.println("table " + tcd + ": ");
} else if (type == 3 && ifTable) {
//1 麻婆豆腐 2 2
if (s[0].charAt(0) == '0') {
System.out.println("wrong format");
oFlag++;
continue;
}
Dish dish = menu.find(s[1]);
if (dish == null) {
oFlag++;
System.out.println(s[1] + " does not exist");
} else {
int no = Integer.parseInt(s[0]);
int n = Integer.parseInt(s[3]);
int p = Integer.parseInt(s[2]);
if (n < 0 || n > 15) {
oFlag++;
System.out.println(no + " num out of range " + n);
continue;
}
if (p > 3 || p < 1) {
oFlag++;
System.out.println(no + " portion out of range " + p);
continue;
}
if (no != oFlag) {
// oFlag++;
System.out.println("record serial number sequence error");
continue;
}
oFlag++;
Record record = new Record(dish, n, Integer.parseInt(s[2]));
table.add(record, no);
System.out.println(no + " " + dish.name + " " + record.price);
}
} else if (type == 1) {
if (ifMenu) {
//麻婆豆腐 12
menu.add(s[0], Integer.parseInt(s[1]), false);
} else {
System.out.println("invalid dish");
}
} else if (type == 6) {
if (ifMenu) {
//麻婆豆腐 12 T
if (s[1].charAt(0) == '0') {
System.out.println("wrong format");
continue;
}
int price = Integer.parseInt(s[1]);
if (price < 0 || price > 300) {
System.out.println(s[0] + " price out of range " + price);
continue;
}
menu.add(s[0], price, true);
} else {
System.out.println("invalid dish");
}
} else if (s.length == 5 && ifTable) {
//1 4 麻婆豆腐 1 1
Dish dish = menu.find(s[2]);
if (dish == null) {
System.out.println(s[2] + " does not exist");
} else {
int tableNo = Integer.parseInt(s[0]);
int ordern = Integer.parseInt(s[1]);
int gg = Integer.parseInt(s[3]);
int fs = Integer.parseInt(s[4]);
Record rec = new Record(dish, fs, gg);
table.otherMap.put(ordern, rec.price);
System.out.println(ordern + " table " + tcd + " pay for table " + tableNo + " " + rec.price);
}
}
}
Map<Integer, List<Table>> map = tableList.stream().collect(Collectors.groupingBy(Table::gettNo));
for (List<Table> value : map.values()) {
if (value.size() == 1) {
Table t = value.get(0);
getOneInfo(t);
} else if (value.size() == 2) {
Table t1 = value.get(0);
Table t2 = value.get(1);
if (t1.date.split(" ")[0].equals(t2.date.split(" ")[0])) {
float v = checkTime(t1.date);
if (v == 0.0f) {
System.out.println("table " + t1.tNo + " out of opening hours");
} else if (v == 1.0f) {
System.out.println("table " + t1.tNo + ": " + t1.all() + t2.all() + " " + t1.all() + t2.all());
} else {
System.out.println("table " + t1.tNo + ": " + t1.all() + t2.all() + " " + t1.all(true, v) + t2.all(true, v));
}
} else {
getOneInfo(t1);
getOneInfo(t2);
}
}
}
for (Table t : tableList) {
if (t == null) continue;
}
}
private static void getOneInfo(Table t) {
float v = checkTime(t.date);
if (v == 0.0f) {
System.out.println("table " + t.tNo + " out of opening hours");
} else if (v == 1.0f) {
System.out.println("table " + t.tNo + ": " + t.all() + " " + t.all());
} else {
System.out.println("table " + t.tNo + ": " + t.all() + " " + t.all(true, v));
}
}
}
class Dish {
String name;
int price;
boolean ifT;
public Dish(String name, int price, boolean ifT) {
this.name = name;
this.price = price;
this.ifT = ifT;
}
}
class Menu {
int count = 0;
Dish[] dishes = new Dish[60];
public void add(String name, int price, boolean ifT) {
dishes[count] = new Dish(name, price, ifT);
count++;
}
public Dish find(String name) {
Dish r = null;
for (int i = 0; i < dishes.length; i++) {
if (dishes[i] != null && dishes[i].name.equals(name)) {
r = dishes[i];
}
}
return r;
}
}
class Record {
Dish dish;
int price;
boolean ifT;
int gg;
int fs;
public void setPrice() {
if (gg == 1) {
price = dish.price * fs;
} else if (gg == 2) {
price = Math.round((float) dish.price * 1.5f) * fs;
} else if (gg == 3) {
price = dish.price * 2 * fs;
}
}
public Record(Dish dish, int fs, int gg) {
this.dish = dish;
this.gg = gg;
this.fs = fs;
this.ifT = dish.ifT;
setPrice();
}
public void addFs(int fs) {
this.fs += fs;
setPrice();
}
}
class Table {
int tNo;
Record[] records = new Record[100];
HashMap<Integer, Integer> deleteNo = new HashMap<>();
String date;
Map<Integer, Integer> otherMap = new HashMap<>();
public Table(int tNo, String date) {
this.tNo = tNo;
this.date = date;
}
public void add(Record record, int no) {
records[no] = record;
}
public int gettNo() {
return tNo;
}
public boolean del(int no) {
if (records[no] == null) {
return false;
} else {
records[no] = null;
return true;
}
}
public int all(boolean dazhe, float xishu) {
int sum = 0;
for (Record record : records) {
if (record == null) continue;
if (dazhe) {
if (record.ifT) {
sum += Math.round((float) record.price * 0.7);
} else {
sum += Math.round((float) record.price * xishu);
}
} else {
sum += record.price;
}
}
for (Integer value : otherMap.values()) {
sum += value;
}
return sum;
}
public int all() {
int sum = 0;
for (Record record : records) {
if (record == null) continue;
sum += record.price;
}
for (Integer value : otherMap.values()) {
sum += value;
}
return sum;
}
boolean checkIfDelete(Integer no) {
if (deleteNo.get(no) == null) {
deleteNo.put(no, no);
return true;
}
return false;
}
}
设置桌号多于字符错误的判断的设置没有多于判断,菜谱信息也出现了错误。
在重复的桌号中没有考虑到不在营业时间,不同时间段,在同一时间段这几种情况所出现的问题。
在多个的桌号中没有考虑到一个桌号时间错误,一个桌号格式错误,一个桌号超出范围,一个桌号格式非法这几种情况所出现的问题。
在代点菜中没有考虑到桌号不存在,在菜谱价格超出范围中没有考虑以及多桌菜测试,无异常记录,桌号时间超过范围,未按顺序排列的序号,以及在代点菜功能中出现的无法存入对应菜单中的问题,同时没有注意到点菜记录中包含多种错误这一问题。
4.主要困难以及改进意见
1.困难
本次作业所需要学习并且了解text库中所包含的方法和种类,同时还要求设置不同错误所包含的点,并且还需要设置时间的标准格式。
作业中所设计的混合错误以及多个桌号同时进行的功能需要进行设计,这使得需要设计一个Map来保存table中数据的存储
同时还需要设计其他的类来组合完成所添加的功能,而类与类之间的关联还需要进行进一步的设计和思考
2.改进意见
可以减少程序中静态导入滥用静态导入会使程序更难阅读,更难维护。静态导入后,代码中就不用再写类名了,但是我们知道类是“一类事物的描述”,缺少了类名的修饰,静态属性和静态方法的表象意义可以被无限放大,这会让阅读者很难弄清楚所谓何意。
避免在构造函数中初始化其他类更符合面向对象编程类与类关系复杂,容易造成栈溢出
第五次作业总结
1.前言
本次作业依旧是在第三次作业的基础上添加了新的功能,本次作业需要对于第三次作业有一定的理解才能进行和完成
本次作业是作业三的另一个迭代分支,本次作业增加了菜的口味度,以及菜的口味类型,例如川菜,晋菜,浙菜
不同菜品类型具有不同菜品的口味度例如辣度,甜度以及酸度
点菜中增加了用户的手机号等多的存储
2.设计与分析
1.分析
本次作业可以使用继承的方法实现对于特色菜种类的继承,继承的方法可以使程序更加简洁并且继承的方法进行重写后可以覆盖和完善所需要的功能
作业中可以使用Map来储存用户的数据,因为用户点菜中用户的信息包含用户的电话号以及用户的姓名,Map与String相比Map可以连续并且可以在储存中插入不同的数据,Map更加方便相对于本次作业。
同时还需要控制判断用户手机号的前几位数字,以及设置用户姓名的字符长度。
作业中主要增加的功能是菜单中增加的特色菜功能,以及用户所需保存的数据。其中特色菜所包括的不同菜品拥有不同的口味度等级,并且口味度等级还与菜品类型相关,不同的菜品类型所对应的口味度有不同的划分。
2.设计
本次作业需要使用继承的方法进行设计,尤其是对于特色菜的方法,特色菜需要设计一个继承的父类,所以可以设计一个抽象类来进行继承
同时使用Map函数来储存菜单中的菜品,包括其中的特色菜种类,以及菜品的价格。
使用text中SimpleDateFormat来自定义输入日期的格式,dateTime.getDay() 获取星期几(0表示周日,1表示周一,2表示周二,以此类推)
使用text库中的ParseException,SimpleDateFormat来设计测算时间的准确性以及时间格式的对错
3.采坑心得
import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.*; public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); Map<String, Meal> menu = new HashMap<>(); Map<Integer, Table> tables = new HashMap<>(); Table localTable = null; while (true) { String input = scanner.nextLine(); String[] inputs = input.split(" "); if (input.matches("end")) { break; } else if (input.matches("\\S+\\s\\d+")) { // * 油淋生菜 9 Meal m = new Meal(); m.name = inputs[0]; m.price = Integer.parseInt(inputs[1]); menu.put(m.name, m); } else if (input.matches("\\S+\\s\\S+\\s\\d+\\sT")) { // * 麻婆豆腐 川菜 12 T Meal m = null; if (inputs[1].equals("川菜")) { m = new ChuanMeal(); } else if (inputs[1].equals("晋菜")) { m = new JinMeal(); } else if (inputs[1].equals("浙菜")) { m = new ZheMeal(); } m.name = inputs[0]; m.price = Integer.parseInt(inputs[2]); menu.put(m.name, m); } else if (input.matches("table\\s\\d+\\s:\\s\\S+\\s\\d+\\s\\d+/\\d+/\\d+\\s\\d+/\\d+/\\d+")) { // * table 1 : tom 13605054400 2023/5/1 21/30/00 int no = Integer.parseInt(inputs[1]); String customer = inputs[3]; String phone = inputs[4]; String time = inputs[5] + " " + inputs[6]; SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd HH/mm/ss"); simpleDateFormat.setLenient(false); try { Table table = new Table(); Date date = simpleDateFormat.parse(time); Calendar calendar = Calendar.getInstance(); calendar.setTime(date); int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK); if (dayOfWeek == 1 || dayOfWeek == 7) { Date start = simpleDateFormat.parse(inputs[5] + " 9/30/00"); Date end = simpleDateFormat.parse(inputs[5] + " 21/30/00"); if ((date.after(start) && date.before(end)) || date.equals(start) || date.equals(end)) { table.weekend = true; table.discount = 1.0F; } else { System.out.println("table " + no + " out of opening hours"); continue; } } else { Date AmStart = simpleDateFormat.parse(inputs[5] + " 10/30/00"); Date AmEnd = simpleDateFormat.parse(inputs[5] + " 14/30/00"); Date PmStart = simpleDateFormat.parse(inputs[5] + " 17/00/00"); Date PmEnd = simpleDateFormat.parse(inputs[5] + " 20/30/00"); if ((date.after(AmStart) && date.before(AmEnd)) || date.equals(AmStart) || date.equals(AmEnd)) { table.discount = 0.6F; } else if ((date.after(PmStart) && date.before(PmEnd)) || date.equals(PmStart) || date.equals(PmEnd)) { table.discount = 0.8F; } else { System.out.println("table " + no + " out of opening hours"); continue; } } localTable = table; } catch (ParseException ignored) { } localTable.no = no; localTable.customer = customer; localTable.phone = phone; tables.put(no, localTable); System.out.println("table " + no + ": "); } else if (input.matches("\\d+\\s\\S+\\s\\d+\\s\\d+")) { if (localTable == null) continue; // * 2 油淋生菜 2 1 Meal meal = menu.get(inputs[1]); int no = Integer.parseInt(inputs[0]); if (meal != null) { Record record = new Record(); record.meal = meal; record.size = Integer.parseInt(inputs[2]); record.number = Integer.parseInt(inputs[3]); record.T = false; localTable.records.put(no, record); System.out.println(no + " " + meal.name+" " + record.getPrice()); } } else if (input.matches("\\d+\\s\\S+\\s\\d+\\s\\d+\\s\\d+")) { // * 2 油淋生菜 2 1 3 if (localTable == null) continue; Meal meal = menu.get(inputs[1]); int no = Integer.parseInt(inputs[0]); if (meal != null) { Record record = new Record(); record.meal = meal; record.degree = Integer.parseInt(inputs[2]); record.size = Integer.parseInt(inputs[3]); record.number = Integer.parseInt(inputs[4]); record.T = true; localTable.records.put(no, record); System.out.println(no + " " + meal.name+" " + record.getPrice()); } } else if (input.matches("\\d+\\s\\d+\\s\\S+\\s\\d+\\s\\d+")) { // * 1 2 油淋生菜 2 1 if (localTable == null) continue; Meal meal = menu.get(inputs[2]); int no = Integer.parseInt(inputs[1]); if (meal != null) { //TODO 判断是否合法的输入 //初始化单条点菜记录 Record record = new Record(); record.meal = meal; record.size = Integer.parseInt(inputs[3]); record.number = Integer.parseInt(inputs[4]); record.T = false; //将点菜记录放入当前桌子的点菜信息里 localTable.records.put(no, record); System.out.println(no + " " + meal.name+" " + record.getPrice()); } } else if (input.matches("\\d+\\s\\d+\\s\\S+\\s\\d+\\s\\d+\\s\\d+")) { // * 2 2 油淋生菜 2 1 3 if (localTable == null) continue; Meal meal = menu.get(inputs[2]); int no = Integer.parseInt(inputs[1]); if (meal != null) { //TODO 判断是否合法的输入 //初始化单条点菜记录 Record record = new Record(); record.meal = meal; record.degree = Integer.parseInt(inputs[3]); record.size = Integer.parseInt(inputs[4]); record.number = Integer.parseInt(inputs[5]); record.T = true; //将点菜记录放入当前桌子的点菜信息里 localTable.records.put(no, record); System.out.println(no + " " + meal.name+" " + record.getPrice()); } } else if (input.matches("\\d+\\sdelete")) { // * 2 delete if (localTable == null) continue; int no = Integer.parseInt(inputs[0]); localTable.records.remove(no); } else { System.out.println("wrong format"); } } //key 客户名字+' '+客户号码 value 应付金额 TreeMap<String, Integer> customerPrice = new TreeMap<>(); for (Table table : tables.values()) { System.out.println("table " + table.no + ": " + table.beforeDiscountPrice() + " " + localTable.afterDiscountPrice() + table.StatisticsT()); if (customerPrice.get(table.customer + " " + table.phone) == null) { customerPrice.put(table.customer + " " + table.phone, table.afterDiscountPrice()); } else { int v = customerPrice.get(table.customer + " " + table.phone); v += table.afterDiscountPrice(); customerPrice.put(table.customer + " " + table.phone, v); } } //Entry 键值对 for (Map.Entry<String, Integer> value : customerPrice.entrySet()) { { System.out.println(value.getKey() + " " + value.getValue()); } } } } class Table { String customer; String phone; int no; float discount; boolean weekend = false; Map<Integer, Record> records = new HashMap<>(); int beforeDiscountPrice() { int sum = 0; for (Record record : records.values()) { sum += record.getPrice(); } return sum; } int afterDiscountPrice() { int sum = 0; for (Record record : records.values()) { if (weekend) { sum += record.getPrice(); } else if (record.T) { sum += Math.round( record.getPrice() * 0.7F); } else { sum += Math.round( record.getPrice() * discount); } } return sum; } String StatisticsT() { String result = ""; String[] la = {"不辣", "微辣", "稍辣", "辣", "很辣", "爆辣"}; String[] suan = {"不酸", "微酸", "稍酸", "酸", "很酸"}; String[] tian = {"不甜", "微甜", "稍甜", "甜"}; int allLaDegree = 0, allSuanDegree = 0, allTianDegree = 0; int laSum = 0, suanSum = 0, tianSum = 0; for (Record record : records.values()) { if (record.T) { if (record.meal instanceof ChuanMeal) { allLaDegree += record.degree*record.number; laSum += record.number; } else if (record.meal instanceof JinMeal) { allSuanDegree += record.degree*record.number; suanSum += record.number; } else if (record.meal instanceof ZheMeal) { allTianDegree += record.degree*record.number; tianSum += record.number; } } } if (laSum != 0) { int avg = Math.round((float) allLaDegree / (float) laSum); result += " 川菜 " + laSum + " " + la[avg]; } if (suanSum != 0) { int avg = Math.round((float) allSuanDegree / (float) suanSum); result += " 晋菜 " + suanSum + " " + suan[avg]; } if (tianSum != 0) { int avg = Math.round((float) allTianDegree / (float) tianSum); result += " 浙菜 " + tianSum + " " + tian[avg]; } return result; } } class Record { Meal meal; boolean T; int number; int size; int degree; public int getPrice() { if (size == 1) { return meal.price * number; } else if (size == 2) { return (int) (Math.round((float) meal.price * 1.5) * number); } else if (size == 3) { return meal.price * number * 2; } return 0; } } interface CheckDegree { boolean check(); } class Meal implements CheckDegree { int price; String name; @Override public boolean check() { return true; } } class ChuanMeal extends Meal { @Override public boolean check() { return super.check(); } } class JinMeal extends Meal { @Override public boolean check() { return super.check(); } } class ZheMeal extends Meal { @Override public boolean check() { return super.check(); } }
设计时继承的类所具备的方法没有考虑清楚,同时继承时子类所重写的方法没有判断具体的程度
增加的类与类之间的关系没有整理清楚,同时对于类与类之间的关联性也没有准确的认知,对于组合和聚合之间的不同没有理解。
组合之间的关联性是强于聚合的,同时组合中的部分是无法分割出去使用,而聚合的部分是可以使用的,同时组合的生命周期是强于聚合的。
currenHaseMap注意 key和value的null值
没有进行程序的测试,同时没有考虑程序运行时可能出现的错误,以及出现错误后导致的其他功能的瘫痪
4.主要困难以及改进意见
1.困难
补充类时没有及时考虑到几个类之间包含的关系导致无法进行程序的基础设计
类与类之间的关联性没有具体设置和规划导致在程序设计后面出现思路的中断以及后面出现功能缺失而导致的增加类的数量。、
2.改进意见
没有进行程序的测试,同时没有考虑程序运行时可能出现的错误,以及出现错误后导致的其他功能的瘫痪
需要考虑到程序的稳定性以及类与类之间的关联,设计功能时所需要的涵盖的类
期中考试
1.前言
本次考试主要考察类的设计,以及后续所出现的接口等方法。
类的结构设计,类的继承和多态,抽i象类以及接口,考察对于类设计的思路以及后续功能的实现
2.设计与分析
1.设计
第一题对于圆类的设计包括了对于圆半径的输入以及get和set方法,还有计算圆的面积,还需设计控制圆本身半径的范围
第二题对于矩形类的设计则需要设置点类和矩形类,同时还需了解两者之间的关联,通过点与点之间的位置计算出矩形的长和宽,同时计算矩形的面积。
将第一题与第二题的类设计进行合并设计,抽象出Shape父类(抽象类),Circle及Rectangle作为子类,同时题目中给出的主函数使用
在第三题的题目基础上,重构类设计,实现列表内图形的排序功能按照图形的面积进行排序。
2.分析
在第四题的这段新代码中,增加了一个ArrayList<Shape>类型的列表,用于存储用户输入的图形对象。通过循环读取用户输入的选择,根据选择创建相应的图形对象,并将其添加到列表中。用户输入0时循环结束。
在循环结束后,通过list.sort(Comparator.naturalOrder())对列表中的图形对象进行排序。排序是根据对象的compareTo()方法来实现的。Rectangle和Circle类都实现了compareTo()方法,根据图形的面积进行比较。面积较小的图形排在前面。
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); Circle c = new Circle(); double r = c.setR(sc.nextDouble()); if(r < 0){ return; } double s = c.getR() * c.getR() * Math.PI; System.out.printf("%.2f",s); } } class Circle { private double r; public Circle() { } public Circle(double r) { this.r = r; } public double getR() { return r; } public double setR(double r) { if(r <= 0){ System.out.println("Wrong Format"); return - 1; } this.r = r; return r; } }
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); Rectangle r = new Rectangle(); Point p1 = new Point(); Point p2 = new Point(); p1.setX(sc.nextDouble()); p1.setY(sc.nextDouble()); p2.setX(sc.nextDouble()); p2.setY(sc.nextDouble()); r.setLowerRightPoint(p1); r.setTopLeftPoint(p2); System.out.printf("%.2f",r.getArea()); } } class Rectangle { private Point topLeftPoint; private Point lowerRightPoint; public Rectangle() { } public Rectangle(Point topLeftPoint, Point lowerRightPoint) { this.topLeftPoint = topLeftPoint; this.lowerRightPoint = lowerRightPoint; } public Point getTopLeftPoint() { return topLeftPoint; } public void setTopLeftPoint(Point topLeftPoint) { this.topLeftPoint = topLeftPoint; } public Point getLowerRightPoint() { return lowerRightPoint; } public void setLowerRightPoint(Point lowerRightPoint) { this.lowerRightPoint = lowerRightPoint; } public double getLength(){ return Math.abs(getLowerRightPoint().getX() - getTopLeftPoint().getX()); } public double getHeight(){ return Math.abs(getLowerRightPoint().getY() - getTopLeftPoint().getY()); } public double getArea(){ return getHeight() * getLength(); } } class Point { private double x; private double y; public Point() { } public Point(double x, double y) { this.x = x; this.y = y; } public double getX() { return x; } public void setX(double x) { this.x = x; } public double getY() { return y; } public void setY(double y) { this.y = y; } }
import java.util.Scanner; public class Main { public static void main(String[] args) { // TODO Auto-generated method stub Scanner input = new Scanner(System.in); int choice = input.nextInt(); switch(choice) { case 1://Circle double radiums = input.nextDouble(); if(radiums <= 0){ System.out.println("Wrong Format"); return; } Shape circle = new Circle(radiums); printArea(circle); break; case 2://Rectangle double x1 = input.nextDouble(); double y1 = input.nextDouble(); double x2 = input.nextDouble(); double y2 = input.nextDouble(); Point leftTopPoint = new Point(x1,y1); Point lowerRightPoint = new Point(x2,y2); Rectangle rectangle = new Rectangle(leftTopPoint,lowerRightPoint); printArea(rectangle); break; } } public static void printArea(Shape shape){ double s = 0; if(shape instanceof Rectangle){ shape = (Rectangle)shape; s = shape.getArea(); } else{ shape = (Circle)shape; s = shape.getArea(); } System.out.printf("%.2f",s); } } class Rectangle extends Shape{ private Point topLeftPoint; private Point lowerRightPoint; public Rectangle() { } public Rectangle(Point topLeftPoint, Point lowerRightPoint) { this.topLeftPoint = topLeftPoint; this.lowerRightPoint = lowerRightPoint; } public Point getTopLeftPoint() { return topLeftPoint; } public void setTopLeftPoint(Point topLeftPoint) { this.topLeftPoint = topLeftPoint; } public Point getLowerRightPoint() { return lowerRightPoint; } public void setLowerRightPoint(Point lowerRightPoint) { this.lowerRightPoint = lowerRightPoint; } public double getLength(){ return Math.abs(getLowerRightPoint().getX() - getTopLeftPoint().getX()); } public double getHeight(){ return Math.abs(getLowerRightPoint().getY() - getTopLeftPoint().getY()); } public double getArea(){ return getHeight() * getLength(); } } class Point { private double x; private double y; public Point() { } public Point(double x, double y) { this.x = x; this.y = y; } public double getX() { return x; } public void setX(double x) { this.x = x; } public double getY() { return y; } public void setY(double y) { this.y = y; } } class Circle extends Shape{ private double r; public Circle() { } public Circle(double r) { this.r = r; } public double getR() { return r; } public void setR(double r) { this.r = r; } public double getArea(){ return r * r * Math.PI; } } abstract class Shape { public Shape() { } public abstract double getArea(); }
import java.util.ArrayList; import java.util.Comparator; import java.util.Scanner; public class Main { public static void main(String[] args) { // TODO Auto-generated method stub Scanner input = new Scanner(System.in); ArrayList<Shape> list = new ArrayList<>(); int choice = input.nextInt(); while (choice != 0) { switch (choice) { case 1://Circle double radiums = input.nextDouble(); int flag = 0; Shape circle = new Circle(radiums); if(radiums <= 0){ flag = 1; } if(flag == 0){ list.add(circle); } break; case 2://Rectangle double x1 = input.nextDouble(); double y1 = input.nextDouble(); double x2 = input.nextDouble(); double y2 = input.nextDouble(); Point leftTopPoint = new Point(x1, y1); Point lowerRightPoint = new Point(x2, y2); Rectangle rectangle = new Rectangle(leftTopPoint, lowerRightPoint); list.add(rectangle); break; } choice = input.nextInt(); } list.sort(Comparator.naturalOrder());//正向排序 for (int i = 0; i < list.size(); i++) { System.out.print(String.format("%.2f", list.get(i).getArea()) + " "); } } } class Rectangle extends Shape{ private Point topLeftPoint; private Point lowerRightPoint; public Rectangle() { } public Rectangle(Point topLeftPoint, Point lowerRightPoint) { this.topLeftPoint = topLeftPoint; this.lowerRightPoint = lowerRightPoint; } public Point getTopLeftPoint() { return topLeftPoint; } public void setTopLeftPoint(Point topLeftPoint) { this.topLeftPoint = topLeftPoint; } public Point getLowerRightPoint() { return lowerRightPoint; } public void setLowerRightPoint(Point lowerRightPoint) { this.lowerRightPoint = lowerRightPoint; } public double getLength(){ return Math.abs(getLowerRightPoint().getX() - getTopLeftPoint().getX()); } public double getHeight(){ return Math.abs(getLowerRightPoint().getY() - getTopLeftPoint().getY()); } public double getArea(){ return getHeight() * getLength(); } @Override public int compareTo(Object o) { if(o instanceof Circle){ if (getArea() > ((Circle) o).getArea()) { return 1; } else { return -1; } } else{ if (getArea() > ((Rectangle) o).getArea()) { return 1; } else { return -1; } } } } class Point { private double x; private double y; public Point() { } public Point(double x, double y) { this.x = x; this.y = y; } public double getX() { return x; } public void setX(double x) { this.x = x; } public double getY() { return y; } public void setY(double y) { this.y = y; } } class Circle extends Shape { private double r; public Circle() { } public Circle(double r) { if (r > 0) { this.r = r; } else { System.out.println("Wrong Format"); } } public double getR() { return r; } public void setR(double r) { if (r > 0) { this.r = r; } else { System.out.println("Wrong Format"); } } public double getArea() { return r * r * Math.PI; } @Override public int compareTo(Object o) { if(o instanceof Circle){ if (getArea() > ((Circle) o).getArea()) { return 1; } else { return -1; } } else{ if (getArea() > ((Rectangle) o).getArea()) { return 1; } else { return -1; } } } } abstract class Shape implements Comparable{ public Shape() { } public abstract double getArea(); }
需要设计好类图,好的类图可以让程序的编写更加顺畅
4.困难与改进意见
1.困难
仔细看清题目给的类图,事实上这些类图是非常重要的,但是我一开始没有重视类图,都是自己乱打一气,其实很不符合题目要求,但是结果是对的,前两次圆和矩形面积都没按类图写,导致后续的代码出现了问题
2.改进意见
arraylist 实现类RandomAccess接口(随机存取接口),这也就标志着arraylist是一个可以随机存取的列表 。适合采用下标方式来访问linkedlist,双向链表,两个元素本来就是有关联的,用foreach会高效
避免用序列化类在构造函数中为不变量赋值
要在本类中覆盖静态导入的变量和方法
本地的方法和属性会被使用。因为编译器有最短路径原则,以确保本类中的属性、方法优先
总结
对于这三次作业中所出现的面向对象的设计思路需要进行理解和吸收
同时还要学习其他库的使用和用法
思考架构也让我受益匪浅,至少能利用面向对象的思想,把一个具体的事物抽象出数据类型和操作了。真正的数据类型不仅仅是存储,而在于性质和操作的捆绑
这几次的作业也提高了我对于程序运行超时和内存不足问题的注意,同时还要减少函数的耦合性

浙公网安备 33010602011771号