概述
java.lang.Double
类提供了三个静态工具方法:
Double.sum(double a, double b)
Double.max(double a, double b)
Double.min(double a, double b)
这些方法用于对两个 double
值执行基本的数学运算:求和、取最大值、取最小值。它们是 Java 标准库中处理浮点数运算的便捷工具。
本文将全面介绍这三个方法的定义、功能、示例、使用技巧、常见错误、注意事项、最佳实践与性能优化,并进行总结,助你快速掌握并高效实践。
一、方法定义
1. Double.sum(double a, double b)
public static double sum(double a, double b)
- 功能:返回两个
double
值的和a + b
。 - 返回值:
double
,即a + b
的结果。 - 异常:无
2. Double.max(double a, double b)
public static double max(double a, double b)
- 功能:返回两个
double
值中的较大者。 - 返回值:
double
- 特殊规则:
- 如果任一参数为
NaN
,返回NaN
0.0
和-0.0
:max(0.0, -0.0)
返回0.0
- 如果任一参数为
- 异常:无
3. Double.min(double a, double b)
public static double min(double a, double b)
- 功能:返回两个
double
值中的较小者。 - 返回值:
double
- 特殊规则:
- 如果任一参数为
NaN
,返回NaN
0.0
和-0.0
:min(0.0, -0.0)
返回-0.0
- 如果任一参数为
- 异常:无
自版本:JDK 1.5
🔗 相关方法:
Math.sum()
,Math.max()
,Math.min()
(功能相同)Integer.sum/max/min
,Long.sum/max/min
等
二、功能说明
方法 | 功能 | 特殊行为 |
---|---|---|
sum(a, b) |
a + b |
标准浮点加法 |
max(a, b) |
a > b ? a : b |
NaN 优先,0.0 > -0.0 |
min(a, b) |
a < b ? a : b |
NaN 优先,-0.0 < 0.0 |
⚠️ 注意:
Double.sum(a, b)
本质上就是a + b
,不提供精度增强或溢出保护。
三、示例代码
public class DoubleMathExample {
public static void main(String[] args) {
double a = 10.5;
double b = 20.3;
double nan = Double.NaN;
double posInf = Double.POSITIVE_INFINITY;
double negInf = Double.NEGATIVE_INFINITY;
// 1. Double.sum()
System.out.println("sum(10.5, 20.3) = " + Double.sum(a, b)); // 30.8
System.out.println("sum(1.0, POSITIVE_INFINITY) = " + Double.sum(1.0, posInf)); // Infinity
System.out.println("sum(NaN, 5.0) = " + Double.sum(nan, 5.0)); // NaN
// 2. Double.max()
System.out.println("max(10.5, 20.3) = " + Double.max(a, b)); // 20.3
System.out.println("max(-5.0, -10.0) = " + Double.max(-5.0, -10.0)); // -5.0
System.out.println("max(0.0, -0.0) = " + Double.max(0.0, -0.0)); // 0.0
System.out.println("max(NaN, 10.0) = " + Double.max(nan, 10.0)); // NaN
System.out.println("max(POSITIVE_INFINITY, NEGATIVE_INFINITY) = " +
Double.max(posInf, negInf)); // Infinity
// 3. Double.min()
System.out.println("min(10.5, 20.3) = " + Double.min(a, b)); // 10.5
System.out.println("min(-5.0, -10.0) = " + Double.min(-5.0, -10.0)); // -10.0
System.out.println("min(0.0, -0.0) = " + Double.min(0.0, -0.0)); // -0.0
System.out.println("min(NaN, 10.0) = " + Double.min(nan, 10.0)); // NaN
System.out.println("min(POSITIVE_INFINITY, NEGATIVE_INFINITY) = " +
Double.min(posInf, negInf)); // -Infinity
// 对比 a + b
System.out.println("a + b = " + (a + b)); // 30.8
System.out.println("Double.sum(a,b) = " + Double.sum(a, b)); // 30.8
}
}
输出结果:
sum(10.5, 20.3) = 30.8
sum(1.0, POSITIVE_INFINITY) = Infinity
sum(NaN, 5.0) = NaN
max(10.5, 20.3) = 20.3
max(-5.0, -10.0) = -5.0
max(0.0, -0.0) = 0.0
max(NaN, 10.0) = NaN
max(POSITIVE_INFINITY, NEGATIVE_INFINITY) = Infinity
min(10.5, 20.3) = 10.5
min(-5.0, -10.0) = -10.0
min(0.0, -0.0) = -0.0
min(NaN, 10.0) = NaN
min(POSITIVE_INFINITY, NEGATIVE_INFINITY) = -Infinity
a + b = 30.8
Double.sum(a,b) = 30.8
四、使用技巧
1. Double.sum()
在 Stream
中的聚合
List<Double> numbers = Arrays.asList(1.1, 2.2, 3.3, 4.4);
double sum = numbers.stream()
.mapToDouble(Double::doubleValue)
.reduce(0.0, Double::sum); // 等价于 .sum()
2. Double.max()
/ Double.min()
用于 Stream
聚合
Optional<Double> max = numbers.stream().max(Double::max); // ❌ 错误!
// 正确写法:
Optional<Double> max = numbers.stream().max(Double::compare); // 或 Double::compareTo
// 或使用原始流
double maxValue = numbers.stream().mapToDouble(Double::doubleValue).max().orElse(0.0);
⚠️ 注意:
Double.max()
是二元函数,不能直接用于Stream.max()
,后者需要Comparator
。
3. 与 Math
类方法等价
// 这些调用完全等价
double s1 = Double.sum(a, b);
double s2 = Math.fma(a, 1, b); // 不推荐
double s3 = a + b; // 最直接
double m1 = Double.max(a, b);
double m2 = Math.max(a, b); // 完全相同
4. 处理 -0.0
的符号敏感场景
System.out.println(Double.max(0.0, -0.0)); // 0.0
System.out.println(Double.min(0.0, -0.0)); // -0.0
// 用于需要保留符号信息的科学计算
五、常见错误
错误 | 说明 |
---|---|
认为 Double.sum() 比 + 更安全或精确 |
实际上就是 a + b ,无区别 |
在 Stream.max() 中使用 Double::max |
类型不匹配,需要 Comparator<Double> |
忽略 NaN 的传播 |
max(NaN, x) 返回 NaN ,可能污染结果 |
混淆 0.0 和 -0.0 的行为 |
max 返回 0.0 ,min 返回 -0.0 |
示例错误:
// ❌ 无法编译
Optional<Double> wrongMax = list.stream().max(Double::max);
// ✅ 正确
Optional<Double> correctMax = list.stream().max(Double::compare);
六、注意事项
- ✅
Double.sum(a, b)
等价于a + b
:无性能或精度优势。 - ⚠️
max/min
会传播NaN
:任一参数为NaN
,结果为NaN
。 - ✅ 正确处理
±0.0
:max(0.0, -0.0) = 0.0
,min(0.0, -0.0) = -0.0
。 - ✅ 支持无穷大:
max(1.0, ∞) = ∞
,min(1.0, -∞) = -∞
。 - ✅ 无异常抛出:所有输入都合法。
- ✅ 线程安全:静态无状态方法。
七、最佳实践
优先使用
+
、Math.max()
、Math.min()
// ✅ 推荐:更常见,语义清晰 double sum = a + b; double max = Math.max(a, b); double min = Math.min(a, b); // ❌ 不必要 double sum = Double.sum(a, b);
在
Stream.reduce()
中使用Double::sum
double total = stream.mapToDouble(...).reduce(0.0, Double::sum);
明确处理
NaN
和±0.0
if (Double.isNaN(a) || Double.isNaN(b)) { // 处理 NaN } else { double result = Double.max(a, b); }
使用
Comparator
进行排序list.sort(Double::compare); // 而非自定义 max/min
八、性能优化
性能与直接运算相同
Double.sum(a, b)
→ 编译为dadd
字节码,与a + b
完全一致。Double.max/min
→ 内部使用条件判断,性能与手动if
相当。
JVM 会内联这些方法
- 无需担心调用开销。
避免在热点路径重复调用
// ❌ if (Double.max(a, b) > threshold) { ... } process(Double.max(a, b)); // ✅ double max = Double.max(a, b); if (max > threshold) { ... } process(max);
九、总结
方法 | 等价操作 | 主要用途 | 建议 |
---|---|---|---|
Double.sum(a, b) |
a + b |
Stream.reduce() |
优先用 + |
Double.max(a, b) |
Math.max(a, b) |
二元最大值 | 优先用 Math.max |
Double.min(a, b) |
Math.min(a, b) |
二元最小值 | 优先用 Math.min |
核心要点:
- ✅
Double.sum(a, b)
就是a + b
,无额外功能。 - ✅
max/min
正确处理NaN
、±0.0
、±∞
。 - ⚠️
NaN
会传播:max(NaN, x) = NaN
。 - 🔄
0.0
和-0.0
有区别:max
返回0.0
,min
返回-0.0
。 - 🚫 不能直接用于
Stream.max()
,需要Comparator
。 - 🏁 推荐优先使用
Math.max/min
和+
操作符,更直观。