0

I cannot figure out what is happening here. I'm trying to create a general max method to handle various array types, but I don't understand where I am trying to cast Integer to Box. I am very new here, so any help would be appreciated.

The one thing that I can thing of is the Object max = 0 line that holds that max value. I chose Object because it can hold anything (as far as I know), but setting it to 0 at first doesn't make much sense, but I can't think of any other way that would work.

EDIT: One more thing, when i test it with the Doubles, it throws the same error, but with java.lang.Integer cannot be cast to java.lang.Double but this, again, doesn't make sense to me. Where am I trying to cast these things? It must be max?

Here is my code:

package q3;

import java.util.Random;

public class Biggest {

public static Object max(Comparable[] x) {

    Object max = 0;

    for (int i = 0; i < x.length; i++) {
        System.out.println("Comparing " + x[i] + " to " + max);
        if (x[i].compareTo(max) > 0) {
            max = x[i];
        }
    }
    return max;
}

public static void main(String[] args) {

    Integer[] ai = new Integer[10];
    Double[] ad = new Double[10];

    fillInts(ai);
    fillDoubs(ad);
    System.out.println("Max ints: " + max(ai));
    //System.out.println("Max doubles: " + max(ad, ad.length));


    ///// boxes/////////

    Box[] boxes = new Box[5];
    fillBoxes(boxes);
    System.out.println(max(boxes));


}



private static void fillBoxes(Box[] boxes) {

    // random class for each of the dimension

    Random a = new Random();
    Random b = new Random();
    Random c = new Random();

    int l, w, h;

    for (int i = 0; i < boxes.length; i++) {
        l = a.nextInt(30);
        w = b.nextInt(30);
        h = c.nextInt(30);

        boxes[i] = new Box(l, w, h);
    }

}



private static void fillDoubs(Double[] ad) {
    Random r = new Random();
    for (int i = 0; i < ad.length; i++) {
        ad[i] = 1.0 * r.nextDouble();
    }

}

private static void fillInts(Integer[] ai) {
    Random r = new Random();
    for (int i = 0; i < ai.length; i++) {
        ai[i] = r.nextInt(100);
    }
}

}

1 Answers1

0

The literal 0 is always of type int, so Object max = 0; is actually implicitly Object max = Integer.valueOf(0); due to autoboxing. This means max always starts out with a value whose actual type is Integer.

Since, for example, Double.compareTo expects a Double argument, it throws an exception when you pass it an Integer.

Why exactly a class cast exception is thrown is a little more complicated to explain, but it's due to the implementation of Java generics, which is via type erasure. Since Comparable is a generic interface, when we override compareTo, the compiler generates something called a bridge method, which looks something like this:

public final class Double implements Comparable<Double> {
    // ...

    // generated bridge method
    public int compareTo(Object o) {
        return compareTo((Double) o);
    }
    // method which java.lang.Double
    // source code actually declares
    @Override
    public int compareTo(Double that) {
        return compare(this.doubleValue(), that.doubleValue());
    }
}

When you call compareTo on the Comparable, it actually calls the method compareTo(Object) which attempts to cast the argument to a Double and then pass it to Double.compareTo(Double). It's this cast in the bridge method which actually throws the exception.

In general, you will need to pass the zero value to your max method yourself, as in the following example (which also uses generics):

public static <T extends Comparable<T>> T max(T[] arr, T zero) {
    T max = zero;
    for (T e : arr)
        if (e.compareTo(max) > 0)
            max = e;
    return max;
}

Another way would be something like this:

public static <T extends Comparable<T>> Optional<T> max(T[] arr) {
    if (arr.length == 0)
        return Optional.empty();
    T max = arr[0];
    for (int i = 1; i < arr.length; ++i)
        if (arr[i].compareTo(max) > 0)
            max = arr[i];
    return Optional.of(max);
}

Also see What is a raw type and why shouldn't we use it?

Radiodef
  • 37,180
  • 14
  • 90
  • 125