java - 从语义上比较不同类型的数字

标签 java numbers comparison comparator comparable

假设我有三个数字:

Comparable n1 = new Integer(432);
Comparable n2 = new Long(40);
Comparable n3 = new Double(500.12);

我想通过Comparable接口(interface)比较这些数字。但是,这会导致 ClassCastException

n1.compareTo(n2);

有没有办法(实用函数、外部库……)来比较不同类型的数字?在上面的示例中,从语义上看,数字 n2 小于 n1,并且 n1 小于 n3

在代码中,我不知道数字的具体类型。因此,我依赖 Comparable 接口(interface)。

最佳答案

first answer完全正确地解释了为什么会出现 ClassCastException - Comparable 接口(interface)是通用的,只能用于相同具体类型的对象。

可能还有其他方法可以解决您的问题:

基元及其对象包装器

如果您确定所有数字都是基元(int、long、float、double)或代表基元的类的对象(Integer、Long、Float、Double) code>),那么您可以使用普通的比较运算符,例如与 n1.compareTo(n2);

等价
int b = n1 > n2 ? 1 : (n1 < n2 ? -1 : 0);

Number 的子类

如果您确定所有变量都是扩展Number的类,即AtomicInteger、AtomicLong、BigDecimal、BigInteger、Byte、Double、Float、Integer、Long、Short,您可以使用以下内容:

    private int compareNumbers(Number n1, Number n2)
    {
        Double n2c = n2.doubleValue();
        Double n1c = n1.doubleValue();

        return n1c.compareTo(n2c);
    }

    public static void main (String[] args)
    {
        Integer n1 = new Integer(432);
        Long n2 = new Long(40);
        Double n3 = new Double(500.12);

        System.out.println(compareNumbers(n1,n2));
    }

编辑

为了回应与OP的评论讨论 - 我们注意到,如果比较两个BigDecimal<,使用Double作为Number比较的基类可能会给出虚假的相等性BigInteger 数字超出了 Double 范围(因此 .doubleValue() 返回 Double.POSITIVE_INFINITY > 或 Double.NEGATIVE_INFINITY(视情况而定)

如果这是一个问题,compareNumbers() 可以更改如下:

    private int compareNumbers(Number n1, Number n2)
    {
        BigDecimal n2c = new BigDecimal(n2.toString());
        BigDecimal n1c = new BigDecimal(n1.toString());

        return n1c.compareTo(n2c);
    }

/编辑

实现 Comparable 但不扩展 Number

如果您甚至不能确定您的变量扩展了 Number,并且您可能正在使用表示数字的类处理变量,实现 Comparable,但不扩展 Number,我相信您只能在以下情况下比较参数他们属于同一类(Class)。在这种情况下,这应该可行,但我无法真正想象用例:

    Comparable n1 = new WierdNonNumberExtendingInteger(432);
    Comparable n2 = new WierdNonNumberExtendingLong(40);
    Comparable n3 = new WierdNonNumberExtendingDouble(500.12);

    Integer b =  null;
    if (n1.getClass().isInstance(n2))
    {
       b =  n1.compareTo(n2);
    }
    else
    {
       System.err.println("Can't compare apples and oranges");
       System.err.print("You tried to compare " + n1.getClass().getSimpleName());
       System.err.print(" with " + n2.getClass().getSimpleName());
    }

    System.out.println(b);

关于java - 从语义上比较不同类型的数字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27922472/

相关文章:

java - 给定一个 Calendar 实例,确定它是否已经过一小时的最简单方法是什么?

java - Tomcat 上的 j_security_check

java - 使用 java.nio.Files 或 java.io 类创建 java.io.BufferedWriter

string - 系统级别的整数和字符串比较

c++ - 重载 *= 用于复数

java - 如何制作一个Java猜谜游戏程序

javascript - 将js中的单词与非常奇怪的结果进行比较

java - Web 应用程序中的 context.xml 与 web.xml

java - 从命令提示符获取 java 程序中的非初始参数用户输入

regex - 提取包含一个或多个数字的文件名,然后将 cat 内容提取到输出文件