简体   繁体   English

如何多态使用java.lang.Number

[英]How to use java.lang.Number polymorphically

I'm trying to use java.lang.Number polymorphically: I have a List where I put multiple Double, Integer, etc. instances, and then I want to polymorphically do arithmetic operations on them (for example double every Number). 我正在尝试多态使用java.lang.Number:我有一个List,在其中放置了多个Double,Integer等实例,然后我想对它们进行多态算术运算(例如,对每个Number加倍)。

We don't have the auto-boxing ability with java.lang.Number and I'm not figuring out a better way to do this without the - not so polymorphic - method multiply(Number n, int factor) in the sample source code that follows... and with this implementation we would need a method for each arithmetic operation (add, subtract, etc.) 我们没有使用java.lang.Number进行自动装箱的功能,并且在示例源代码中没有-不是那么多态-方法multiple(Number n,int factor)的情况下,我也没有想出更好的方法来做到这一点随后...通过这种实现,我们将需要一个用于每个算术运算(加,减等)的方法。


EDIT - ENHANCE QUESTION: if we think on the java.lang.Number from a abstraction perspective, we would think that any Number can be part of arithmetic operations but yet again it doesn't seem to exist a simple way to add/subtract/multiply/etc x to a list of Number, independently of their type (Integer, Double, Short...) 编辑-增强问题:如果从抽象的角度考虑java.lang.Number,我们会认为任何Number都可以算术运算的一部分,但它似乎并不存在简单的加/减/方法。将x乘以/ etc到Number列表,而与数字的类型无关(Integer,Double,Short ...)


Any better ideias? 还有更好的想法吗? Thanks in advance ;) 提前致谢 ;)

Sample source code: 示例源代码:

public class NumberTest {

    private List<Number> list = new ArrayList<Number>();    

    public static void main(String args[]) {
        new NumberTest().start();

    }

    protected void start() {
        this.fillList();
        Number num;
        for (int i = 0; i < list.size(); i++) {
            num = this.multiply(list.get(i), 2);
            list.set(i, num);
        }

        System.out.println(this.toString());
    }

    private void fillList() {
        list.add(new Byte((byte) 12));
        list.add(new Short((short) 20));
        list.add(new Integer(30));
        list.add(new Long(40));
        list.add(new Float(50.123));
        list.add(new Double(60.123));
    }

    private Number multiply(Number n, int factor) {
        if (n instanceof Byte) {
            n = n.byteValue() * factor;
        } else if (n instanceof Short) {
            n = n.shortValue() * factor;
        } else if (n instanceof Integer) {
            n = n.intValue() * factor;
        } else if (n instanceof Long) {
            n = n.longValue() * factor;
        } else if (n instanceof Float) {
            n = n.floatValue() * factor;
        } else if (n instanceof Double) {
            n = n.doubleValue() * factor;
        }
        return n;
    }

    @Override
    public String toString() {
        String result = "";
        for (Number num : list) {
            result += num+"\n";
        }
        return result;
    }

I really don't see why you can't use Number.doubleValue() and do the math. 我真的不明白为什么不能使用Number.doubleValue()进行数学运算。 What am I missing? 我想念什么?

eg 例如

public Double multiply(Number n, double factor) {
   return new Double(n.getDoubleValue() * factor);
}

EDIT ADDED: 编辑已添加:

@amano has clarified that he wants to change the Objects in the existing List, while maintaining their original type . @amano已澄清,他想更改现有List中的Objects,同时保持其原始类型 I guess my first question is, "why"? 我想我的第一个问题是,“为什么”? His example uses a Byte . 他的示例使用Byte Multiplying a Byte times most anything will often result in an overflow. 大多数东西乘一个字节乘以通常会导致溢出。 Adding a double to an Integer will lose precision. Integer添加double精度将失去精度。 Subtracting an integer from a Byte and forcing the result back into a Byte will usually give a wrong result. Byte减去integer并将结果强制返回Byte通常会给出错误的结果。 Dividing an Integer by an integer will usually lose precision (eg 3/2 = 1, not 1.5). 将整数除以整数通常会失去精度(例如3/2 = 1,而不是1.5)。 Unless you need absolute perfect precision (say, for money) the most mathematically correct solution is to always convert to a double and keep the result as a double. 除非您需要绝对完美的精度(例如,为了钱),否则数学上最正确的解决方案是始终转换为双精度并保持结果为双精度。 Yes, there will be minor rounding errors but nothing like 3/2 = 1, or (byte)23 - 665544 = who knows what as a byte? 是的,会有一些较小的舍入错误,但是没有什么比3/2 = 1或(字节)23-665544 =谁知道字节是什么?

And why would you care that the value was originally a Byte? 您为什么还要关心该值最初是一个字节? When you make a big deal about wanting to treat it as a Number? 当您想将其视为数字时,有什么大不了的? Numbers in, Numbers (technically, Doubles) out. 数字输入,数字(技术上为双精度)输出。

So I understand better but I'm still missing something. 所以我理解得更好,但我仍然缺少一些东西。 The constraint that the values remain of the same original type causes inaccuracies, plus a lot more work. 值保持原始类型的约束会导致不准确,并增加了很多工作。 If you insist on that constraint, yes, you will have to do a lot of instanceof . 如果您坚持这种约束,是的,您将不得不做很多instanceof

Mirror the Number class hierarchy: write your own NumberWrapper class and for each primitive write a specialized class that knows the actual type and can perform the proper operations. 镜像Number类的层次结构:编写自己的NumberWrapper类,并为每个基元编写一个知道实际类型并可以执行适当操作的专门类。

Late night edit: of course, you could always just use Number#doubleValue() and do your processing only with doubles... 深夜编辑:当然,您始终可以只使用Number#doubleValue()并仅使用双打进行处理...

I agree with Tassos, except that writing all of that sounds quite tedious... 我同意塔索斯的看法,除了写所有这些听起来很乏味...

Instead of reinventing the wheel, you might try using something like this: http://code.google.com/p/generic-java-math/ . 您可以尝试使用类似以下内容的方法,而不是重新发明轮子: http : //code.google.com/p/generic-java-math/ I've never used this library myself but it looks like what you need. 我自己从未使用过此库,但看起来像您需要的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM