Java Number & Math 类详解
在 Java 编程中,Number类和Math类是处理数值计算和数据类型转换的核心工具。本文将深入剖析这两个类的功能、方法及应用场景,并通过示例代码演示其使用技巧。
一、Number 类:数值包装类的抽象基类
1. 类层次结构
Number是一个抽象类,作为以下包装类的父类:
基本数值类型:Byte、Short、Integer、Long、Float、Double
特殊数值类型:BigInteger、BigDecimal(不可变的任意精度数值)
2. 核心方法
所有Number子类必须实现以下抽象方法:
byte byteValue(); // 转换为byte类型
short shortValue(); // 转换为short类型
int intValue(); // 转换为int类型
long longValue(); // 转换为long类型
float floatValue(); // 转换为float类型
double doubleValue(); // 转换为double类型
3. 自动装箱与拆箱
Java 5 引入的特性,简化基本类型与包装类的转换:
// 自动装箱:基本类型 → 包装类
Integer num = 10; // 等价于 Integer num = Integer.valueOf(10);
// 自动拆箱:包装类 → 基本类型
int value = num; // 等价于 int value = num.intValue();
4. 数值比较
包装类重写了equals()和compareTo()方法:
Integer a = 1000;
Integer b = 1000;
System.out.println(a == b); // 输出: false(引用比较)
System.out.println(a.equals(b)); // 输出: true(值比较)
// compareTo返回值:-1(小于)、0(等于)、1(大于)
System.out.println(a.compareTo(b)); // 输出: 0
二、Math 类:数学运算工具库
1. 类特性
静态类:所有方法和字段都是静态的,无需实例化
不可变:所有方法不修改输入参数,返回新结果
高精度:基于 IEEE 754 标准实现浮点数运算
2. 常用常量
Math.PI; // 圆周率 π ≈ 3.141592653589793
Math.E; // 自然对数底数 e ≈ 2.718281828459045
3. 基本数值运算
// 绝对值
Math.abs(-10); // 返回: 10
// 最大值/最小值
Math.max(5, 10); // 返回: 10
Math.min(5.5, 3.2); // 返回: 3.2
// 四舍五入
Math.round(3.7); // 返回: 4 (long类型)
Math.round(3.2f); // 返回: 3 (int类型)
4. 幂与对数运算
// 幂运算:a^b
Math.pow(2, 3); // 返回: 8.0
// 平方根/立方根
Math.sqrt(16); // 返回: 4.0
Math.cbrt(27); // 返回: 3.0
// 自然对数与指数
Math.log(Math.E); // 返回: 1.0
Math.exp(2); // 返回: e² ≈ 7.389
5. 三角函数与角度转换
// 三角函数(参数为弧度)
Math.sin(Math.PI/2); // 返回: 1.0
Math.cos(0); // 返回: 1.0
Math.tan(Math.PI/4); // 返回: 1.0
// 弧度与角度转换
Math.toRadians(180); // 返回: π (3.14159...)
Math.toDegrees(Math.PI); // 返回: 180.0
6. 随机数生成
// 生成 [0, 1) 之间的随机double值
double random = Math.random(); // 例如: 0.42356789
// 生成 [min, max) 之间的随机整数
int min = 10, max = 20;
int randInt = min + (int)(Math.random() * (max - min));
三、高精度计算:BigInteger 与 BigDecimal
1. BigInteger:任意精度整数
// 创建方式
BigInteger a = new BigInteger("12345678901234567890");
BigInteger b = BigInteger.valueOf(1000);
// 基本运算
BigInteger sum = a.add(b); // 加法
BigInteger product = a.multiply(b); // 乘法
BigInteger mod = a.mod(b); // 取模
2. BigDecimal:任意精度小数
// 创建方式(避免使用double构造函数,存在精度问题)
BigDecimal a = new BigDecimal("0.1");
BigDecimal b = BigDecimal.valueOf(0.2);
// 精确计算
BigDecimal sum = a.add(b); // 0.3
BigDecimal quotient = a.divide(b, 10, RoundingMode.HALF_UP); // 0.5000000000
四、性能优化与注意事项
1. 避免不必要的装箱拆箱
// 低效:每次循环都进行装箱拆箱
Long sum = 0L;
for (long i = 0; i < Integer.MAX_VALUE; i++) {
sum += i; // 等价于 sum = Long.valueOf(sum.longValue() + i);
}
// 高效:使用基本类型
long sum = 0;
for (long i = 0; i < Integer.MAX_VALUE; i++) {
sum += i;
}
2. 浮点数精度问题
// 不精确计算示例
System.out.println(0.1 + 0.2); // 输出: 0.30000000000000004
// 解决方案:使用BigDecimal
BigDecimal a = new BigDecimal("0.1");
BigDecimal b = new BigDecimal("0.2");
System.out.println(a.add(b)); // 输出: 0.3
3. Math 类方法的性能差异
Math.round()比手动计算更快
避免在高性能场景下使用Math.random(),考虑java.util.Random或ThreadLocalRandom
五、典型应用场景
1. 金融计算
// 精确计算货币金额
BigDecimal price = new BigDecimal("9.99");
BigDecimal quantity = new BigDecimal("3");
BigDecimal total = price.multiply(quantity);
System.out.println(total.setScale(2, RoundingMode.HALF_UP)); // 输出: 29.97
2. 科学计算
// 计算复利
double principal = 1000;
double rate = 0.05;
int years = 10;
double amount = principal * Math.pow(1 + rate, years);
System.out.println("复利总额: " + amount); // 输出: 1628.894626777041
3. 随机数应用
// 生成随机验证码
String chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
StringBuilder code = new StringBuilder();
for (int i = 0; i < 6; i++) {
int index = (int)(Math.random() * chars.length());
code.append(chars.charAt(index));
}
System.out.println("验证码: " + code); // 例如: K7D9A3
六、总结与扩展
核心要点
Number 类:提供基本数值类型的包装和类型转换能力
Math 类:封装常用数学运算,静态方法直接调用
高精度计算:BigInteger和BigDecimal处理任意精度需求
性能优化:避免不必要的装箱拆箱,注意浮点数精度问题
扩展工具
Apache Commons Math:提供更丰富的数学工具(如统计、线性代数)
Java 8+ Stream API:结合IntStream、DoubleStream进行高效数值处理
第三方库:如 Guava 的IntMath、DoubleMath提供更多实用方法
掌握Number和Math类的使用,是 Java 开发者处理数值计算的基础。合理选择数据类型和运算方法,既能保证代码的正确性,又能提升系统的性能。
posted on
2025-06-22 20:48
coding博客
阅读(19)
评论(0)
收藏
举报