Question

Say we got 2 ordered collections of numbers. We want to compute the arithmetic difference element by element. I think we need to use List of Number in order to model the idea of 'ordered collection of numbers'. The problem is that the arithmetic difference (a banal '-' like in 3-2) is not defined for Number. I can cast everything to Double, but I'd rather prefer a clean solution.

public static <E extends Number> List<E> listDifferenceElementByElement(List<E> minuend, List<E> subtrahend) throws Exception {
    if (minuend.size() != subtrahend.size()) {
        throw new Exception("Collections must have the same size"); //TODO: better exception handling
    }
    List<E> difference = new ArrayList<E>();
    int i = 0;
    for (E currMinuend : minuend) {
        difference.add(currMinuend-subtrahend.get(i)); //error: The operator - is undefined for the argument type(s) E, E
        i++;
    }
    return difference;
}

Any idea?

Was it helpful?

Solution

Since Number does not provide any subtract method, you can't do it simply. The alternatives I can think of are:

  1. use the provided doubleValue() method, and return a double, but you could lose precision if the lists contain BigDecimal for example.
  2. have one method per available Number subclass, but it could create a lot of duplicated code...
  3. restrict the type to whatever makes sense (say double if precision does not matter too much or BigDecimal if it does), which is a subcase of (2).

Option 2 could be implemented like by replacing difference.add(currMinuend-subtrahend.get(i)); by difference.add(subtract(currMinuend, subtrahend.get(i)));

Then it's only a matter of writing 10 subtract methods:

private static int subtract(int a, int b) { return a - b; }
private static double subtract(double a, double b) { return a - b; }
private static BigDecimal subtract(BigDecimal a, BigDecimal b) { return a.subtract(b); }

etc.

OTHER TIPS

This is nothing to do with generics, arrays, etc. Java doesn't allow operator overloading, so you cannot subtract 2 numbers with -, and the Number class doesn't define any methods for numeric operations. It can't because it might be operating on different subclasses (e.g. Integer.subtract(Double)) which would make defining the return type impossible.

You will need to use intrinsic types or BigDecimal (or similar) here, I think.

If you want to work with many arithmetic type, you can set your list as a generic list, then add the handler when you want to find the difference between them. The handler check if the type is instance of Double, Integer, or anything you want. Based on each type, you could compute the difference.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top