Reputation: 11
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).
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.)
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...)
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;
}
Upvotes: 1
Views: 1195
Reputation: 15729
I really don't see why you can't use Number.doubleValue() and do the math. What am I missing?
e.g.
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. I guess my first question is, "why"? His example uses a Byte
. Multiplying a Byte times most anything will often result in an overflow. Adding a double
to an Integer
will lose precision. Subtracting an integer
from a Byte
and forcing the result back into a Byte
will usually give a wrong result. Dividing an Integer by an integer will usually lose precision (e.g. 3/2 = 1, not 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?
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
.
Upvotes: 1
Reputation: 16142
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.
Late night edit: of course, you could always just use Number#doubleValue() and do your processing only with doubles...
Upvotes: 0
Reputation: 1068
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/. I've never used this library myself but it looks like what you need.
Upvotes: 0