1

我正在尝试多态地使用 java.lang.Number:我有一个列表,其中放置了多个 Double、Integer 等实例,然后我想对它们进行多态算术运算(例如,每个数字加倍)。

我们没有 java.lang.Number 的自动装箱能力,而且我没有找到更好的方法来做到这一点,而不是示例源代码中的 - 不是那么多态 - 方法 multiply(Number n, int factor)接下来......通过这个实现,我们需要一个用于每个算术运算(加法,减法等)的方法


编辑 - 增强问题:如果我们从抽象的角度考虑 java.lang.Number,我们会认为任何数字都可以是算术运算的一部分,但它似乎并不存在一种简单的加/减/将 / 等 x 乘以数字列表,与它们的类型无关(整数、双精度、短 ...)


有更好的想法吗?提前致谢 ;)

示例源代码:

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;
    }
4

3 回答 3

1

我真的不明白为什么你不能使用 Number.doubleValue() 来做数学。我错过了什么?

例如

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

编辑添加:

@amano 澄清说他想更改现有 List 中的 Objects,同时保持它们的原始 type。我想我的第一个问题是,“为什么”?他的示例使用Byte. 将一个字节乘以大多数任何东西通常都会导致溢出。将 a 添加double到 anInteger将失去精度。integer从 a中减去aByte并将结果强制返回到 aByte通常会给出错误的结果。将整数除以整数通常会丢失精度(例如 3/2 = 1,而不是 1.5)。除非您需要绝对完美的精度(例如,为了钱),否则数学上最正确的解决方案是始终转换为双精度并将结果保持为双精度。是的,会有轻微的舍入错误,但没有像 3/2 = 1 或 (byte)23 - 665544 = 谁知道字节是什么?

为什么你会关心这个值最初是一个字节?当你想把它当作一个数字来对待时?数字输入,数字(技术上,双打)输出。

所以我理解得更好,但我仍然缺少一些东西。值保持相同原始类型的约束会导致不准确,以及更多的工作。 如果您坚持该约束,是的,您将不得不做很多instanceof.

于 2012-08-17T02:39:02.793 回答
0

镜像 Number 类层次结构:编写您自己的 NumberWrapper 类,并为每个基元编写一个知道实际类型并可以执行正确操作的专用类。

深夜编辑:当然,您总是可以只使用 Number#doubleValue() 并且只使用双打进行处理......

于 2012-08-17T01:33:55.487 回答
0

我同意塔索斯的观点,除了写所有这些听起来很乏味......

而不是重新发明轮子,你可以尝试使用这样的东西:http ://code.google.com/p/generic-java-math/ 。我自己从来没有使用过这个库,但它看起来像你需要的。

于 2012-08-17T02:05:46.840 回答