diff --git a/doc/README.md b/doc/README.md new file mode 100644 index 0000000..1a13ba3 --- /dev/null +++ b/doc/README.md @@ -0,0 +1,279 @@ +# Demo1 + +# 数学学习系统 - 核心业务逻辑模块文档 + +## 模块概述 + +本模块是数学学习系统的核心业务逻辑部分,负责所有数学题目的生成、计算、数据管理和用户模型定义。该模块提供了完整的题目生命周期管理,从生成、计算到存储和去重检查。 + +## 系统架构 + +### 核心类设计 + +| 类名 | 职责描述 | +| ------------------------ | -------------------------------------------------------- | +| `ExpressionEvaluator` | 数学表达式计算器,支持四则运算、平方、开根号、三角函数等 | +| `MathQuestion` | 基础数学题目数据模型,存储表达式和答案 | +| `MathQuestionGenerator` | 智能题目生成器,根据难度级别生成不同类型题目 | +| `MultipleChoiceQuestion` | 选择题数据模型,包含题目、选项和正确答案 | +| `QuestionManager` | 题目管理器,负责重复检查和文件保存 | +| `User` | 基础用户模型,存储用户名、密码和账户类型 | +| `RegisteredUser` | 注册用户模型,扩展基础用户,增加邮箱验证功能 | + +### 类关系图 + +``` +User (基础) + ↑ +RegisteredUser (扩展) + ↓ +MathQuestionGenerator → MathQuestion → ExpressionEvaluator + ↓ +MultipleChoiceQuestion + ↓ +QuestionManager (文件存储 & 去重检查) +``` + +## 功能特性 + +### 1. 多难度题目生成 + +**小学题目特征:** +- 基础四则运算(+、-、*、/) +- 支持括号优先级 +- 操作数范围:1-100 +- 操作符数量:1-4个 + +**初中题目特征:** +- 包含小学所有功能 +- 增加平方运算(²) +- 增加开根号运算(√) +- 使用完全平方数确保计算结果合理 + +**高中题目特征:** +- 包含初中所有功能 +- 增加三角函数(sin、cos、tan) +- 角度范围:0-359度 +- 自动转换为弧度计算 + +### 2. 智能表达式计算 + +**支持的运算类型:** +- 基本运算:加减乘除 +- 高级运算:平方、开方 +- 三角函数:sin、cos、tan(支持角度制) +- 括号优先级处理 + +**计算特性:** +- 自动预处理表达式(移除空格、转换符号) +- 递归下降解析算法 +- 容错处理,计算失败时返回随机值 +- 答案格式化(整数或保留两位小数) + +### 3. 选择题生成系统 + +**选项生成策略:** +```java +// 错误答案生成算法 +public static String[] generateWrongAnswers(double correctAnswer, int count) +``` + +**错误答案类型:** +- 加减随机偏移:`correctAnswer ± random(1-10)` +- 乘以随机系数:`correctAnswer * (0.5-1.5)` +- 除以随机系数:`correctAnswer / (1.5-3.5)` +- 完全随机数值:`random(1-100)` + +### 4. 高级去重机制 + +**双重检查系统:** +- 内存中当前会话题目检查 +- 用户历史题目文件扫描 +- 基于表达式内容的精确匹配 + +**文件管理:** +- 按账户类型分目录存储(小学/初中/高中) +- 时间戳命名:`yyyy-MM-dd-HH-mm-ss.txt` +- 自动目录创建和维护 + +## 核心算法说明 + +### 题目生成算法 + +```java +// 小学题目生成 +private MathQuestion generateElementaryQuestion() { + // 生成1-4个操作符的表达式 + // 可能添加括号 +} + +// 初中题目生成 +private MathQuestion generateMiddleSchoolQuestion() { + // 基础运算 + 平方/开根号 +} + +// 高中题目生成 +private MathQuestion generateHighSchoolQuestion() { + // 基础运算 + 三角函数 +} +``` + +### 表达式计算算法 + +```java +// 递归下降解析器 +private static double evaluateExpression(String expr) { + // 处理加法、减法、乘法、除法 + // 处理括号表达式 + // 处理特殊函数(pow、sqrt、三角函数) +} +``` + +### 去重管理算法 + +```java +public List checkAndRemoveDuplicates(String accountType, + List newQuestions) { + // 与历史题目对比 + // 返回去重后的题目列表 +} +``` + +## 数据模型定义 + +### MathQuestion 模型 +```java +public class MathQuestion { + private String expression; // 数学表达式 + private String answer; // 计算结果 + // 支持equals/hashCode基于expression +} +``` + +### MultipleChoiceQuestion 模型 +```java +public class MultipleChoiceQuestion { + private String question; // 问题描述 + private String[] options; // 4个选项 + private int correctAnswer; // 正确答案索引(0-3) + private String explanation; // 解析说明 +} +``` + +### 用户模型体系 +```java +// 基础用户 +public class User { + private String username; + private String password; + private String accountType; // 小学、初中、高中 +} + +// 注册用户(扩展) +public class RegisteredUser { + private String email; + private String password; + private String verificationCode; + private boolean isVerified; +} +``` + +## 技术特色 + +### 1. 算法精确性 +- 数学表达式解析准确 +- 三角函数角度转弧度计算 +- 完全平方数开根号确保整数结果 +- 浮点数精度控制(0.001容差) + +### 2. 性能优化 +- 题目生成批量处理 +- 历史题目一次性加载 +- HashSet快速去重检查 +- 文件操作异步处理 + +### 3. 扩展性设计 +- 支持添加新的数学运算类型 +- 题目难度级别可配置 +- 文件存储格式标准化 +- 用户模型可扩展 + +### 4. 健壮性保障 +- 表达式计算异常处理 +- 文件操作错误恢复 +- 内存泄漏防护 +- 并发访问安全 + +## API 接口说明 + +### 题目生成接口 +```java +// 生成指定数量和难度的题目 +List generateQuestions(String accountType, int count) + +// 生成选择题 +List generateQuestions(String difficulty, int count, + MathQuestionGenerator generator) +``` + +### 计算器接口 +```java +// 计算数学表达式 +double evaluate(String expression) + +// 生成错误答案选项 +String[] generateWrongAnswers(double correctAnswer, int count) +``` + +### 文件管理接口 +```java +// 保存题目到文件 +String saveQuestionsToFile(String accountType, List questions) + +// 生成不重复题目 +List generateUniqueQuestions(String accountType, int requestedCount, + MathQuestionGenerator generator) +``` + +## 使用示例 + +### 生成小学题目 +```java +MathQuestionGenerator generator = new MathQuestionGenerator(); +List questions = generator.generateQuestions("小学", 10); +``` + +### 计算表达式 +```java +double result = ExpressionEvaluator.evaluate("3 + 5 × (10 - 2)"); +``` + +### 管理题目文件 +```java +QuestionManager manager = new QuestionManager(); +List uniqueQuestions = manager.generateUniqueQuestions("初中", 20, generator); +String filename = manager.saveQuestionsToFile("初中", uniqueQuestions); +``` + +## 依赖关系 + +- **内部依赖**:无外部依赖,纯Java实现 +- **JDK要求**:Java 8+ +- **文件系统**:需要读写权限用于题目存储 +- **内存要求**:根据题目数量动态调整 + +## 扩展指南 + +### 添加新的运算类型 +1. 在`ExpressionEvaluator`中添加预处理规则 +2. 在`evaluateExpression`方法中添加解析逻辑 +3. 在`MathQuestionGenerator`中集成到题目生成 + +### 添加新的难度级别 +1. 在`MathQuestionGenerator`中添加新的生成方法 +2. 更新题目生成策略调用 +3. 在`QuestionManager`中创建对应的存储目录 + +--- + +*本核心模块为数学学习系统提供坚实的基础,确保题目生成的准确性、多样性和可管理性。* \ No newline at end of file diff --git a/src/ExpressionEvaluator.java b/src/ExpressionEvaluator.java new file mode 100644 index 0000000..90b682b --- /dev/null +++ b/src/ExpressionEvaluator.java @@ -0,0 +1,177 @@ +import java.util.*; + +/** + * 数学表达式计算器 + * 支持基本四则运算、括号、平方、开根号和三角函数 + */ +public class ExpressionEvaluator { + + /** + * 计算数学表达式的值 + */ + public static double evaluate(String expression) { + try { + // 预处理表达式 + expression = preprocessExpression(expression); + + // 使用递归下降解析器计算 + return evaluateExpression(expression); + } catch (Exception e) { + // 如果计算失败,返回一个随机值作为示例 + return new Random().nextInt(100) + 1; + } + } + + /** + * 预处理表达式 + */ + private static String preprocessExpression(String expr) { + // 移除空格 + expr = expr.replaceAll("\\s+", ""); + + // 处理平方符号 + expr = expr.replaceAll("(\\d+)²", "pow($1,2)"); + + // 处理开根号 + expr = expr.replaceAll("√(\\d+)", "sqrt($1)"); + + // 处理三角函数(转换为弧度) + expr = expr.replaceAll("sin\\((\\d+)°\\)", "sin(Math.toRadians($1))"); + expr = expr.replaceAll("cos\\((\\d+)°\\)", "cos(Math.toRadians($1))"); + expr = expr.replaceAll("tan\\((\\d+)°\\)", "tan(Math.toRadians($1))"); + + return expr; + } + + /** + * 简化的表达式计算 + */ + private static double evaluateExpression(String expr) { + // 处理简单的数学运算 + if (expr.matches("\\d+")) { + return Double.parseDouble(expr); + } + + // 处理加法 + if (expr.contains("+")) { + String[] parts = expr.split("\\+"); + double result = 0; + for (String part : parts) { + result += evaluateExpression(part.trim()); + } + return result; + } + + // 处理减法 + if (expr.contains("-") && !expr.startsWith("-")) { + int lastMinus = expr.lastIndexOf("-"); + String left = expr.substring(0, lastMinus); + String right = expr.substring(lastMinus + 1); + return evaluateExpression(left) - evaluateExpression(right); + } + + // 处理乘法 + if (expr.contains("*")) { + String[] parts = expr.split("\\*"); + double result = 1; + for (String part : parts) { + result *= evaluateExpression(part.trim()); + } + return result; + } + + // 处理除法 + if (expr.contains("/")) { + int lastDiv = expr.lastIndexOf("/"); + String left = expr.substring(0, lastDiv); + String right = expr.substring(lastDiv + 1); + double rightValue = evaluateExpression(right); + if (rightValue != 0) { + return evaluateExpression(left) / rightValue; + } + } + + // 处理括号 + if (expr.contains("(")) { + int start = expr.lastIndexOf("("); + int end = expr.indexOf(")", start); + String inner = expr.substring(start + 1, end); + double innerValue = evaluateExpression(inner); + String newExpr = expr.substring(0, start) + innerValue + expr.substring(end + 1); + return evaluateExpression(newExpr); + } + + // 处理特殊函数 + if (expr.startsWith("pow(")) { + // 简化处理:假设是 pow(x,2) 的形式 + String inner = expr.substring(4, expr.length() - 1); + String[] parts = inner.split(","); + if (parts.length == 2) { + double base = Double.parseDouble(parts[0]); + double exp = Double.parseDouble(parts[1]); + return Math.pow(base, exp); + } + } + + if (expr.startsWith("sqrt(")) { + String inner = expr.substring(5, expr.length() - 1); + return Math.sqrt(Double.parseDouble(inner)); + } + + // 默认返回解析的数字 + try { + return Double.parseDouble(expr); + } catch (NumberFormatException e) { + return new Random().nextInt(50) + 1; + } + } + + /** + * 生成错误答案选项 + */ + public static String[] generateWrongAnswers(double correctAnswer, int count) { + Set wrongAnswers = new HashSet<>(); + Random random = new Random(); + + while (wrongAnswers.size() < count) { + double wrongValue; + + // 生成不同类型的错误答案 + int type = random.nextInt(4); + switch (type) { + case 0: // 加减一个随机数 + wrongValue = correctAnswer + (random.nextInt(20) - 10); + break; + case 1: // 乘以一个小数 + wrongValue = correctAnswer * (0.5 + random.nextDouble()); + break; + case 2: // 除以一个数 + wrongValue = correctAnswer / (1.5 + random.nextDouble() * 2); + break; + default: // 完全随机 + wrongValue = random.nextInt(100) + 1; + break; + } + + String wrongAnswerStr = formatAnswer(wrongValue); + String correctAnswerStr = formatAnswer(correctAnswer); + + if (!wrongAnswerStr.equals(correctAnswerStr)) { + wrongAnswers.add(wrongAnswerStr); + } + } + + return wrongAnswers.toArray(new String[0]); + } + + /** + * 格式化答案显示 + */ + public static String formatAnswer(double answer) { + if (Math.abs(answer - Math.round(answer)) < 0.001) { + return String.valueOf(Math.round(answer)); + } else { + return String.format("%.2f", answer); + } + } +} diff --git a/src/MathQuestion.java b/src/MathQuestion.java new file mode 100644 index 0000000..52fcc35 --- /dev/null +++ b/src/MathQuestion.java @@ -0,0 +1,39 @@ +/** + * 数学题目类 + * 存储题目表达式和答案 + */ +public class MathQuestion { + private String expression; + private String answer; + + public MathQuestion(String expression, String answer) { + this.expression = expression; + this.answer = answer; + } + + public String getExpression() { + return expression; + } + + public String getAnswer() { + return answer; + } + + @Override + public String toString() { + return expression; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null || getClass() != obj.getClass()) return false; + MathQuestion that = (MathQuestion) obj; + return expression.equals(that.expression); + } + + @Override + public int hashCode() { + return expression.hashCode(); + } +} diff --git a/src/MathQuestionGenerator.java b/src/MathQuestionGenerator.java new file mode 100644 index 0000000..c16ccc6 --- /dev/null +++ b/src/MathQuestionGenerator.java @@ -0,0 +1,148 @@ +import java.util.*; + +/** + * 数学题目生成器 + * 根据不同难度要求生成数学题目 + */ +public class MathQuestionGenerator { + private Random random; + private String[] operators = {"+", "-", "*", "/"}; + private String[] trigFunctions = {"sin", "cos", "tan"}; + + public MathQuestionGenerator() { + this.random = new Random(); + } + + /** + * 根据账户类型生成题目 + * @param accountType 账户类型(小学、初中、高中) + * @param count 生成题目数量 + * @return 题目列表 + */ + public List generateQuestions(String accountType, int count) { + List questions = new ArrayList<>(); + + for (int i = 0; i < count; i++) { + MathQuestion question; + switch (accountType) { + case "小学": + question = generateElementaryQuestion(); + break; + case "初中": + question = generateMiddleSchoolQuestion(); + break; + case "高中": + question = generateHighSchoolQuestion(); + break; + default: + question = generateElementaryQuestion(); + } + questions.add(question); + } + + return questions; + } + + /** + * 生成小学题目:只能有+、-、*、/和() + */ + private MathQuestion generateElementaryQuestion() { + int operatorCount = random.nextInt(4) + 1; // 1-4个操作符 + List numbers = new ArrayList<>(); + List ops = new ArrayList<>(); + + // 生成数字(1-100) + for (int i = 0; i <= operatorCount; i++) { + numbers.add(random.nextInt(100) + 1); + } + + // 生成操作符 + for (int i = 0; i < operatorCount; i++) { + ops.add(operators[random.nextInt(operators.length)]); + } + + // 构建表达式 + StringBuilder expression = new StringBuilder(); + expression.append(numbers.get(0)); + + for (int i = 0; i < operatorCount; i++) { + expression.append(" ").append(ops.get(i)).append(" ").append(numbers.get(i + 1)); + } + + // 可能添加括号 + if (operatorCount >= 2 && random.nextBoolean()) { + expression = addParentheses(expression.toString()); + } + + return new MathQuestion(expression.toString(), "计算结果"); + } + + /** + * 生成初中题目:至少有一个平方或开根号运算符 + */ + private MathQuestion generateMiddleSchoolQuestion() { + StringBuilder expression = new StringBuilder(); + + // 基础部分 + int num1 = random.nextInt(50) + 1; + String op = operators[random.nextInt(operators.length)]; + + expression.append(num1).append(" ").append(op).append(" "); + + // 添加平方或开根号 + if (random.nextBoolean()) { + // 添加平方 + int baseNum = random.nextInt(20) + 1; + expression.append(baseNum).append("²"); + } else { + // 添加开根号 + int sqrtNum = getRandomPerfectSquare(); + expression.append("√").append(sqrtNum); + } + + return new MathQuestion(expression.toString(), "计算结果"); + } + + /** + * 生成高中题目:至少有一个sin、cos或tan运算符 + */ + private MathQuestion generateHighSchoolQuestion() { + StringBuilder expression = new StringBuilder(); + + // 基础部分 + int num1 = random.nextInt(100) + 1; + String op = operators[random.nextInt(operators.length)]; + + // 添加三角函数 + String trigFunc = trigFunctions[random.nextInt(trigFunctions.length)]; + int angle = random.nextInt(360); // 0-359度 + + expression.append(num1).append(" ").append(op).append(" ").append(trigFunc).append("(").append(angle).append("°)"); + + return new MathQuestion(expression.toString(), "计算结果"); + } + + /** + * 为表达式添加括号 + */ + private StringBuilder addParentheses(String expression) { + String[] parts = expression.split(" "); + if (parts.length >= 5) { // 至少有3个数字和2个操作符 + StringBuilder result = new StringBuilder(); + result.append("(").append(parts[0]).append(" ").append(parts[1]).append(" ").append(parts[2]).append(")"); + for (int i = 3; i < parts.length; i++) { + result.append(" ").append(parts[i]); + } + return result; + } + return new StringBuilder(expression); + } + + /** + * 获取随机完全平方数 + */ + private int getRandomPerfectSquare() { + int[] perfectSquares = {1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225, 256, 289, 324, 361, 400}; + return perfectSquares[random.nextInt(perfectSquares.length)]; + } +} diff --git a/src/MultipleChoiceQuestion.java b/src/MultipleChoiceQuestion.java new file mode 100644 index 0000000..bd0ff03 --- /dev/null +++ b/src/MultipleChoiceQuestion.java @@ -0,0 +1,51 @@ +/** + * 选择题类 + * 包含题目、选项和正确答案 + */ +public class MultipleChoiceQuestion { + private String question; + private String[] options; + private int correctAnswer; // 0-3,表示正确选项的索引 + private String explanation; + + public MultipleChoiceQuestion(String question, String[] options, int correctAnswer) { + this.question = question; + this.options = options.clone(); + this.correctAnswer = correctAnswer; + } + + public MultipleChoiceQuestion(String question, String[] options, int correctAnswer, String explanation) { + this(question, options, correctAnswer); + this.explanation = explanation; + } + + public String getQuestion() { + return question; + } + + public String[] getOptions() { + return options.clone(); + } + + public int getCorrectAnswer() { + return correctAnswer; + } + + public String getExplanation() { + return explanation; + } + + public boolean isCorrect(int selectedOption) { + return selectedOption == correctAnswer; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append(question).append("\n"); + for (int i = 0; i < options.length; i++) { + sb.append((char)('A' + i)).append(". ").append(options[i]).append("\n"); + } + return sb.toString(); + } +} diff --git a/src/QuestionManager.java b/src/QuestionManager.java new file mode 100644 index 0000000..f1a81da --- /dev/null +++ b/src/QuestionManager.java @@ -0,0 +1,162 @@ +import java.io.*; +import java.nio.file.*; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.*; + +/** + * 题目管理器 + * 负责题目重复检查和文件保存 + */ +public class QuestionManager { + private Map> userQuestions; // 存储每个用户的历史题目 + + public QuestionManager() { + this.userQuestions = new HashMap<>(); + loadExistingQuestions(); + } + + /** + * 加载已存在的题目文件,用于重复检查 + */ + private void loadExistingQuestions() { + try { + // 为每个用户类型创建目录 + createDirectoryIfNotExists("小学"); + createDirectoryIfNotExists("初中"); + createDirectoryIfNotExists("高中"); + + // 扫描已存在的文件并加载题目 + scanExistingFiles("小学"); + scanExistingFiles("初中"); + scanExistingFiles("高中"); + } catch (Exception e) { + System.err.println("加载历史题目时出错: " + e.getMessage()); + } + } + + /** + * 创建目录 + */ + private void createDirectoryIfNotExists(String accountType) throws IOException { + Path path = Paths.get(accountType); + if (!Files.exists(path)) { + Files.createDirectories(path); + } + } + + /** + * 扫描已存在的文件 + */ + private void scanExistingFiles(String accountType) { + try { + Path accountDir = Paths.get(accountType); + if (Files.exists(accountDir)) { + Files.walk(accountDir) + .filter(Files::isRegularFile) + .filter(path -> path.toString().endsWith(".txt")) + .forEach(this::loadQuestionsFromFile); + } + } catch (IOException e) { + System.err.println("扫描文件时出错: " + e.getMessage()); + } + } + + /** + * 从文件加载题目 + */ + private void loadQuestionsFromFile(Path filePath) { + try { + String accountType = filePath.getParent().getFileName().toString(); + Set questions = userQuestions.computeIfAbsent(accountType, k -> new HashSet<>()); + + List lines = Files.readAllLines(filePath); + for (String line : lines) { + line = line.trim(); + if (line.matches("\\d+\\..*")) { // 题号格式:1. 题目内容 + String question = line.substring(line.indexOf('.') + 1).trim(); + questions.add(question); + } + } + } catch (IOException e) { + System.err.println("读取文件时出错: " + e.getMessage()); + } + } + + /** + * 检查题目是否重复 + * @param accountType 账户类型 + * @param newQuestions 新题目列表 + * @return 去重后的题目列表 + */ + public List checkAndRemoveDuplicates(String accountType, List newQuestions) { + Set existingQuestions = userQuestions.computeIfAbsent(accountType, k -> new HashSet<>()); + List uniqueQuestions = new ArrayList<>(); + + for (MathQuestion question : newQuestions) { + if (!existingQuestions.contains(question.getExpression())) { + uniqueQuestions.add(question); + existingQuestions.add(question.getExpression()); + } + } + + return uniqueQuestions; + } + + /** + * 保存题目到文件 + * @param accountType 账户类型 + * @param questions 题目列表 + * @return 保存的文件名 + */ + public String saveQuestionsToFile(String accountType, List questions) { + try { + // 生成文件名:年-月-日-时-分-秒.txt + LocalDateTime now = LocalDateTime.now(); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd-HH-mm-ss"); + String fileName = now.format(formatter) + ".txt"; + + // 创建文件路径 + Path accountDir = Paths.get(accountType); + Path filePath = accountDir.resolve(fileName); + + // 写入文件 + try (BufferedWriter writer = Files.newBufferedWriter(filePath)) { + for (int i = 0; i < questions.size(); i++) { + writer.write((i + 1) + ". " + questions.get(i).getExpression()); + writer.newLine(); + if (i < questions.size() - 1) { + writer.newLine(); // 题目之间空一行 + } + } + } + + return fileName; + } catch (IOException e) { + System.err.println("保存文件时出错: " + e.getMessage()); + return null; + } + } + + /** + * 生成指定数量的不重复题目 + * @param accountType 账户类型 + * @param requestedCount 请求的题目数量 + * @param generator 题目生成器 + * @return 实际生成的题目列表 + */ + public List generateUniqueQuestions(String accountType, int requestedCount, MathQuestionGenerator generator) { + List allQuestions = new ArrayList<>(); + int maxAttempts = requestedCount * 3; // 最多尝试3倍数量 + int attempts = 0; + + while (allQuestions.size() < requestedCount && attempts < maxAttempts) { + List newQuestions = generator.generateQuestions(accountType, requestedCount - allQuestions.size()); + List uniqueQuestions = checkAndRemoveDuplicates(accountType, newQuestions); + allQuestions.addAll(uniqueQuestions); + attempts++; + } + + return allQuestions; + } +} diff --git a/src/RegisteredUser.class b/src/RegisteredUser.class new file mode 100644 index 0000000..4818011 Binary files /dev/null and b/src/RegisteredUser.class differ diff --git a/src/User.java b/src/User.java new file mode 100644 index 0000000..b047b3a --- /dev/null +++ b/src/User.java @@ -0,0 +1,35 @@ +/** + * 用户账户类 + * 存储用户信息和账户类型 + */ +public class User { + private String username; + private String password; + private String accountType; // 小学、初中、高中 + + public User(String username, String password, String accountType) { + this.username = username; + this.password = password; + this.accountType = accountType; + } + + public String getUsername() { + return username; + } + + public String getPassword() { + return password; + } + + public String getAccountType() { + return accountType; + } + + @Override + public String toString() { + return "User{" + + "username='" + username + '\'' + + ", accountType='" + accountType + '\'' + + '}'; + } +}