Java Number & Math 类详解

在 Java 编程中,Number类和Math类是处理数值计算和数据类型转换的核心工具。本文将深入剖析这两个类的功能、方法及应用场景,并通过示例代码演示其使用技巧。

一、Number 类:数值包装类的抽象基类

1. 类层次结构

Number是一个抽象类,作为以下包装类的父类:

  • 基本数值类型:ByteShortIntegerLongFloatDouble
  • 特殊数值类型:BigIntegerBigDecimal(不可变的任意精度数值)

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.RandomThreadLocalRandom

五、典型应用场景

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 类:封装常用数学运算,静态方法直接调用
  • 高精度计算:BigIntegerBigDecimal处理任意精度需求
  • 性能优化:避免不必要的装箱拆箱,注意浮点数精度问题

扩展工具

  • Apache Commons Math:提供更丰富的数学工具(如统计、线性代数)
  • Java 8+ Stream API:结合IntStreamDoubleStream进行高效数值处理
  • 第三方库:如 Guava 的IntMathDoubleMath提供更多实用方法

掌握NumberMath类的使用,是 Java 开发者处理数值计算的基础。合理选择数据类型和运算方法,既能保证代码的正确性,又能提升系统的性能。

posted on 2025-06-22 20:48  coding博客  阅读(95)  评论(0)    收藏  举报