Downcasting an array of type Comparable[] to generic <T extends Comparable<T>>

57 Views Asked by At

So, recently I've been trying to implement my own array of generic comparable type and my class contains a private field T[] array, the problem is that for my implementation of sorting algorithm I need to use a function that could return array but when I try to do it I get a ClassCastException. So after debugging I found out that when I create T[] array using constructor or resize() method I get as a result an instance of Comparable[] but it stores my generic type T. I read about downcasting and people say that it isn't always working properly, but I can't get it how it works then. Is there any way to return array to program for further use without getting ClassCastException

public class myArray<T extends Comparable<T>> {
    private T[] array;
    private int size;
    private int maxSize;

    public myArray() {
        maxSize = 100;
        size = 0;
        array = (T[]) new Comparable[maxSize];
    }

    public myArray(int newSize) {
        maxSize = newSize * 2 + 10;
        array = (T[]) new Comparable[maxSize];
        size = 0;
    }

    public myArray(myArray<T> myArr) {
        maxSize = myArr.maxSize;
        size = myArr.size;
        array = (T[]) new Comparable[maxSize];
        if (size >= 0) System.arraycopy(myArr.array, 0, array, 0, size);
    }
    private void resize() {
        maxSize = size * 2 + 10;
        T[] tmp_array = array;
        array = (T[]) new Comparable[maxSize];
        System.arraycopy(tmp_array, 0, array, 0, size);
    }
    public T[] getArray() {
        return array;
    }
    public String toString() {
        if (size == 0) {
            return "Empty array";
        }
        String str = "";
        for (int i = 0; i < this.size; i++) {
            str += this.array[i].toString() + " ";
        }
        return str;
    }
}

And this is where I try to use it and get ClassCastException

    @Test
    @DisplayName("Resize test")
    public void test3() {
        myArray<Integer> array = new myArray<Integer>(2);
        System.out.println("Array size is " + array.size() + " and max size is " + array.maxSize());
        for (int i = 0; i < array.maxSize(); i++) {
            array.pushBack(i * i - 3 * i);
        }
        System.out.println("Array is " + array + "and max size is " + array.maxSize());
        Integer[] arr = array.getArray();
        for (Integer i : arr) {
            System.out.println(i + " ");
        }
    }
1

There are 1 best solutions below

3
Reilas On

Use an Object array, over a T array.

class myArray<T extends Comparable<T>> {
    private Object[] array;
    private int size;
    private int maxSize;

    public myArray() {
        maxSize = 100;
        size = 0;
        array = new Object[maxSize];
    }

    public myArray(int newSize) {
        maxSize = newSize * 2 + 10;
        array = new Object[maxSize];
        size = 0;
    }

    public myArray(myArray<T> myArr) {
        maxSize = myArr.maxSize;
        size = myArr.size;
        array = new Object[maxSize];
        if (size >= 0) System.arraycopy(myArr.array, 0, array, 0, size);
    }
    private void resize() {
        maxSize = size * 2 + 10;
        Object[] tmp_array = array;
        array = new Object[maxSize];
        System.arraycopy(tmp_array, 0, array, 0, size);
    }
    @SuppressWarnings("unchecked")
    public T[] getArray() {
        return (T[]) array;
    }
    public String toString() {
        if (size == 0) {
            return "Empty array";
        }
        String str = "";
        for (int i = 0; i < this.size; i++) {
            str += this.array[i].toString() + " ";
        }
        return str;
    }
}

Here is an example usage.

myArray<String> a = new myArray<>();
String[] b = a.getArray();