How to have Java method return generic list of any type?

I would like to write a method that would return a java.util.List of any type without the need to typecast anything:

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


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


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

What would the method signature look like? Something like this, perhaps(?):

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


return list;
}
228627 次浏览
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;
}

One can give a generic type parameter to a method too. You have correctly deduced that one needs the correct class instance, to create things (klazz.getConstructor().newInstance()).

You can use the old way:

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


return list;
}

or you can use Object and the parent class of everything:

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


return list;
}

Note Perhaps there is a better parent class for all the objects you will put in the list. For example, Number would allow you to put Double and Integer in there.

Something like this

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

I'm pretty sure you can completely delete the <stuff> , which will generate a warning and you can use an, @ suppress warnings. If you really want it to be generic, but to use any of its elements you will have to do type casting. For instance, I made a simple bubble sort function and it uses a generic type when sorting the list, which is actually an array of Comparable in this case. If you wish to use an item, do something like: System.out.println((Double)arrayOfDoubles[0] + (Double)arrayOfDoubles[1]); because I stuffed Double(s) into Comparable(s) which is polymorphism since all Double(s) inherit from Comparable to allow easy sorting through 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)

No need to even pass the class:

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

Another option is doing the following:

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);

`

Let us have List<Object> objectList which we want to cast to 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;
}

You can simply cast to List and then check if every element can be casted to T.

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

Given some legacy code that returns an untyped List

List list = database.GetCustomers(); //legacy code returns untyped list

we will use a helper function:

public static <T> @NotNull List<T> castList(final @NotNull Iterable sourceList)
{
List<T> result = new ArrayList<>();
for (Object o : sourceList)
result.add((T)o);


return result;
}

to convert the returned list to a generic typed List<T>:

List<Customer> = castList(database.GetCustomers()); //cast the list the appropriate type

Why Java doesn't have extension methods is quite beyond me.