一:前言:
1.知识点:主要包括类和对象的使用、数据封装、方法的定义和使用、继承、多态、泛型、抽象类,集合框架,异常处理,字符串处理、以及基本的输入输出操作。
2.题量:现在的题目集都是一道题了,题量没什么说的。
3.难度:每次题集的难度都较大,每次都要7.8小时及以上,第七次的电路题增加了互斥开关和受控窗帘,互斥开关需要记录接入的引脚是1,2或者1,3,然后再判断开关的状态,受控窗帘
只需要和之前的受控元件一样处理即可。第八次的电路题难度很大,需要改变的逻辑很多,之前的电路题我的思路都是先判断电路的通路,短路和断路,然后通过计算每个元件的电阻和总
电阻来得到每个元件的分压,但是这一次还需要给出每个引脚的电压,而且电路更加复杂,需要考虑右边引脚的电位可能大于左边引脚的电位等许多难以考虑到的情况,难度很大。
二:设计与分析:
第七次作业:
家居强电电路模拟程序-3:模拟了一个电路系统中设备的操作,包括开关、调速器和受控设备(如灯具和风扇等),在之前的基础上互斥开关和受控窗帘。
类的详细设计
-
Device(抽象类)
属性:
id:设备的唯一标识符。
pin1 和 pin2:记录接入的引脚是1,2或者1,3,再判断开关的状态
vd:电压差。
resistance:设备的总电阻。
方法:
构造函数:初始化设备ID。
getResistance():抽象方法,用于获取设备的总电阻。 -
ControlDevice(抽象类)
继承自:Device
属性:
继承自Device的所有属性。
resistance:初始化为0,表示控制设备的电阻。
方法:
构造函数:初始化设备ID和电阻。
OutVoltage(double v):抽象方法,根据输入电压计算输出电压。
getResistance():返回设备的电阻。 -
ControlledDevice(抽象类)
继承自:Device
方法:
构造函数:初始化设备ID。
setState(double v):抽象方法,根据电压差设置设备的状态。 -
SerialCircuit(类)
继承自:Device
属性:
继承自Device的所有属性。
rnn:表示接入互斥开关的哪个口,2或者3。
flag:标志位。
flat:用于标记电路的连接状态。
devices:存储串联电路中的设备列表。
totalResistance:计算得到的总电阻。
方法:
构造函数:初始化设备ID。
addDevice(Device device):添加设备到电路。
getResistance():返回计算得到的总电阻。
calculateVoltage(double inputVoltage):计算电路中每个设备的电压。 -
ParallelCircuit(类)
继承自:Device
属性:
继承自Device的所有属性。
rnn:表示接入互斥开关的哪个口,2或者3。
flat:用于标记电路的连接状态。
circuits:存储并联电路中的串联电路列表。
totalResistance:计算得到的总电阻。
方法:
构造函数:初始化设备ID。
addCircuit(SerialCircuit circuit):添加串联电路到并联电路。
updateResistance():更新并联电路的总电阻。
getResistance():返回计算得到的总电阻。
calculateVoltage(double inputVoltage):计算并联电路中每个串联电路的电压。 -
MutualSwitch(类)
继承自:ControlDevice
属性:
继承自ControlDevice的所有属性。
pin12Resistance:12之间默认电阻。
pin13Resistance:13之间默认电阻。
state:互斥开关的状态。
方法:
构造函数:初始化设备ID。
OutVoltage(double v):根据互斥开关状态返回输入电压或0。
getState():返回互斥开关的状态字符串。
control():切换互斥开关状态。
getResistance(int pin):根据引脚返回互斥开关的电阻。 -
Switch(类)
继承自:ControlDevice
属性:
继承自ControlDevice的所有属性。
state:开关的状态。
方法:
构造函数:初始化设备ID和状态。
OutVoltage(double v):根据开关状态返回输入电压或0。
getState():返回开关的状态字符串。
control():切换开关状态。 -
GearSpeedRegulator(类)
继承自:ControlDevice
属性:
继承自ControlDevice的所有属性。
flag:用于控制齿轮速度。
方法:
构造函数:初始化设备ID。
changeGear(boolean increase):根据传入的布尔值增加或减少齿轮速度。
OutVoltage(double v):根据齿轮速度计算输出电压。 -
ContinuousSpeedRegulator(类)
继承自:ControlDevice
属性:
继承自ControlDevice的所有属性。
parameter:用于控制连续速度。
方法:
构造函数:初始化设备ID。
OutVoltage(double v):根据参数计算输出电压。 -
IncandescentLamp(类)
继承自:ControlledDevice
属性:
继承自ControlledDevice的所有属性。
light:表示灯的亮度。
resistance:固定为10。
方法:
构造函数:初始化设备ID和电阻。
setState(double v):根据电压差设置灯的亮度。
getResistance():返回设备的电阻。 -
FluorescentLamp(类)
继承自:ControlledDevice
属性:
继承自ControlledDevice的所有属性。
light:表示灯的亮度。
resistance:固定为5。
方法:
构造函数:初始化设备ID和电阻。
setState(double v):根据电压差设置灯的亮度。
getResistance():返回设备的电阻。 -
CeilingFan(类)
继承自:ControlledDevice
属性:
继承自ControlledDevice的所有属性。
speed:表示风扇的速度。
resistance:固定为20。
方法:
构造函数:初始化设备ID和电阻。
setState(double v):根据电压差设置风扇的速度。
getResistance():返回设备的电阻。 -
FloorFan(类)
继承自:ControlledDevice
属性:
继承自ControlledDevice的所有属性。
speed:表示风扇的速度。
resistance:固定为20。
方法:
构造函数:初始化设备ID和电阻。
setState(double v):根据电压差设置风扇的速度。
getResistance():返回设备的电阻。 -
Curtain(类)
继承自:ControlledDevice
属性:
继承自ControlledDevice的所有属性。
openRatio:窗帘开合比例。
resistance:固定为15。
方法:
构造函数:初始化设备ID和电阻。
setState(double v):根据电压差设置窗帘的开合比例。
calculateTotalLux():计算总光照强度。
getResistance():返回设备的电阻。 -
Main(类)
属性:
deviceMap:存储所有设备的映射。
allDevices:存储所有设备。
serialCircuits:存储所有串联电路。
parallelCircuits:存储所有并联电路。
lines:存储输入的指令。
方法:
main(String[] args):程序的主入口,处理输入,设置电阻,计算电压,打印结果。
handleLines(Listlines):处理输入的每一行指令。
setResistance():设置电路的电阻。
processCircuit(String line):处理电路定义的指令。
getOrCreateDevice(String deviceId):获取或创建设备。
printResults():打印所有设备的结果。
数据处理:
使用 handleLines 方法处理输入的每一行数据,根据数据类型执行相应的操作,如控制设备状态或处理电路定义。
使用 setResistance 方法遍历所有设备和电路,计算并设置设备的电阻和电路的总电阻。
使用 processCircuit 方法处理电路定义,创建串联电路(SerialCircuit)和并联电路(ParallelCircuit)的实例,并根据连接定义添加设备。
使用 getOrCreateDevice 方法根据输入数据获取或创建设备实例,如开关(Switch)、调速器(GearSpeedRegulator 和 ContinuousSpeedRegulator)、灯具(IncandescentLamp 和 FluorescentLamp)、风扇(CeilingFan 和 FloorFan)以及窗帘(Curtain)。
计算电压:
使用 calculateVoltage 方法计算每个电路的电压差,该方法会根据电路的总电阻和输入电压计算每个设备的电压差(vd)。
类图:
第八次作业:
总体的设计思路和第七题类似,主要增加了对每个元件引脚的电位的计算方法,
主要思路:元器件的输入电压等于上一个的输出电压,输出电压 = 输入电压 - 电压差;
增加了一个List,用于将最近的一次输出电压存入
点击查看代码
Lsit,List<Double> voltages = new ArrayList<>();
增加一个方法用于获取最近一次的输出的电压
点击查看代码
public static double getRecentVoltage(List<Double> voltages){
return voltages.get(voltages.size() - 1);
}
类图:
三:采坑心得:
第七次作业:
在计算完分压和得到所有受控元件状态输出时,按照id的顺序输出,但是我考虑到的id为int类型,而题目中id应该为String类型,也就是说id为11的应该在id为2的设备之前输出。
修改排序的代码,因为当时如果是将int类型改为String类型需要改变很多地方,所以我就想到了只改排序,按照字典序的id排序即可
点击查看代码
// 对每类设备按ID排序
Comparator<Device> byId = Comparator.comparing(d -> String.valueOf(d.id));
switches.sort(byId);
gearRegulators.sort(byId);
continuousRegulators.sort(byId);
incandescentLamps.sort(byId);
fluorescentLamps.sort(byId);
ceilingFans.sort(byId);
floorFans.sort(byId);
mutualSwitches.sort(byId); // 互斥开关排序
curtains.sort(byId);
第八次作业:
考虑右边的引脚的电位可能大于左边的引脚,左边为断路时,通过并联的其他路将电流传到右边的引脚,这样左边的引脚就为0,
但是右边的引脚却不为零。
四:改进建议:
第七次作业:
关键指标分析
语句数 (Statements): 435条语句,这个数量表明代码文件中包含了较多的操作。
分支语句百分比 (Percent Branch Statements): 29.4%,这个比例相对较高,表明代码中包含了不少条件判断,可能会影响代码的可读性和可维护性。
方法调用语句 (Method Call Statements): 159,这表明代码中方法调用较为频繁,这通常是好的实践,但如果方法调用链过长,可能会影响性能。
注释率 (Percent Lines with Comments): 8.2%,注释率较低,这可能影响代码的可读性和可维护性。
类和接口数量 (Classes and Interfaces): 14,这个数量表明项目中包含多个类和接口,需要确保每个类和接口都有清晰的职责和设计。
方法复杂度
最复杂方法 (Name of Most Complex Method): Mutua,位于第104行,最大复杂度为81,这表明该方法可能包含复杂的逻辑,需要进一步分析和可能的重构。
平均方法复杂度 (Average Complexity): 4.35,这个平均值表明大部分方法的复杂度处于中等水平。
代码块深度
最深代码块行号 (Line Number of Deepest Block): 290,最大代码块深度为8,这可能表明存在深层嵌套的代码块,这通常不是一个好的实践,因为它降低了代码的可读性。
平均代码块深度 (Average Block Depth): 3.03,这个平均值表明代码块深度总体上是可以接受的,但仍需注意深层嵌套的代码块。
改进建议
重构代码: 考虑将Main.java文件中的代码重构为更小的模块,每个模块负责一个单一职责,以降低复杂度。
增加注释: 为代码添加更多的注释,特别是对于复杂的逻辑和方法,以提高代码的可读性。
简化复杂方法: 尝试简化最复杂的方法Mutua,可能通过提取子方法或重构逻辑来实现。
减少深层嵌套: 检查并重构深层嵌套的代码块,以提高代码的可读性和可维护性。
五:总结:
本阶段的题目集涵盖了Java编程的多个方面,包括面向对象编程、数据结构、异常处理、正则表达式、输入输出处理等。
通过题集,我学会了Java集合框架,了解它们的用途和性能特点,还学会了对字符串的处理,采用split,trim,substring,indexof等方法,学会了面向对象的思想,
接下来应该深入学习异常处理:学习如何自定义异常,并在代码中合理使用try-catch-finally块来处理异常,以及一些java模型,如装饰模型,桥接模型等,在写代码时可以启到事半功倍的效果,便于迭代。
学习心得:在写题时不能看个大概就直接开始写,应该在反复阅读题目设计好解题思路,画出简易的类图后开始写。
不然在后面调试代码改错时会花费大量时间
建议及意见:建议能够给出大作业中测试点的提示信息更加详细一点,有的时候一个测试点需要猜几个小时。