1、在实验二的基础上改进设计,功能点如下:
(1)设计算式接口IEqualtion,提供了算式两个操作数(short)、操作符(char)的getter及setter抽象方法,以及calculate抽象方法,它应返回算式的计算结果。
(2)设计算式抽象类AbstractEquation,它实现了IEquation的部分方法,包括getter、setter,它还覆盖实现equals、hashCode方法。AbstractEquation还提供了三个参数的构造方法。
(3)设计算式子类AddEquation、SubEquation,它们继承AbstractEquation,并实现calculate方法。
(4)设计算式约束接口EquationChecker,它有方法bool check(IEqualtion equation)。设计实现该接口的实体类EquationCheckerOfRange。它的构造方法是:EquationCheckerOfRange(int min, int max),min指出操作数及结果的最小值(含),max指出操作数及结果的最大值(含),该类主要实现check方法,限定操作数及结果。
(5)设计算式产生类EquationGenerator。它有产生算式集合的方法:List<IEqualtion> generate(int n, EquationChecker checker),产生n个,无重复的(内部使用HashSet),受约束(checker实例检查)的算式。产生时操作数要随机,加减法算式要随机。
(6)设计Main类。读入数目n,产生(EquationGenerator/EquationCheckerOfRange)n个加减法算式(AddEquation/SubEquation),产生次序随机,且操作数介于0到100(含)。遍历算式,并在终端输出算式。
2、使用设计模式对上述代码进行改造
(7)将EquationGenerator改造为单实例类。
3、使用Java的序列化机制对上述代码进行改造
(8)将产生的算式保存到文件中,随后读取它们,进行验证。
public interface IEqualtion {
// 获取第一个操作数
short getNum1();
// 设置第一个操作数
void setNum1(short num1);
// 获取第二个操作数
short getNum2();
// 设置第二个操作数
void setNum2(short num2);
// 获取操作符
char getOperator();
// 设置操作符
void setOperator(char operator);
// 计算结果
short calculate();
}
import java.util.*;
public abstract class AbstractEquation implements IEqualtion{
private short num1;
private short num2;
private char operator;
// 三个参数的构造方法
public AbstractEquation(short num1, short num2, char operator) {
this.num1 = num1;
this.num2 = num2;
this.operator = operator;
}
// 实现接口的getter方法
@Override
public short getNum1() {
return num1;
}
@Override
public short getNum2() {
return num2;
}
@Override
public char getOperator() {
return operator;
}
// 实现接口的setter方法
@Override
public void setNum1(short num1) {
this.num1 = num1;
}
@Override
public void setNum2(short num2) {
this.num2 = num2;
}
@Override
public void setOperator(char operator) {
this.operator = operator;
}
// 覆盖实现equals方法
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
AbstractEquation that = (AbstractEquation) obj;
return num1 == that.num1 && num2 == that.num2 && operator == that.operator;
}
// 覆盖实现hashCode方法
@Override
public int hashCode() {
return Objects.hash(num1, num2, operator);
}
}
public class AddEquation extends AbstractEquation{
public AddEquation(short num1, short num2) {
super(num1, num2, '+');
}
@Override
public short calculate(){
return (short)(getNum1()+getNum2());
}
}
public class SubEquation extends AbstractEquation {
public SubEquation(short num1, short num2) {
super(num1 ,num2,'-');
}
@Override
public short calculate(){
return (short)(getNum1()-getNum2());
}
}
// 定义算式约束接口
public interface EquationChecker {
boolean check(IEqualtion equation);
}
// 实现EquationChecker接口的实体类,用于检查操作数及结果是否在指定范围内
class EquationCheckerOfRange implements EquationChecker {
private int min;
private int max;
public EquationCheckerOfRange(int min, int max) {
this.min = min;
this.max = max;
}
@Override
public boolean check(IEqualtion equation) {
int result = equation.calculate();
int num1 = equation.getNum1();
int num2 = equation.getNum2();
// 检查操作数和结果是否在指定范围内
return (num1 >= min && num1 <= max) &&
(num2 >= min && num2 <= max) &&
(result >= min && result <= max);
}
}
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Random;
import java.util.Set;
public class EquationGenerator implements Serializable {
private static EquationGenerator instance;
private Random random = new Random();
// 私有构造函数,防止外部直接创建实例
private EquationGenerator() {}
// 获取单例实例的静态方法
public static synchronized EquationGenerator getInstance() {
if (instance == null) {
instance = new EquationGenerator();
}
return instance;
}
public List<IEqualtion> generate(int n, EquationChecker checker) {
List<IEqualtion> equations = new ArrayList<>();
Set<String> uniqueEquations = new HashSet<>();
while (equations.size() < n) {
int num1 = random.nextInt(101); // 生成0-100的随机数
int num2 = random.nextInt(101); // 生成0-100的随机数
// 随机选择加法或减法
int ov = random.nextInt(2);
IEqualtion equation;
if (ov==1) {
equation = new AddEquation((short) num1, (short) num2);
} else {
equation = new SubEquation((short) num1, (short) num2);
}
// 检查算式是否满足约束条件并且是唯一的
if (checker.check(equation) && uniqueEquations.add(equation.toString())) {
equations.add(equation);
}
}
return equations;
}
}
import java.util.List;
import java.util.Scanner;
import java.io.FilterInputStream;
import java.io.*;
import java.io.ObjectOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class Main {
public static void main(String[] args) {
EquationGenerator generator = EquationGenerator.getInstance();
EquationChecker checker = new EquationCheckerOfRange(0, 100);
System.out.print("请输入要生成的算式数量: ");
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
String [] a = new String[n];
while (true) {
if (scanner.hasNextInt()) {
int i = 0;
if (n > 0) {
List<IEqualtion> equations = generator.generate(n, checker);
for (IEqualtion equation : equations) {
System.out.println(equation.getNum1() + " " + equation.getOperator() + " " + equation.getNum2() + " = " + equation.calculate());
a[i]=equation.getNum1() + " " + equation.getOperator() + " " + equation.getNum2() + " = " + equation.calculate();
i++;
}
break;
} else {
System.out.print("数量必须是正整数,请重新输入: ");
}
} else {
System.out.print("输入无效,请重新输入正整数: ");
scanner.next(); // 清除非整数输入
}
}
scanner.close();
//序列化
try{
FileOutputStream fileout = new FileOutputStream("us.ser");
ObjectOutputStream out = new ObjectOutputStream(fileout);
out.writeObject(a);
System.out.print("序列化数据保存至、user/us.ser");
}catch(
IOException j
){
j.printStackTrace();
}
//反序列化
try{
FileInputStream filein = new FileInputStream("us.ser");
ObjectInputStream in = new ObjectInputStream(filein);
String[] x = (String[]) in.readObject();
System.out.println("以下为读取的内容");
for (int m = 0; m < a.length; m++) {
System.out.println(x[m]);
}
}catch (IOException j){
j.printStackTrace();
return;
}catch (ClassNotFoundException c){
System.out.println("not found!");
c.printStackTrace();
return;
}System.out.println("算式:");
}
}
将HashSet转化为ArrayList:
Convert HashSet to a List/ArrayList
单例设计模式:
Java的序列化机制:
Java序列化ArrayList
https://www.java8net.com/2020/03/serialize-arraylist-in-java.html
Serialize and Deserialize an ArrayList in Java
序列化相关I/O类
FileOutputStream (Java Platform SE 8 )
ObjectOutputStream (Java Platform SE 8 )
FileInputStream (Java Platform SE 8 )
ObjectInputStream (Java Platform SE 8 )
java.util.Random类的API文档:
java.util.HashSet类的API文档:
java.util.Scanner类的API文档:
关于equals、hashCode方法:
Java中的equals()方法_public boolean equals(object obj) { if (obj instan-CSDN博客
详解equals()方法和hashCode()方法 - 知乎
关于Java集合的遍历: