Arunselvan
Arunselvan

Reputation: 65

how to convert a generic List to a generic array in Java?

I tried to write a generic class to sort a array of any type.
First sort function does sorting of any type of array. Its working fine.

In second sort function, I passed list and tried to convert into array to use first sort function. But when i tried to convert list into array inside generic class, It throws unexpected type error.

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

    public class Sort<T extends Comparable>{
         //public T l;
         T tmp;
        public  void sort(T[] l){

        for(int i=0;i<l.length;i++){
           for(int j=i+1;j<l.length;j++){
              if(l[i].compareTo(l[j])>0){
                   tmp=l[i];
                  l[i]=l[j];
                   l[j]=tmp;
              }
            }
        }
                    System.out.println( Arrays.asList(l));
              }
         public  <T extends Comparable>  void sort(List<T> l){
          T[] array = (T[]) new Object[l.size()];
          sort(l.toArray(T[] array));
      // System.out.println(l);
         }   

    public static void main(String[] args){
                Integer[] i={2,4,1,5,3};
                List<String> l = Arrays.asList("c","d","a","e","b");
                Sort s=new Sort();
                //String[] j=l.toArray(new String[l.size()]);
                s.sort(i);
                s.sort(l);

            }
    }

Upvotes: 0

Views: 2612

Answers (3)

n247s
n247s

Reputation: 1918

Its because you didnt imply any generic arguments on class level (e.g. Sort(<)String(>) s = new Sort<>()) It means you wont be able to use it with the Integer arrray(and vice versa if you used Integer as generic type). What I would do is using the generic argument on method level instead. (As you did with the second method)

public class Sort {

    public  <T extends Comparable> void sort(T[] l){
    T tmp;
    for(int i=0;i<l.length;i++){
       for(int j=i+1;j<l.length;j++){
          if(l[i].compareTo(l[j])>0){
               tmp=l[i];
              l[i]=l[j];
               l[j]=tmp;
          }
        }
    }
                System.out.println( Arrays.asList(l));
          }
     public  <T extends Comparable>  void sort(List<T> l){
      T[] array = (T[]) new Object[l.size()];
      sort(l.toArray(T[] array));
  // System.out.println(l);
     } 

Upvotes: 1

davidxxx
davidxxx

Reputation: 131376

As n247s suggested, you should use the same parameterized type for class and methods if you want to have a consistence between them.
It asks another question : if you do it, you should not mix oranges and bananas since otherwise your sort could give unexpected results. Suppose, you put in the array or in the List, a mix of Comparable objects which are not designed to be compared between them : String, Boolean, CustomClassWhichIsComparable

Besides, in your method which converts the list to an array, you want to assign a array of Object in a array of Comparable. But you cannot do it because all Object instances are not necessarily Comparable instances.

 public  <T extends Comparable>  void sort(List<T> l){
   T[] array = (T[]) new Object[l.size()];
   sort(l.toArray(T[] array));
 }  


You could do it :

public void sort(List<T> l) {
  T[] array = (T[]) new Comparable[l.size()];
  sort(l.toArray(array));
}

In both cases, you would have a warning but no exception.

Here is the class with proposed modifications :

public class Sort<T extends Comparable<T>> {

    T tmp;


    public void sort(T[] l) {

    for (int i = 0; i < l.length; i++) {
        for (int j = i + 1; j < l.length; j++) {
          if (l[i].compareTo(l[j]) > 0) {
            tmp = l[i];
            l[i] = l[j];
            l[j] = tmp;
          }
        }
    }
      System.out.println(Arrays.asList(l));
    }

    public void sort(List<T> l) {
       T[] array = (T[]) new Comparable[l.size()];
       sort(l.toArray(array));
     }

    public static void main(String[] args) {
      Integer[] i = { 2, 4, 1, 5, 3 };
      Sort<Integer> sortInt = new Sort<Integer>();
      sortInt.sort(i);

      Sort<String> sortString = new Sort<String>();
      List<String> l = Arrays.asList("c", "d", "a", "e", "b");
      sortString.sort(l);
    }
}

Upvotes: 1

Nick Vanderhoven
Nick Vanderhoven

Reputation: 3093

The problem is the <T extends Comparable> in your second sort method. This type T is shadowing your class type T.

You could rename it, but since you don't return something in the first method, the quickest fix is to just leave it out, so that the compiler is happy again. Starting with your code, that would translate to something like this:

public void sort(List<T> l){
    T[] array = (T[]) new Object[l.size()];
    sort(array);
}

Upvotes: 0

Related Questions