Java方法专题 - 动手动脑问题与实验总结
一、随机数生成相关实验
动手动脑1:纯随机数发生器实现
问题要求:
编写一个方法,使用线性同余算法生成指定数目(比如1000个)的随机整数。
算法参数:
- Modulus = 2³¹ - 1 = int.MaxValue
- Multiplier = 7⁵ = 16807
- C = 0
实现代码:
public class LinearCongruentialGenerator {
private static final long MODULUS = 2147483647L; // 2^31 - 1
private static final long MULTIPLIER = 16807L;
private long seed;
public LinearCongruentialGenerator(long seed) {
this.seed = seed;
}
public int nextInt() {
seed = (MULTIPLIER * seed) % MODULUS;
return (int) seed;
}
// 生成指定数量的随机整数
public static int[] generateRandomNumbers(int count, long seed) {
LinearCongruentialGenerator generator = new LinearCongruentialGenerator(seed);
int[] numbers = new int[count];
for (int i = 0; i < count; i++) {
numbers[i] = generator.nextInt();
}
return numbers;
}
}
学习要点:
- 理解伪随机数生成原理
- 掌握线性同余算法的实现
- 学会建立个人代码仓库,积累实用工具类
二、可变参数方法
动手动脑2:可变参数方法的特点
示例代码分析:
public class VariableArgumentsTest {
public static double max(double... values) {
double largest = Double.MIN_VALUE;
for (double v : values) {
if (v > largest) largest = v;
}
return largest;
}
public static void main(String[] args) {
System.out.println("Max: " + max(1, 11, 300, 2, 3));
}
}
可变参数特点总结:
- 位置要求:只能出现在方法参数列表的最后
- 语法格式:"..."位于变量类型和变量名之间,前后有无空格均可
- 实现机制:编译器为可变参数隐含创建数组
- 访问方式:在方法体中以数组形式访问可变参数
三、方法重载
动手动脑3:方法重载特性分析
示例代码:
public class MethodOverload {
public static void main(String[] args) {
System.out.println("The square of integer 7 is " + square(7));
System.out.println("The square of double 7.5 is " + square(7.5));
}
public static int square(int x) {
return x * x;
}
public static double square(double y) {
return y * y;
}
}
方法重载要点:
-
必要条件:
- 方法名相同
- 参数类型不同,或参数个数不同,或参数类型的顺序不同
-
非判断条件:方法的返回值类型
-
实践练习:
- 查看JDK中System.out.println()方法的重载形式
- 发现println方法有多个重载版本,分别处理不同数据类型
四、递归与递推
动手动脑4:n!的递归与递推实现对比
递归实现:
public class RecursionExample {
// 递归方式计算阶乘
public static long factorialRecursive(int n) {
if (n == 0 || n == 1) {
return 1; // 递归结束条件
}
return n * factorialRecursive(n - 1); // 自己调用自己
}
}
递推实现:
public class IterationExample {
// 递推方式计算阶乘
public static long factorialIterative(int n) {
long result = 1;
for (int i = 1; i <= n; i++) {
result *= i; // 从前到后逐步计算
}
return result;
}
}
递归编程模式总结:
- 递归头:函数开头必须判断递归结束条件
- 递归体:至少有一句"自己调用自己"
- 控制变量:必须有控制递归终结的参数变量
递归 vs 递推对比:
| 特性 | 递归 | 递推 |
|---|---|---|
| 执行方向 | 由后至前再回来 | 从前到后 |
| 实现方式 | 函数自我调用 | 循环语句 |
| 内存使用 | 栈空间消耗大 | 栈空间消耗小 |
| 代码可读性 | 更符合数学思维 | 更直观易懂 |
五、大数字与浮点数处理
动手动脑5:大整数阶乘计算
问题现象:
使用int或long类型计算较大数的阶乘时会出现负数结果
问题根源:
- int类型:32位,最大值2,147,483,647
- long类型:64位,最大值9,223,372,036,854,775,807
- 数值超出范围时发生二进制截断
解决方案:使用BigInteger类
import java.math.BigInteger;
public class BigNumberExample {
public static BigInteger calculateBigFactorial(int n) {
if (n == 0 || n == 1) {
return BigInteger.valueOf(1);
}
return BigInteger.valueOf(n).multiply(calculateBigFactorial(n - 1));
}
}
动手动脑6:浮点数精度比较
问题代码:
double i = 0.0001;
double j = 0.00010000000000000001;
System.out.println(i == j); // 输出:true
正确比较方法:
// 比较两个浮点数的差值是否在允许范围内
public static boolean doubleEquals(double a, double b, double epsilon) {
return Math.abs(a - b) < epsilon;
}
// 使用示例
if (doubleEquals(i, j, 1e-10)) {
System.out.println("在精度范围内相等");
} else {
System.out.println("不相等");
}
六、课后实验项目
实验项目:四则运算题目生成器
阶段1要求:
花二十分钟写一个能自动生成30道小学四则运算题目的"软件"
基础实现思路:
public class ArithmeticGenerator {
private Random random = new Random();
public void generateQuestions(int count) {
for (int i = 0; i < count; i++) {
int num1 = random.nextInt(100);
int num2 = random.nextInt(100);
char operator = getRandomOperator();
System.out.println((i+1) + ". " + num1 + " " + operator + " " + num2 + " = ");
}
}
private char getRandomOperator() {
char[] operators = {'+', '-', '×', '÷'};
return operators[random.nextInt(operators.length)];
}
}
阶段2进阶要求:
-
题目质量:
- 避免重复题目
- 减法不允许出现负数
- 乘法结果不允许出现四位数
- 除法必须整除不允许出现小数
-
功能扩展:
- 实现在线实时答题
- 统计显示错题数和正确率
- 增加倒计时功能
方法设计建议:
public class AdvancedArithmeticTest {
// 检查题目是否重复
public static boolean isDuplicate(String question, Set<String> existingQuestions) {
return existingQuestions.contains(question);
}
// 验证减法结果非负
public static boolean isValidSubtraction(int a, int b) {
return a >= b;
}
// 验证乘法结果不超过四位数
public static boolean isValidMultiplication(int a, int b) {
return a * b < 10000;
}
// 验证除法可以整除
public static boolean isValidDivision(int a, int b) {
return b != 0 && a % b == 0;
}
}
七、学习总结与最佳实践
代码仓库建设
- 分类整理:按功能模块分类存储代码片段
- 注释完善:为每个方法添加详细的使用说明
- 测试用例:为重要方法编写测试代码
- 文档配套:建立配套的使用文档和示例
开发效率提升
- 避免重复造轮子:充分利用已有代码资源
- 方法设计原则:单一职责、参数验证、异常处理
- 递归使用场景:树形结构、分治算法、动态规划
- 大数处理:金融计算、科学运算等场景使用BigDecimal/BigInteger
问题解决思路
- 理解问题本质:如整数溢出、浮点精度等根本原因
- 选择合适的工具:根据需求选择递归或递推实现
- 边界条件处理:特别注意递归结束条件和数值边界
- 性能与可读性平衡:在保证正确性的前提下优化代码
附录:完整代码示例
完整的四则运算题目生成器
import java.util.*;
public class CompleteArithmeticGenerator {
private Random random = new Random();
private Set<String> generatedQuestions = new HashSet<>();
public void generateAdvancedQuestions(int count) {
generatedQuestions.clear();
for (int i = 0; i < count; i++) {
String question = generateValidQuestion();
System.out.println((i+1) + ". " + question);
}
}
private String generateValidQuestion() {
String question;
do {
int num1 = random.nextInt(100) + 1;
int num2 = random.nextInt(100) + 1;
char operator = getRandomOperator();
// 根据运算符进行验证
switch (operator) {
case '-':
if (!isValidSubtraction(num1, num2)) {
// 确保被减数大于等于减数
int temp = num1;
num1 = Math.max(num1, num2);
num2 = Math.min(temp, num2);
}
break;
case '×':
if (!isValidMultiplication(num1, num2)) {
// 调整数值使乘积不超过四位数
num1 = random.nextInt(100) + 1;
num2 = random.nextInt(100) + 1;
continue;
}
break;
case '÷':
if (!isValidDivision(num1, num2)) {
// 调整数值使能够整除
num2 = random.nextInt(20) + 1;
num1 = num2 * (random.nextInt(50) + 1);
}
break;
}
question = num1 + " " + operator + " " + num2 + " = ";
} while (generatedQuestions.contains(question));
generatedQuestions.add(question);
return question;
}
private char getRandomOperator() {
char[] operators = {'+', '-', '×', '÷'};
return operators[random.nextInt(operators.length)];
}
private boolean isValidSubtraction(int a, int b) {
return a >= b;
}
private boolean isValidMultiplication(int a, int b) {
return a * b < 10000;
}
private boolean isValidDivision(int a, int b) {
return b != 0 && a % b == 0;
}
public static void main(String[] args) {
CompleteArithmeticGenerator generator = new CompleteArithmeticGenerator();
generator.generateAdvancedQuestions(30);
}
}

浙公网安备 33010602011771号