2013-07-24 9 views
43

Vorrei scrivere un metodo che restituisce un java.util.List di qualsiasi tipo senza la necessità di typecast nulla:Come avere il metodo Java restituire un elenco generico di qualsiasi tipo?

List<User> users = magicalListGetter(User.class); 

List<Vehicle> vehicles = magicalListGetter(Vehicle.class); 

List<String> strings = magicalListGetter(String.class); 

Quale sarebbe la firma del metodo simile? Qualcosa di simile, forse (?):

public List<<?> ?> magicalListGetter(Class<?> clazz) { 
    List<?> list = doMagicalVooDooHere(); 

    return list; 
} 

Grazie in anticipo!

+2

Vuoi l'elenco per essere popolato attraverso la riflessione? Altrimenti usa semplicemente 'new ArrayList <>()'. –

risposta

83
private Object actuallyT; 

public <T> List<T> magicalListGetter(Class<T> klazz) { 
    List<T> list = new ArrayList<>(); 
    list.add(klazz.cast(actuallyT)); 
    try { 
     list.add(klazz.getConstructor().newInstance()); // If default constructor 
    } ... 
    return list; 
} 

Si può dare anche un parametro di tipo generico a un metodo. Hai correttamente dedotto che è necessario l'istanza di classe corretta, per creare cose (klazz.getConstructor().newInstance()).

1

È possibile utilizzare il vecchio modo:

public List magicalListGetter() { 
    List list = doMagicalVooDooHere(); 

    return list; 
} 

oppure è possibile utilizzare Object e la classe padre di tutto:

public List<Object> magicalListGetter() { 
    List<Object> list = doMagicalVooDooHere(); 

    return list; 
} 

Nota Forse c'è una migliore classe genitore per tutta la oggetti che inserirai nella lista. Ad esempio, Number consentirebbe di inserire Double e Integer lì.

1

Qualcosa di simile

publiс <T> List<T> magicalListGetter(Class<T> clazz) { 
    List list = doMagicalVooDooHere(); 
    return list; 
} 
+1

perché passare 'clazz' se non lo userai? – newacct

+1

era così nella domanda, probabilmente OP lo userà in qualche modo –

-1

Sono abbastanza sicuro che si può completamente eliminare la <roba>, che genererà un avvertimento e si può utilizzare una, @ sopprimere avvertimenti. Se vuoi davvero che sia generico, ma per usare uno qualsiasi dei suoi elementi dovrai digitare il casting. Ad esempio, ho creato una semplice funzione di ordinamento a bolle e utilizza un tipo generico per ordinare l'elenco, che in realtà è un array di Paragonabile in questo caso. Se desideri utilizzare un oggetto, fai qualcosa come: System.out.println ((Double) arrayOfDoubles [0] + (Double) arrayOfDoubles [1]); perché ho farcito doppia (s) in comparabili (s) che è il polimorfismo dal momento che tutti doppia (s) eredita da Paragonabile per consentire un facile ordinamento attraverso Collections.sort()

 //INDENT TO DISPLAY CODE ON STACK-OVERFLOW 
@SuppressWarnings("unchecked") 
public static void simpleBubbleSort_ascending(@SuppressWarnings("rawtypes") Comparable[] arrayOfDoubles) 
{ 
//VARS 
    //looping 
    int end  =  arrayOfDoubles.length - 1;//the last index in our loops 
    int iterationsMax = arrayOfDoubles.length - 1; 

    //swapping 
    @SuppressWarnings("rawtypes") 
    Comparable tempSwap = 0.0;//a temporary double used in the swap process 
    int elementP1 = 1;//element + 1, an index for comparing and swapping 


//CODE 
    //do up to 'iterationsMax' many iterations 
    for (int iteration = 0; iteration < iterationsMax; iteration++) 
    { 
     //go through each element and compare it to the next element 
     for (int element = 0; element < end; element++) 
     { 
      elementP1 = element + 1; 

      //if the elements need to be swapped, swap them 
      if (arrayOfDoubles[element].compareTo(arrayOfDoubles[elementP1])==1) 
      { 
       //swap 
       tempSwap = arrayOfDoubles[element]; 
       arrayOfDoubles[element] = arrayOfDoubles[elementP1]; 
       arrayOfDoubles[elementP1] = tempSwap; 
      } 
     } 
    } 
}//END public static void simpleBubbleSort_ascending(double[] arrayOfDoubles) 
16

Non c'è bisogno di passare anche la classe:

public <T> List<T> magicalListGetter() { 
    return new ArrayList<T>(); 
} 
+2

Penso che sia necessario passare una classe quando si desidera aggiungere elementi. – zygimantus

1

Un'altra opzione sta facendo il seguente:

public class UserList extends List<User>{ 

} 

public <T> T magicalListGetter(Class<T> clazz) { 
    List<?> list = doMagicalVooDooHere(); 
    return (T)list; 
} 

List<User> users = magicalListGetter(UserList.class); 

`

2

Diamo List<Object> objectList che vogliamo lanciare al List<T>

public <T> List<T> list(Class<T> c, List<Object> objectList){   
    List<T> list = new ArrayList<>();  
    for (Object o : objectList){ 
     T t = c.cast(o); 
     list.add(t); 
    } 
    return list; 
} 
0

Si può semplicemente lanciare to List e quindi verificare se ogni elemento può essere colato a T.

public <T> List<T> asList(final Class<T> clazz) { 
    List<T> values = (List<T>) this.value; 
    values.forEach(clazz::cast); 
    return values; 
} 
Problemi correlati