3

I've tried to understand how generics works. I created several implementations sorting algorithms and before sorting i shuffling input array by shuffleArray method in AbstractSorter.java:

public class AbstractSorter<T extends Comparable> {

public void swap(final T[] input, int srcPos, int dstPos) {
    if (dstPos != srcPos) {
        T accum = input[dstPos];
        input[dstPos] = input[srcPos];
        input[srcPos] = accum;

    }
}

public T[] shuffleArray(final T[] inputArray) {
    //        E[] arr = (E[])new Object[INITIAL_ARRAY_LENGTH];
    T[] result = (T[]) new Comparable[inputArray.length];
    System.arraycopy(inputArray, 0, result, 0, inputArray.length);
    int index;
    Random random = new Random();
    for (int i = result.length - 1; i > 0; i--) {
        index = random.nextInt(i + 1);
        if (index != i) {
            swap(result, i, index);
        }
    }
    return result;
}

public boolean more(final T x, final T y) {
    return (x.compareTo(y) > 0);
}

but when i try to use like this:

AbstractSorter<Integer> sortHelper = new AbstractSorter();
Integer[] expResult = new Integer[]{-30, -29, -28, -27 };
Integer[] shuffleArray = sortHelper.shuffleArray(expResult);
System.out.println("Array ="+Arrays.toString(shuffleArray));

it i got exception:

java.lang.ClassCastException: 
[Ljava.lang.Comparable; cannot be cast to [Ljava.lang.Integer;

I don't understand how can i fix shuffle method. Is it possible implement this functionality on arrays or should i migrate to collections?

Thanks in advance!

John Bl
  • 33
  • 4

3 Answers3

1

You're trying to create an array of Comparable, but the expected array is an array of Integer.

You can't cast an array of something to an array of something else, even though the contained objects are parents .

But as you said, we can't easily create an array of generic objects, so I refered to How to create a generic array in Java?

Replace :

T[] result = (T[]) new Comparable[inputArray.length];

with :

final T t = inputArray[0];
T[] result = (T[]) Array.newInstance(t.getClass(), inputArray.length);
Community
  • 1
  • 1
Arnaud
  • 16,319
  • 3
  • 24
  • 39
1

The reason you're getting the exception is because you're trying to convert an array of Comparable objects to an array of Integer objects, which is illegal. You can only cast from Integer to Comparable, not the other way around.

This is your problem: T[] result = (T[]) new Comparable[inputArray.length];. Here you're casting a Comparable to T which is an Integer in this case.

Change the lines T[] result = (T[]) new Comparable[inputArray.length]; and System.arraycopy(inputArray, 0, result, 0, inputArray.length); to T[] result = Arrays.copyOf(inputArray, inputArray.length); so your shuffleArray method looks like:

public T[] shuffleArray(final T[] inputArray) {
    T[] result = Arrays.copyOf(inputArray, inputArray.length);
    int index;
    Random random = new Random();
    for (int i = result.length - 1; i > 0; i--) {
        index = random.nextInt(i + 1);
        if (index != i) {
            swap(result, i, index);
        }
    }
    return result;
}

Running the example with:

AbstractSorter<Integer> sortHelper = new AbstractSorter();
Integer[] expResult = new Integer[]{-30, -29, -28, -27};
Integer[] shuffleArray = sortHelper.shuffleArray(expResult);

System.out.println ("Array =" + Arrays.toString(shuffleArray));

Produces the result: Array =[-30, -28, -29, -27]

Luke Melaia
  • 1,432
  • 13
  • 21
0

Surely you want the following:

public class AbstractSorter<T extends Comparable<T>>

and

T[] result = (T[]) new Comparable<T>[inputArray.length];

and

AbstractSorter<Integer> sortHelper = new AbstractSorter<>();
SomeGuy
  • 438
  • 4
  • 8