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

JavaListGenericsReflectionCasting

Java Problem Overview


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

Java Solutions


Solution 1 - Java

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()).

Solution 2 - Java

No need to even pass the class:

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

Solution 3 - Java

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

`

Solution 4 - Java

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

Solution 5 - Java

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.

Solution 6 - Java

Something like this

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

Solution 7 - Java

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

Solution 8 - Java

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)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser1768830View Question on Stackoverflow
Solution 1 - JavaJoop EggenView Answer on Stackoverflow
Solution 2 - JavanewacctView Answer on Stackoverflow
Solution 3 - JavaAidaminaView Answer on Stackoverflow
Solution 4 - JavaOleg MikhailovView Answer on Stackoverflow
Solution 5 - JavaLee MeadorView Answer on Stackoverflow
Solution 6 - JavaEvgeniy DorofeevView Answer on Stackoverflow
Solution 7 - JavaK. GolView Answer on Stackoverflow
Solution 8 - JavakoZmiZmView Answer on Stackoverflow