在 Java 中比较数字

2022-09-01 18:05:35

在Java中,所有数字类型都从java.lang.Number扩展而来。有一个如下的方法会是一个好主意:

public boolean areEqual(Number first, Number second) {
    if (first != null && second != null) {
        return first.equals(second);
    }
}

我担心双2.00000不等于int 2的情况。这些是否由内置的 equals 处理?如果没有,有没有办法用java编写一个简单的数字比较函数?(外部库,如apache commons是可以的)


答案 1

A 永远不会对 .此外,a 与 .DoubleequalsIntegerdoubleDouble

Java 具有基元类型和引用类型。Java 中真正的数值类型不会从 扩展而来,因为它们是基元。Number

您可能要考虑一个不混合类型的系统,因为这通常会给隐式/显式转换带来很多麻烦,这些转换可能会/可能不会丢失信息等。

相关问题

开 vs :intInteger

比较:Number

另请参见


关于混合类型计算

混合类型计算是Java益智游戏中至少4个谜题的主题。

以下是各种摘录:

通常最好避免混合类型计算[...],因为它们本质上是令人困惑的[...]这一点在条件表达式中最为明显。混合类型比较总是令人困惑的,因为系统被迫提升一个操作数以匹配另一个操作数的类型。转换是不可见的,可能无法产生您期望的结果

处方:避免混合积分和浮点类型的计算。与浮点相比,首选积分算术。


答案 2

要比较Java中的两个数字,您可以使用 from .BigDecimal可以容纳从短到双或BigInteger的所有内容,因此它是完美的类。compareToBigDecimal

所以你可以尝试写这样的东西:

public int compareTo(Number n1, Number n2) {
    // ignoring null handling
    BigDecimal b1 = BigDecimal.valueOf(n1.doubleValue());
    BigDecimal b2 = BigDecimal.valueOf(n2.doubleValue());
    return b1.compareTo(b2);
}

这肯定不是性能的最佳方法。到目前为止,以下测试是有效的,至少在JDK7中是这样:

assertTrue(compareTo(new Integer(1), new Integer(2)) == -1);
assertTrue(compareTo(new Integer(1), new Double(2.0)) == -1);
assertTrue(compareTo(new Integer(1), new Double(Double.MAX_VALUE)) == -1);
assertTrue(compareTo(new Integer(1), new Double(Double.MIN_VALUE)) == 1);
assertTrue(compareTo(new Integer(1), new Double(1.000001)) == -1);
assertTrue(compareTo(new Integer(1), new Double(1.000)) == 0);
assertTrue(compareTo(new Integer(1), new Double(0.25*4)) == 0);
assertTrue(compareTo(new Integer(1), new AtomicLong(1)) == 0);

推荐