0

Im having a big problem with this code: I need to create my own Merge Method without using java´s Merge Method.

public static <T extends Comparable> T[] merge(T[] a, T[] b){
    T[] c = (T[]) new Object[a.length + b.length];  

    /*
     *
     * More code
     *
     *
    */
    return c;
}

The problem is that in runtime I have this error: java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.Comparable; I have already looked for this problem, and the solution is using Reflection.

The problem i have it in this line: T[ ] c = (T[ ]) new Object[a.length + b.length];

The problem is that I dont understand how to use it, have already try using reflection in many different ways but i can´t solve this.

I really appreciate any answer and tell me where should I change my code.

2
  • How about Arrays.copyOf? stackoverflow.com/a/8220245/303939 Commented Mar 24, 2015 at 2:27
  • 1
    (rawtypes! Should be <T extends Comparable<T>>, or better <T extends Comparable<? super T>>.) Commented Mar 24, 2015 at 3:05

2 Answers 2

4

You could create an array of the same type as the input arrays, using reflection - something like this:

if(a.getClass() != b.getClass()) // or .equals if you prefer. It doesn't matter for Class objects
    throw new IllegalArgumentException("Arrays don't have the same type");

T[] c = Array.newInstance(a.getClass().getComponentType(), a.length + b.length);

Note that it is impossible to use something like T.class. Note also that this won't work as expected for cases like:

Comparable[] result = <Comparable>merge(new Integer[] {1, 2, 3}, new Integer[] {4, 5, 6});

as the result will be an Integer[] instead of a Comparable[]. However, it is the closest you can do without passing Comparable.class to the function, or pre-allocating the result array before calling it.

Or you could use Arrays.copyOf as suggested by Ming-Tang, and then fill the array with null (otherwise it starts with a copy of a):

if(a.getClass() != b.getClass()) // or .equals
    throw new IllegalArgumentException("Arrays don't have the same type");

T[] c = Arrays.copyOf(a, a.length + b.length);
Arrays.fill(c, null);

This has the same issues.

Sign up to request clarification or add additional context in comments.

4 Comments

Because of the bizarre and unnatural behaviour of arrays, you should choose the "greatest common superclass". (Code for which is left as an exercise for the interested reader.) When I say "should", you should follow @immibis' advice and use List.
@TomHawtin-tackline Note that I wrote both answers, because either one could be best for the OP's application. (Although one would certainly hope, for his/her sanity, that the List one works)
Heh, didn't realise it was the same person. Reference arrays were badly messed up (not that System.arraycopy is a nice way of dealing with arrays).
you need to cast the result of Array.newInstance() to T[]
2

You could just use List instead.

public static <T extends Comparable> List<T> merge(List<T> a, List<T> b){
    List<T> c = new ArrayList<T>(a.size() + b.size());

    /*
     *
     * More code
     *
     */
    return c;
}

This might not be an option if some other part of your code forces you to use arrays in merge.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.