randomizertech
randomizertech

Reputation: 2329

How to use compareTo within a Generic array in java?

I am trying to figure out how to compare two items within a T[] array, here is what I have:

public static <T extends Comparable< ? super T>> T getLargest(T [] a, int low, 
               int high){
    if(low>high)
            throw new IllegalArgumentException();
    T[] arrCopy = (T[]) new Object[high-low];
    for(int i=low;i<high;i++){
        if(a[i].compareTo(a[i-1])>0)
            arrCopy[i]=a[i];
        else
            arrCopy[i]=a[i+1];
    }
    return arrCopy[0];
}

and then I get the error: Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.Comparable;

Any ideas on how I can resolve this?

Upvotes: 2

Views: 3785

Answers (6)

user102008
user102008

Reputation: 31323

Just change new Object[high-low]; to new Comparable[high-low];. Generics are erased to their lower bound, so T is erased to Comparable.

Upvotes: 0

Puce
Puce

Reputation: 38142

Use:

public static <T extends Comparable<? super T>> T max(final T[] data, int fromIndex, 
               int toIndex) {
    return Collections.max(Arrays.asList(data).subList(fromIndex, toIndex));
}

Upvotes: 2

Sean Patrick Floyd
Sean Patrick Floyd

Reputation: 299048

You can assign the array like this:

@SuppressWarnings("unchecked")
T[] arrCopy = (T[]) Array.newInstance(a.getClass().getComponentType(), high-low);

Although the unchecked warning is necessary, this should actually be safe.

Btw, if you want to find the largest element in an array, here's a oneliner:

public static <T extends Comparable<T>> T max(final T[] data) {
    return Collections.max(Arrays.asList(data));
}

For the complete problem you can use one of these two (they are equivalent):

public static <T extends Comparable<T>> T maxA(final T[] data,int from, int to) {
    return Collections.max(Arrays.asList(Arrays.copyOfRange(data, from, to)));
}
public static <T extends Comparable<T>> T maxB(final T[] data,int from, int to) {
    return Collections.max(Arrays.asList(data).subList(from, to));
}

Upvotes: 5

seh
seh

Reputation: 15259

There's no reason to assume that an array of Object instances is fit for treatment as an array of Comparable instances. You're forcibly casting Object down to T, which we expect extends Comparable, but that unchecked assignment isn't even necessary here.

Instead, consider an implementation that does not copy any of the array:

public static <T extends Comparable<? super T>>
T getLargest(T[] a, int first, int last)
{
  // Don't tolerate an empty range:
  if (first >= last)
    throw new IllegalArgumentException();
  // Eventually checked by subsequent use of array index operator:
  if (first < 0 || first >= a.length ||
      last < 0 || last >= a.length)
    throw new IndexOutOfBoundsException();

  T largest = a[first];
  while (++first != last)
  {
    final T candidate = a[first];
    if (candidate.compareTo(largest) > 0)
      largest = candidate;
  }
  return largest;
}

Alternately, use Collections#max(), supplying your array viewed as a List after passing it through Arrays#asList().

Upvotes: 2

0xCAFEBABE
0xCAFEBABE

Reputation: 5666

You get the error here:

T[] arrCopy = (T[]) new Object[high-low];

You cannot cast the mother object of all objects (java.lang.object) to anything that has java.lang.comparable as the lowest common denominator, so the exception is thrown. An object (as in java.lang.object) does not implement java.lang.comparable.

In your specific example, you would need to create an array of T (or at the very least java.lang.comparable).

Upvotes: 2

jtahlborn
jtahlborn

Reputation: 53694

not sure why you create an entire new array when you only care about 1 object, but the issue has nothing to do with generics. you can't cast an Object[] to some more specific type like String[], just like you can't write String s = new Object().

seeing as you only care about the largest value, it would make much more sense to only track 1 value (the biggest value seen so far), not the entire array.

Upvotes: 2

Related Questions