比较Java中的数字

时间:2010-07-09 16:05:15

标签: java comparison numbers

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

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

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

8 个答案:

答案 0 :(得分:38)

Double 从不 equalsInteger。此外,doubleDouble不同。

Java具有原始类型和引用类型。 Java中真正的数字类型不会从Number扩展,因为它们是原语。

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

相关问题

int vs Integer上:

Number比较:

另见


关于混合型计算

混合型计算是Java Puzzlers中至少4个谜题的主题。

以下是各种摘录:

  

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

     

处方:避免混合使用整数和浮点类型的计算。首选积分算术到浮点。

答案 1 :(得分:11)

我知道这是一个古老的话题,但...... 要比较Java中的两个数字,可以使用BigDecimal中的compareTo方法。 BigDecimal可以容纳从short到double或BigInteger的所有内容,因此它是完美的类。

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

public int compareTo(Number n1, Number n2) {
    // ignoring null handling
    BigDecimal b1 = new BigDecimal(n1.doubleValue());
    BigDecimal b2 = new BigDecimal(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);

答案 2 :(得分:6)

您建议的具体方法会失败,因为它使用的是继承自equals()的{​​{1}}。也就是说,它会检查Object 对象是否相同,而不是它们的是否相同。

如果那只是一个说明性的例子,我会更新我的答案。

polygene的答案实际上几乎覆盖了我前进的基础。您可能也对此问题感兴趣:Why doesn't java.lang.Number implement Comparable?

答案 3 :(得分:4)

如果您想知道对象引用是否相同,那么现有方法符合要求。代表Double的{​​{1}}和代表2.0的{​​{1}}绝对是不同的对象,并且在一般意义上肯定不可互换。

如果您只是想知道数值是否相同,可以使用Number.doubleValue()方法将两个数字转换为双数,然后将这些数字进行比较(可能允许较小的容差,因为大多数数字表示不完整,例如1.99999999996583,应该是2,取决于中间计算步骤)。如下所示:

Integer

答案 4 :(得分:1)

比较整数和浮点之间的数字几乎不会产生你想要的东西。但是,如果这是一个简单的练习,您可以通过比较值的字符串表示来实现比较,如:

public boolean areEqual(Number first, Number second) {
    if (first == null) {
        return second == null;
    }
    if (second == null) {
        return false;
    }

    return first.toString().equals(second.toString());
}

答案 5 :(得分:1)

在几个回复的切线上,我可以建议不要写下这样的内容:

boolean compare(Object o1, Object o2)
{
  if (o1==null)
    return o2==null;
  if (o2==null)
    return false;
  return o1.equals(o2);
}

它更简洁,我相信写得更有效率:

boolean compare(Object o1, Object o2)
{
  return o1==o2 || o1!=null && o2!=null && o1.equals(o2);
}

如果两者都为null,则o1 == o2将返回true。如果他们不是,但他们是同一个对象,那也没关系。

从技术上讲,对于大多数equals实现来说,o2!= null并不是必需的,但是如果你真的如此通用,就像在上面的例子中那样对象,你当然不会知道每个覆盖是如何写的

答案 6 :(得分:0)

    public static boolean compareTo(Number d1, Number d2) {
    Double num1=d1.doubleValue();
    Double num2=d2.doubleValue();
     if(Double.compare(num1, num2)==0)
         return true;
     else
         return false;

}

OR
    public static boolean compareTo(Number d1, Number d2) {
     if(d1.doubleValue()==d2.doubleValue())
         return true;
     else
         return false;

}

答案 7 :(得分:-1)

你不能打电话

number.equals(number2);

因为,如果number是一个Double而number2是一个Integer,它们将不属于同一个类,你会得到一个异常,告诉你这个事实。

您可以自己编写一个接受Number对象的比较类,但是您必须考虑Number的不同子类